Demo for Sparkfun's RPG with internal RGB led using interrupts
Using a Rotary Pulse Generator (RPG) or Rotary Encoder
This is a demo for Sparkfun's RPG (rotary pulse generator or rotary encoder) with an internal RGB led using interrupts to read the 2-bit encoder signal. By monitoring these output bits, the amount and direction of rotation of the knob by the user can be determined. Pushing the knob down activates a pushbutton that can be used to change modes in a device. See comments in main.cpp for more details and pin hookups. The RPG is mounted on Sparkfun's breakout board. The code uses the encoder count to dim the built-in red LED using PWM. The RPG's shaft pushbutton is also debounced using interrupts.
While simple software polling (programmed I/O) could be used to read the encoder bits, interrupts are more efficient in this application since it would be necessary to sample and read the two encoder bits a couple hundred times a second when someone spins the knob. Since the vast majority of the time bits are not changing at all, constantly polling this fast wastes a lot of processor time and power!
Inside view of a RPG (rotary encoder) showing encoder wheel (silver teeth on left) and dual switch contacts (right) from https://www.robotroom.com/Counter5.html. Two parallel contacts are often used to increase reliability and reduce contact bounce.
This style RPG has one toothed encoder wheel but the contacts are at different angles for the phase shift between the two output bits.
Encoder animation of A and B output bits from Wikipedia
The truth table is stored in a predefined C array:
const int lookup_table[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
An interrupt routine is called whenever one of the two bits changes state and the truth table in an array is checked to determine how to change the count (i.e.+1, -1, 0). The encoder uses Gray code (only 1 bit changes at a time), if no bits or two bits change it may be switch contact noise and the count is not changed (i.e., a "0") in the truth table. See http://makeatronics.blogspot.com/2013/02/efficiently-reading-quadrature-with.html for a detailed explanation of the RPG encoder counting algorithm using interrupts with a lookup table.
The header pins are spaced so far apart that all of the jumper wire pins are under the PCB in the normal breadboard locations for an IC, but if you put in across a power bus (power bus under middle of PCB) as seen in the photo below, you will have room to connect the jumper wires after inserting the breakout (otherwise pins for jumper wires are all under the breakout board).
Parts used:
https://www.sparkfun.com/products/15141 https://www.sparkfun.com/products/11722 https://www.sparkfun.com/products/10597
Wiring
RPG breakout | mbed LPC1768 |
---|---|
A encoder output bit | p14 |
B encoder output bit | p15 |
C encoder common | gnd |
+ LED+ for RGB LED | Vout 3.3 |
R LED- | p21 |
G LED- | p22 |
B LED- | p23 |
SW pushbutton | p16 |
This same scheme of two phase shifted encoder output bits to determine CW or CCW rotation is often used for feedback in motor control systems. In this application, it is called a quadrature encoder (QE). In fast motors, an optical signal is used to read the bits from the encoder wheel instead of a mechanical switch contact as in this RPG. The mbed LPC1768 has a built-in hardware quadrature encoder interface with a counter that would be nice to use for the RPG, but it does not come out on the module's limited breadboard pins.
mbed.bld@0:3eea8ad2dbbc, 2022-01-12 (annotated)
- Committer:
- 4180_1
- Date:
- Wed Jan 12 19:52:47 2022 +0000
- Revision:
- 0:3eea8ad2dbbc
ver 1.0
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
4180_1 | 0:3eea8ad2dbbc | 1 | https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400 |