This is a follow-up to my previous writings on the subject of rotary encoders: Rotary Encoders on the i2c Bus. This time I am using the Sparkfun Rotary Encoder – Illuminated (RGB) (Part: COM-10982), this has the same rotary goodness as the SparkFun 12-step rotary encoder but with the addition of three LED’s to provide a whole host of colours on the rotating shaft.

Test Setup
Again I will be using the MCP23017 port expander to add 16 digital I/O ports to the Arduino via the i2c bus, the rotary encoder part operates in the same manner as before and we can use the internal pull-up resistors to reduce the number of components. The LED’s operate with a common anode and the push button also operates on 5v rather than the usual switching to ground.

For my test setup I have connected the rotary encoder to GPA0 and GPA1, the push button to GPA2 and the Red, Green and Blue LED’s to GPA5, GPA4 and GPA3. Note the 10K pull-down resistor on the push button.
My program on the Arduino changes the colours as you rotate the shaft, you will see seven colours, to see more you would need to use PWM to control the LED’s brightness. With the common anode on the LED’s the logic for switching them is inverted, so HIGH = off, LOW = on. You will need the Adafruit MCP23017 Arduino Library.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
#include <Wire.h> #include "Adafruit_MCP23017.h" // https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library // setup the port expander Adafruit_MCP23017 mcp0; #define ROT_A 0 #define ROT_B 1 #define ROT_BTN 2 #define ROT_RED 3 #define ROT_GRN 4 #define ROT_BLU 5 // some colours to display // because of the common anode on the LED's, logic is inverted: 0 = on, 1 = off // R G B boolean colours[8][3] = { {1, 1, 1}, // off (black) {1, 1, 0}, // blue {1, 0, 1}, // green {1, 0, 0}, {0, 1, 1}, // red {0, 1, 0}, {0, 0, 1}, {0, 0, 0}}; // white int colPointer = 0; unsigned long currentTime; unsigned long loopTime; int rotAprev=0; const int leds[3] = { ROT_RED, ROT_GRN, ROT_BLU }; void setColours(boolean colour[]) { for (int i=0; i<3; i++) { mcp0.digitalWrite(leds[i], colour[i]); } return; } void setup() { Serial.begin(9600); mcp0.begin(0); // 0 = i2c address 0x20 mcp0.pinMode(ROT_A, INPUT); // Rotary switch A mcp0.pullUp(ROT_A, HIGH); // turn on a 100K pullup internally mcp0.pinMode(ROT_B, INPUT); // Rotary switch B mcp0.pullUp(ROT_B, HIGH); // turn on a 100K pullup internally mcp0.pinMode(ROT_BTN, INPUT); // Push Button mcp0.pinMode(ROT_RED, OUTPUT); // Red mcp0.pinMode(ROT_GRN, OUTPUT); // Green mcp0.pinMode(ROT_BLU, OUTPUT); // Blue mcp0.digitalWrite(ROT_RED, HIGH); // all colours off mcp0.digitalWrite(ROT_GRN, HIGH); // HIGH = off, LOW = on mcp0.digitalWrite(ROT_BLU, HIGH); currentTime = millis(); loopTime = currentTime; Serial.println("ready"); setColours(colours[0]); } void loop() { currentTime = millis(); // check every 5 millisecs if(currentTime >= (loopTime + 5)) { int rotA = mcp0.digitalRead(ROT_A); int rotB = mcp0.digitalRead(ROT_B); // turn white if the button is pressed if (mcp0.digitalRead(ROT_BTN) == true) { setColours(colours[7]); } // see if there has been any rotation if((!rotA) && (rotAprev)) { if (rotB) { Serial.println("clockwise"); colPointer++; } else { Serial.println("counter-clockwise"); colPointer--; } // make sure the pointer stays within range if (colPointer > 7) { colPointer = 0; } if (colPointer < 0) { colPointer = 7; } Serial.print("pointer: "); Serial.println(colPointer); // set the shaft colour to that in pointer setColours(colours[colPointer]); } rotAprev = rotA; loopTime = currentTime; // Updates loopTime } } |
Links
- UK supplier: http://www.hobbytronics.co.uk/rotary-encoder-rgb they also have a useful breakout board for the switch
- MCP23017/MCP23S17 Data Sheet
- Rotary Encoder – Illuminated (RGB) Data Sheet