Introduction: RGB LED Color Selector / Picker / Chooser

About: A Maker since childhood with all the classic symptoms, a robot builder, and an Internet software CTO/Tech Product Manager.

One Challenge with working with RGB LEDs is getting the right Red, Green and Blue values to match a color you are trying to display. You can start with web colors, and then sometimes need to adjust them since the LEDs don't look quite the same as they do on monitors.

So, this is a quick project to allow you to set the RGB values with a simple hand-held gadget - maybe useful when working offline with these LEDs.

This project shows a WS2812b digitally addressable LED, but could be adapted for other LED types.

Parts:

  • An Arduino - clones can be found for $10
  • An Adafruit LCD Shield - this shield has a 16x2 LED display, and 5 push buttons that we will use for changing the red, green, and blue color values. Adafruit also has a shield where the backlight color is an RGB LED - might be worth trying!
  • An LED - this one uses a single WS2812b LED from a 30 LED/meter strip of LEDs - we had this left over from another project. Adafruit sells them individually on carrier boards too.
  • Some solid core wire - I used some 20 gauge wire since it was rigid and held the LED nicely.

Step 1: Construction

Build the LED Shield per the instructions that come with it (online).  Test it our with your Arduino.

Now, we will solder the LED to the board.  Since the LCD Shield is intended to be on the top of the stack of shields, the pins are not brought out in header sockets.  But the pins are there to mechanically support the shield, so you can carefully solder wires to the tops of those pins.  See the pictures for details.

We will solder digital pin 6 to the data in line - that has to be connected to the input end of the arrow on the LED since they have a direction on the data line.  The other two wires are the +5v, and Gnd - those can be soldered on either end of the LED.

The LED is very bright, so one idea is to put a piece of white paper over it.  Or perhaps aim it down and run it over a white surface.

Step 2: Code

The below code is what I used to test the board. The top line shows the current R, G, and B values (0-255) with a star to the left of the current one. The second row shows the step size for the +/- buttons. The commands are:
  • Down Button: reduce the selected color (R, G, or B) by the current step size
  • Up Button: increase the selected color (R, G, or B) by the current step size
  • Left Button: move to the previous color
  • Right button: move to the next color
  • Select button: toggle the step size from 1 to 5 to 10 to 20 to 50, then back to 1...
The code uses the Adafruit LCD Shield and Neopixel libraries. The sample code is below.

You could also add a connector and power a full string with this approach.

The code I used:



//*********************
// RGB_LCD - use the Adafruit LCD shield to set the RGB values on a single WS2812b LED
// Based on the Adafruit Neopixel and LCD Shield Libraries and examples
// December, 2013 Carl Sutter
//*********************

// LCD Shield Library
#include <Wire.h>
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>
// The shield uses the I2C SCL and SDA pins. On classic Arduinos
// this is Analog 4 and 5 so you can't use those for analogRead() anymore
// However, you can connect other I2C sensors to the I2C bus and share
// the I2C bus.
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

// Neopixel Library
#include <Adafruit_NeoPixel.h>
#define PIN 6
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(1, PIN, NEO_GRB + NEO_KHZ800);

// These #defines make it easy to set the backlight color - use if you have an RGB shield
//#define RED 0x1
//#define YELLOW 0x3
//#define GREEN 0x2
//#define TEAL 0x6
//#define BLUE 0x4
//#define VIOLET 0x5
#define WHITE 0x7
#define ARROW 0x7E
#define LARROW 0x7F
#define DELAY_QUICK 40    // the shortes delay between presses so you can scroll quickly, but still get to a specific button press / value
#define DELAY_SLOW 100    // slower delay for buttons thatare changing modes etc.

uint8_t curCols[] = {127, 127, 127};   // array of current RGB values
uint8_t curCol = 0;                    // index of the current color being worked on - 0=R, 1-G, 2=B
uint8_t step_size = 1;                 // the amount to move in each button press

void setup() {
  lcd.begin(16, 2);

  strip.begin();
  strip.show(); // Initialize all pixels to 'off'

  lcd.setBacklight(WHITE);
  
  // leave the "Step Size:" label on the display so it does not flicker 
  lcd.setCursor(2,1);
  lcd.print("Step Size: ");
  
  // display the startup data
  display();
}

// display - print the RGB values and set the LED
void display() {
  uint8_t i;
  
  strip.setPixelColor(0, curCols[0], curCols[1], curCols[2]);
  strip.show();

  lcd.setCursor(0,0);
  for (i=0; i<3; i++) {
    if (curCol == i) {
      lcd.print(char('*'));
    } else {
      lcd.print(' ');
    }

    if (i == 0) lcd.print('R');
    if (i == 1) lcd.print('G');
    if (i == 2) lcd.print('B');

    if (curCols[i]<100) lcd.print(' ');
    if (curCols[i]<10) lcd.print(' ');
    lcd.print(curCols[i]);
  }  

  //lcd.setCursor(2,1);
  //lcd.print("Step Size: ");
  lcd.setCursor(13,1);
  lcd.print(step_size);
  lcd.print(' ');  // hack to have one digit #s print over old 2 digit #s
} // print_val


void loop() {
  uint8_t buttons = lcd.readButtons();

  if (buttons) {
    if (buttons & BUTTON_UP) {
      curCols[curCol] += step_size;
      display();
      delay(DELAY_QUICK);
    }
    if (buttons & BUTTON_DOWN) {
      curCols[curCol] -= step_size;
      display();
      delay(DELAY_QUICK);
    }
    if (buttons & BUTTON_LEFT) {
      if (curCol == 0) {
        curCol = 2;
      } else {  
        curCol--;
      }  
      display();
      delay(DELAY_SLOW);
    }
    if (buttons & BUTTON_RIGHT) {
      if (curCol == 2) {
        curCol = 0;
      } else {  
        curCol++;
      }  
      display();
      delay(DELAY_SLOW);
    }
    if (buttons & BUTTON_SELECT) {
      switch (step_size) {
        case 1:
          step_size = 5;
          break;
        case 5:
          step_size = 10;
          break;
        case 10:
          step_size = 20;
          break;
        case 20:
          step_size = 50;
          break;
        default: 
          step_size = 1;
      }
      display();
      delay(DELAY_SLOW);
    }
    
  } // buttons != 0
} // loop

Make It Glow Contest

Participated in the
Make It Glow Contest