This application note describes an SLG46140V design that implements a 16-bit up/down counter with quadrature encoder inputs. The GreenPAK device relieves the host of real-time input requirements and allows for easy connection of multiple encoders.
Rotary Encoders measure the number of rotations, the rotational angle, and the rotational position. Incremental Incremental Encoders output a pulse string according to the rotational displacement of an axis. The number of rotations can be detected by counting the number of pulses.
Rotary encoders are widely used to sense the orientation of shafts and machine parts, and as user interface input devices. Most rotary encoders output a pair of quadrature signals, which encode the shaft movement as a series of pulses.
To keep track of the encoder position, every pulse must be counted. Often, interrupt pins are used for this purpose, with the counting implemented in software. Many microcontrollers include specialized peripherals to read quadrature signals. However, interrupt based counting limits the maximum pulse rate and takes up CPU time, while the specialized peripherals limit the number of encoders that can be connected to a single microcontroller. Furthermore, on non-realtime platforms — such as PCs — neither option is available.
This application note demonstrates how an SLG46140V GreenPAK device can implement a quadrature encoder interface with a 16 bit up/down counter and SPI bus interface. The current position of the encoder can be read out by the host application at the desired interval, while the auxiliary device keeps track of each input pulse. Furthermore, the SPI bus allows chaining multiple devices to interface a flexible number of encoders to a single processor.
The High-Level Design
This application note design has three input signals from the encoder: A, B, and Z. Signals A and B are the quadrature signals which switch state alternately in 00, 10, 11, 01 gray code sequence. Signal Z is an optional encoder zero index input, which resets the counter to the zero position.
Figure 1. System connections with one encoder device.
The described SPI consists of the nCS chip select signal, an SCK serial clock, and the MISO (master in, slave out) serial output. Chip select is active low, and the bus can be used by other SPI devices when nCS is high. The SPI transfer format used in this application note is CPOL=0, CPHA=1, which means that SCK is in a low state when idle and data is sampled on the falling edge.
Figure 2. System connections with multiple encoders.
Multiple devices can be chained on the same bus by using the Chain_IN and Chain_OUT signals, which internally delay the data for 16 SCK clock cycles. Thus, the first 16 bits received by the host will be from the first encoder, the next 16 bits from the second encoder and so on. All encoders will be sampled at the same time on the first SCK clock edge.
The implementation inside the GreenPAK device consists of three parts:
- Quadrature encoder input block: Converts quadrature signals to KEEP / UP signal pair for the counter, and synchronizes the signals to an internal clock.
- 16-bit up/down counter: Two chained 8-bit counters count the encoder pulses and provide parallel data to SPI block.
- SPI bus: SPI latches the parallel data and outputs it serially when nCS is active.
The quadrature input block and the counter run from the internal ring oscillator clock, while the SPI is clocked externally by the SPI master. The following sections contain a detailed description of each component.
Quadrature Encoder Input Block
Signals from the encoder initially go to a pair of delay blocks. These work as both glitch filters and synchronizers, ensuring that their output signal only changes at the clock rising edge. The delay value is set to minimum, giving a 2-clock cycle delay. Optionally, for noisy signals, the delay can be increased to filter out any glitch pulses from the inputs, but this filtering will also limit the maximum pulse rate.
The output from the delay blocks is passed to a pair of D-flipflops, which retain the signal state from the previous clock cycle. The current state and the previous state are then compared with a 4-input XNOR gate. If either of the signals has changed, the XNOR gate will output a 0 value for KEEP signal, causing the counter block to count.
Figure 3. Quadrature signal input block
Encoder direction is detected by comparing the current states At and Bt with the previous state Bt-1, as shown in Table 1. The detection logic has been programmed to the 3-bit LUT0 component, which outputs an UP signal to the counters.
Table 1. Direction Detection from Signal States
Some encoders have an additional zero position sensor, which can be used to find the absolute position of the system after a reboot. A high level on this Z signal will reset the counter to zero. If this functionality is not needed, the signal can be left unconnected as the input pin has been configured with a pulldown resistor.
16-Bit Up/Down Counter
The SLG46140V device contains two counter / finite state machine blocks with a parallel data connection to the SPI block. Each of these can output an 8-bit count, and by chaining the two counters a 16-bit counter can be made. The counter wraps around from 0x0000 to 0xFFFF in either direction.
Figure 4. Logic for Z input signal
By default, the CNT3 block counts from configurable start value either downwards to 0 or upwards to 255, and then restarts at the configured value. Wrap around for downward counting is available by setting the start value for 255, but to get wraparound for upward counting simultaneously, extra logic is needed.
Figure 5. Carry out and wraparound logic for lower 8-bit counter
The counter's OUT signal activates when the counter is at its extreme value. When KEEP=0 and OUT=1, LUT0 outputs a carry pulse to the next counter to increment its count. Simultaneously LUT1 activates the reset signal if UP=1. DFF2 samples the reset signal so that the counter resets synchronously on the clock rising edge.
The CLEAR signal from the encoder Z input is connected to the asynchronous set input of DFF2, which causes an immediate reset of the counter. The counter resumes counting on the next rising clock edge.
Figure 6. Wraparound logic for high 8-bit counter
The second counter stage is connected similarly because a separate carry out signal is not needed from this stage; the three signals are all connected to a single LUT component. It resets the counter to zero when UP=1, KEEP=0, and OUT=1.
SPI Bus
The parallel to serial converter interface is available as a ready-made functional block in the SLG46140 and the SLG46620. The block latches the parallel data from the two counters on the first SCK edge after nCS goes low, and then shifts out the data bit by bit.
The externally generated SCK signal is not synchronous with the internal clock used by the counters, so the two blocks need to be synchronized in some way to reliably transfer data between them. The SPI block offers a built-in selection for gating the FSM clock for two clock cycles when data transfer occurs. In this application, gating the FSM clock is undesirable because it could cause pulses to be lost while the clock was disabled. Instead, DFF5 is used to synchronize the external SCK signal to internal ring oscillator clock. This ensures that the SCK clock edge as seen by SPI block occurs at ring oscillator clock edge when the FSM data is stable.
In this application note, the basic SPI is extended by data chaining logic. This allows connecting multiple encoders easily on the same SPI bus and sampling the counter value of them all simultaneously.
The chaining function is based on Pipe Delay functional block. This block has a chain of 16 flip-flops, which will shift in and shift out one bit on each rising edge of the clock signal. The MISO signal from the previous device in the chain is connected to the input, and the output goes to the next device.
Because the MISO signal is directly connected to pin 12 in hardware, Chain_OUT will have to be externally connected in parallel with it. The output-enabled logic ensures that only one of the pins is active at a time.
Figure 7. SPI and data chain logic
For the first 16 clock cycles, after nCS goes low, each device keeps MISO enabled and clock out its counter value. Simultaneously, the Pipe Delay block stores the signal received from the N-1th device in the chain.
After 16 clock cycles, the SPI INTR output goes high to indicate the end of the transmission. LUT2 OR-gate then causes DFF4 flip-flop to go high, disabling PIN12 and enabling PIN13. The Pipe Delay block shifts out the N-1th value, while simultaneously shifting in N-2th value. This continues until all values have been read and the host raises an nCS signal, which resets DFF4 back to its initial state.
Figure 8. SPI signal capture with two devices
Figure 8 shows an example of SPI communication where the device first sends its own 16-bit data value and then forwards the 16-bit value from the next device in the chain.
Clock Rate Limitations
The delay and counter blocks are clocked from the internal ring oscillator, which runs at approximately 27 MHz frequency and has selectable divider of 1, 4, 8, or 16. The maximum clock rate depends on the delay of the logic elements and varies with the supply voltage.
The longest logic chain in the design goes from input DLY0/1 blocks through 4-bit LUT0 change detector, 2-bit LUT0 carry out logic and 3-bit LUT1 wraparound logic to the FSM blocks. The delay values for these blocks are defined in the SLG46140 datasheet and are summarized in Table 2. Due to routing delays and part variance, the theoretically possible 6.8 MHz frequency did not work with the lowest end of the GreenPAK’s input voltage range (VDD = 1.8 V), and 3.4 MHz clock is used instead.
Table 2. Block Delays and Maximum Operating Frequency
The operating frequency will limit the minimum pulse width on the quadrature inputs. The input glitch filter passes through pulses that are at least three clock cycles long and filter out anything below two clock cycles.
Test Results
Functionality was tested in two ways. Manual testing was performed with the quadrature output from AMT203 rotary encoder, to verify counting in both directions worked as expected and followed the encoder movement.
Maximum pulse rates and counting reliability was verified with a microcontroller generated signal source, which emulates quadrature signals. The microcontroller was configured to output 8000 steps at given step frequencies. Pulse width in quadrature signals is twice the step spacing, as only one signal changes state at a time. The step series was repeated several times while data was being read out through SPI bus. A test case was marked as successful only if all steps were correctly counted every time.
Test results are summarized in Table 3. As expected, pulses shorter than two clock periods get rejected by the glitch filter and result in a zero count. When operating close to the minimum pulse width at each voltage, there are some lost steps. This may be caused by asymmetric rise/fall delays, which can slightly shorten some of the pulses as they travel through the logic.
Conclusions
A design for interfacing quadrature encoders to an SPI bus has been presented. The design can be used as-is, or the individual components can be repurposed for different applications. The quadrature input section can be modified to output signals directly suitable for different devices, such as stepper drivers. The 16-bit up/down counter block provides a useful tool for measuring many kinds of pulse sources. The chainable SPI can be used to simultaneously sample and read from multiple GreenPAK devices, and the data source can come from a counter or an ADC.
References
For related documents and software, visit the configurable mixed signal product page
Download the free GreenPAK Designer software [1] to open the .gp files [2] and view the proposed circuit design. Use the GreenPAK development tools [3] to freeze the design into your own customized IC in a matter of minutes. Dialog Semiconductor provides a complete library of Application Notes [4] featuring design examples as well as explanations of features and blocks within the Dialog IC.
- GreenPAK Designer Software, Software Download and User Guide, Dialog Semiconductor.
- .gp, GreenPAK Design File, Dialog Semiconductor.
- GreenPAK Development Tools, GreenPAK Development Tools Webpage, Dialog Semiconductor.
- GreenPAK Application Notes, GreenPAK Application Notes Webpage, Dialog Semiconductor.
Industry Articles are a form of content that allows industry partners to share useful news, messages, and technology with All About Circuits readers in a way editorial content is not well suited to. All Industry Articles are subject to strict editorial guidelines with the intention of offering readers useful news, technical expertise, or stories. The viewpoints and opinions expressed in Industry Articles are those of the partner and not necessarily those of All About Circuits or its writers.
Introduction
Rotary encoders are electronic devices that can measure mechanical rotation. They can be used in two fashions – As a control or as a device to measure the rotation of a shaft.
When used as a control, rotary encoders can be much more versatile than a potentiometer. They can be used when you need a very precision control, and they are not subject to drift due to temperature.
As a device to measure mechanical rotation rotary encoders have several uses. One of them is to measure the rotation of a DC gearmotor.
Today we will look at both types of rotary encoders. I will show you how to hook them up to an Arduino and I’ll give you some demonstration sketches that you can run yourself.
So let’s get started!
Rotary Encoders
A rotary encoder, which can also be referred to as a shaft encoder, is an electro-mechanical device that can convert the angular position (rotation) of a shaft to either an analog or digital output signals. We will be focusing on digital devices today.
There are two main types of rotary encoder: absolute and incremental. The difference is the absolute encoder gives the precise position of the shaft in degrees, whereas the incremental encoder reports how many increments the shaft has moved, but not its actual position.
Rotary encoders are used in many different applications including industrial controls, robotics, optomechanical mice and trackballs, CNC machines and printers.
Rotary Encoder Operation
There are several different types of rotary encoders. I’m restricting this discussion to the simpler “incremental” encoders. These are sometimes called quadrature or relative rotary encoders.
These encoders have two sensors and output two sets of pulses. The sensors, which can be magnetic (hall effect) or light (LED or Laser), produce pulses when the encoder shaft is rotated.
As there are two sensors in two different positions they will both produce the same pulses, however, they will be out of phase as one sensor will pulse before the other one. Which sensor goes first is determined by the direction of rotation.
In the above example the encoder shaft is spinning clockwise. The sensor on the top is triggered before the bottom one, so the top set of pulses precedes the bottom set.
If the encoder shaft is rotated counterclockwise then the bottom set of pulses will be delivered before the top set.
In both cases the pulses can be counted to determine how much the shaft has rotated. By checking to see which pulse comes first we can determine the direction of rotation.
Control Encoder
The control encoder we are going to use is a very common device, and it’s available from several sources. It’s also included in the infamous “37 in one” sensor kit that is available at many electronic stores and online.
The encoder can be mounted exactly like a potentiometer, and it has a D-shaft to accept a knob. It also has its own push button momentary contact switch that can be activated by pressing down upon the shaft.
The pinouts of the control encoder are as follows:
- GND – The Ground connection.
- +V – The VCC or positive supply voltage, usually 3.3 or 5-volts.
- SW – The pushbutton switch output. When the shaft is depressed this goes to ground level.
- DT – The Output A connection.
- CLK – The output B connection.
I will show you how to use this control encoder in a moment, but first, let’s look at the other rotary encoder we will be discussing today.
Motor Encoder
Motor encoders are mounted on the shaft of a DC motor and can count the amount that the motor shaft has moved. Coupled with a motor driver, this will allow you to create a feedback mechanism that can permit you to specify how much you would like the shaft to turn.
You can also use these encoders as a tachometer to measure the speed that the shaft is rotating.
The encoder I’m illustrating here is the one that is attached to the gear motor I am using in my DB1 Robot from my Build a REAL Robot series of articles and videos. It is a goBILDA 5201 Series Spur Gear Motor with a built-in encoder.
Other motor encoders should have similar connections.
The connections are very basic:
- VCC – the 5-volt power supply input.
- GND – The Ground connection.
- CH A – Output A.
- CH B – Output B.
We will see how to use this with an Arduino to measure the motor RPM very soon.
Reading Control Encoders
We will begin our rotary encoder experiments using the control encoder.
Reading a control encoder with an Arduino is actually fairly straightforward. We just need to read input pulses and count them. We also need to determine which set of pulses is occurring first, so that we can determine the direction of rotation.
Arduino Control Encoder Test Hookup
Here is how we will hook up our first rotary encoder experiment.
You will notice that in addition to the rotary encoder I have added a couple of LEDs. These will indicate the direction that we are spinning the encoder shaft.
The dropping resistors for the two LEDs are any value from 150 to 470 ohms, in the illustration I show 220 ohm resistors.
Incidentally, none of the pins used on the Arduino are critical. You can change them around, provided that you alter the sketch accordingly.
Arduino Control Encoder Test Sketch
Now that you have your encoder and LEDs hooked up you’ll need a sketch to make it all work. Here is the one I came up with:
Rotary Encoder Demo
2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 | Rotary Encoder Demo Demonstrates operation of Rotary Encoder DroneBot Workshop 2019 */ // Rotary Encoder Inputs #define inputDT 5 // LED Outputs #define ledCCW 9 intcounter=0; intpreviousStateCLK; Stringencdir='; voidsetup(){ // Set encoder pins as inputs pinMode(inputDT,INPUT); // Set LED pins as outputs pinMode(ledCCW,OUTPUT); // Setup Serial Monitor // Assign to previousStateCLK variable currentStateCLK=digitalRead(inputCLK); // If the previous and the current state of the inputCLK are different then a pulse has occured // If the inputDT state is different than the inputCLK state then if(digitalRead(inputDT)!=currentStateCLK){ encdir='CCW'; digitalWrite(ledCCW,HIGH); }else{ counter++; digitalWrite(ledCW,HIGH); Serial.print('Direction: '); Serial.print(' -- Value: '); } previousStateCLK=currentStateCLK; |
We start the sketch by defining some constants to represent the inputs from the encoder and the outputs to the two LEDs.
Next, a few integer variables are defined. The counter variable represents the count that will be modified by turning the controller, it can be a positive or negative number..
The currentStateCLK and previousStateCLK variables hold the state of the CLK output (Output B), these are used as part of the system to determine the direction of rotation.
A string called encdir is defined, it will be used when we print the current direction of rotation to the serial monitor.
Now on the the Setup section.
The Setup is pretty straightforward, we setup the serial monitor, define the connections to the encoder as inputs and the connections to the two LEDs as outputs.
At the end of the Setup we read the current value of the CLK pin and assign it to the previousStateCLK variable.
And now the Loop, where all the action takes place!
We check the CLK input and compare it to the previousStateCLK value. If it has changed then a pulse has occurred.
Next the logic to determine the direction of rotation. We now look at the DT pin on the encoder module and compare it to the current state of the CLK pin.
If it is different then we are rotating counterclockwise. We then decrement the counter variable value, set encdir to hold a value of “CCW” and turn on the red (CCW) LED.
If, on the other hand, the two values are the same then we are moving clockwise. We do the opposite – increment the counter, write “CW” to the encdir variable and turn on the Green (CW) LED.
After we print our results to the serial monitor we update previousStateCLK with the current state of CLK.
Then we do it all over again.
Load the sketch and observe both the serial monitor and the two LEDs. When the CW LED is lit the value in the serial monitor should increment. Otherwise, the CCW LED will be lit and the value will decrement.
You may use this sketch as the basis for your own encoder projects. In fact, the next demo does exactly that!
Control Encoder with Servo Motor
The next experiment we will perform is to use a rotary encoder to control the position of a servo motor.
This is a great application for a rotary encoder as it will let you position the servo motor very precisely. It would be a great way to operate a robot arm, for example, as it would let you precisely position the arm and its grip. Of course, you would need to add more encoders and more servo motors to the design.
Arduino Servo Hookup
The hookup for the servo motor controller is illustrated below:
One thing to note is that I have used a separate power supply for the servo motor. I always recommend doing this as the servo can induce electrical noise onto the 5-volt line that the Arduino uses. But, if you really must, you can eliminate the extra supply and use the Arduino 5-volt output.
Again the pinouts are not critical but if you do change them you’ll need to make sure to use a digital I/O pin on the Arduino that supports PWM for the servo control lead.
Arduino Servo Control Sketch
Here is the sketch you will need to use to control the servo motor with the rotary encoder.
Servo with Encoder
2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 | Rotary Encoder with Servo Motor Demo Demonstrates operation of Rotary Encoder Displays results on Serial Monitor https://dronebotworkshop.com #include <Servo.h> // Rotary Encoder Inputs #define inputDT 5 // Create a Servo object intcurrentStateCLK; pinMode(inputCLK,INPUT); Serial.begin(9600); // Attach servo on pin 9 to the servo object // Assign to previousStateCLK variable currentStateCLK=digitalRead(inputCLK); // If the previous and the current state of the inputCLK are different then a pulse has occured // If the inputDT state is different than the inputCLK state then if(digitalRead(inputDT)!=currentStateCLK){ if(counter<0){ } }else{ counter++; counter=180; myservo.write(counter); Serial.print('Position: '); } previousStateCLK=currentStateCLK; |
If you compare this sketch to the previous one you’ll undoubtedly notice many similarities. It starts out by defining many of the same variables, without the LEDs of course as they are not used here.
We also include the built-in Arduino Servo library and define a myservo object to represent our servo motor.
The counter, currentStateCLK and previousStateCLK variables are used again.
In the Setup we attach the myservo object to pin 9, which is where the control lead of the servo motor is connected.
The Loop is also very much like the previous sketch, with some notable exceptions.
Since a servo motor only accepts a value between 0 and 180 we limit our results to this range.
After getting the counter value we use it to position the servo motor. The value should represent the position of the servo arm in degrees.
We print this position to the serial monitor, reset the previousStateCLK variable and do it all over again.
When you run the sketch observe both the arm on the servo motor and your serial monitor. The arm position should correspond to the reading on the serial monitor.
This is a very accurate method of positioning a servo motor.
Using Gearmotor Encoders
Now that we have seen how to use control encoders let’s turn our attention to encoders used with gearmotors.
![Rotary Quadrature Encoder Rotary Quadrature Encoder](/uploads/1/2/4/8/124865917/352931272.png)
As with the control encoders, the motor encoders have two outputs. This will allow you to determine the direction that the motor is spinning.
I am actually NOT going to decode the motor direction as I don’t really see the point – after all I am the one spinning the motor in a specific direction so I already know which way it is going!
Motor Encoder Output
Before I hook up the encoder to an Arduino thought it might be a good opportunity to take a look at the pulses that it produces. So I hooked the two outputs up to my oscilloscope.
As you can see from the scope traces the two outputs are nice square waves, offset from each other.
You could also use the two square waves to make a more accurate encoder, reading the combination of pulses to get much finer resolution. However, as my encoder gives out 374 pulses per rotation it is already accurate to less than a degree. That is accurate enough for my purposes.
Arduino Motor Encoder Hookup
Now let’s test the encoder with an Arduino. We will hook it up, along with a motor driver and a potentiometer to control speed and read the RPM of the motor.
The motor driver I am using is the Cytron MD10C, which I have used in the article Controlling Large DC Gearmotors. You can read more details about it there if you like. It is very simple to use, requiring only a power supply for the motor to power its internal logic circuits.
I also used a 12-volt power supply, as that is the recommended voltage for my motor.
The potentiometer I used was a 10k linear-taper. Any value from 5k or higher will work.
The connections from the Arduino to the encoder are as follows:
Arduino Pin | Encoder Pin |
5V (5-volt output) | VCC |
Ground | GND |
3 | CH A (Output A) |
Actually, you could have used Output B instead, as I’m not measuring the direction of rotation, just the position.
The input connections to the Cytron MD10C motor driver are as follows:
Arduino Pin | Cytron MD10C Input Pin |
12 | DIR (Direction) |
10 | PWM |
Ground | GND |
I’m not actually using the DIR pin as in this sketch I’m not controlling the motor direction, so you can leave it out if you wish.
The output of the motor controller is connected to, what else, the motor! And the power supply is connected to the power inputs, be sure to observe the proper polarity.
The potentiometer is hooked to analog input A0, so we can control the motor speed.
Arduino Motor Encoder Sketch
Now that we have our motor hooked up it’s time to run the sketch to control and read its speed.
Motor Encoder RPM
2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100 | Gearmotor Rotary Encoder Test Read pulses from motor encoder to calculate speed Displays results on Serial Monitor DroneBot Workshop 2019 */ // Motor encoder output pulse per rotation (change as required) #define ENC_IN 3 // MD10C PWM connected to pin 10 // MD10C DIR connected to pin 12 intspeedcontrol=0; // Pulse count from encoder intinterval=1000; // Counters for milliseconds during interval longcurrentMillis=0; // Variable for RPM measuerment intmotorPwm=0; voidsetup() // Setup Serial Monitor pinMode(ENC_IN,INPUT_PULLUP); // Set PWM and DIR connections as outputs pinMode(DIR,OUTPUT); // Attach interrupt attachInterrupt(digitalPinToInterrupt(ENC_IN),updateEncoder,RISING); // Setup initial values for timer } voidloop() motorPwm=map(analogRead(speedcontrol),0,1023,0,255); // Write PWM to controller currentMillis=millis(); previousMillis=currentMillis; rpm=(float)(encoderValue *60/ENC_COUNT_REV); // Only update display when there is a reading Serial.print('PWM VALUE: '); Serial.print('t'); Serial.print(encoderValue); Serial.print(' SPEED: '); Serial.println(' RPM'); } { encoderValue++; |
In this sketch we will need to use interrupts to count pulses from our encoder, this is because our pulses will be arriving pretty quickly as compared to reading an encoder control.
Before we can use the sketch we need to know how many pulses our encoder will produce for one rotation of the motor. You can determine this from the specification sheet for your motor. Without this value, you won’t be able to get an accurate RPM reading.
My motor produces 374 pulses per rotation, so I set the constant ENC_COUNT_REV to this value.
The next few lines define the pins that connect to the motor encoder, motor driver and to the potentiometer.
We will use the long encoderValue to keep track of the pulses we receive from the encoder. Then we will count how many of these occur in one second. By multiplying this by 60 we’ll know how many pulses we should get in a minute. If we divide this value by the ENC_COUNT_REV then we can determine the RPM of the motor shaft.
We will measure the one-second interval by keeping track of the number of milliseconds that have elapsed. The Arduino millis() function counts the number of milliseconds since the Arduino was last reset or powered on, so we can get out interval using this.
At the bottom of the sketch is an interrupt handler, it simply increments the value of encoderValue when it is triggered by a pulse from the encoder.
In the Setup we attach the interrupt handler to the pin connected to the encoder (pin 3), we trigger on a rising pulse.
The Loop starts with reading the value of the analog input connected to the potentiometer. We use the Arduino Map Function to change its range to 0-255 and an analogWrite command to send a PWM signal with this value to the motor controller. This results in the motor turning at the desired speed.
We see if 1000 milliseconds have elapsed, if so we read the count and do the math to determine the RPM. We then print the values to the serial monitor. Note the use of the tab character to format these results in nice columns.
After printing the value we reset the encoderValue variable to zero so we can begin counting again.
Load the sketch and power everything up. Turn the potentiometer and observe the motor turning, as well as the value on the serial monitor.
Conclusion
Rotary encoders are pretty versatile, they can be used as both controls and as sensors.
As controls, they have much greater precision than a potentiometer, and they cost just a little bit more. I know that I’m planning to create many of my future designs using them.
I also will be building a complete motor controller using the rotary encoder included with my gear motor. Being able to position my robot to within less than a millimeter is an extremely attractive proposition.
I hope this article, and its associated video, have opened your eyes to some tasks you can perform with a rotary encoder.
Resources
Sketches – ZIP file with all of the sketches used in this article.
Related
Using Rotary Encoders with Arduino
Description
Rotary Encoders can be used in two fashions - as a control with more versatility than a potentiometer, and as a device to measure mechanical rotation. Today I will show you how to use both types of rotary encoders.
Author
DroneBot Workshop
Publisher Logo