Colecago’s Blog » 3D Printing, Arduino, Boardgames, LED, Project

D20 RGB Lamp Writeup

I recently created a D20 RGB Lamp using my 3D printer, and Arduino, and RGB LED lights.  Demonstration below

 

Menu Flow Diagram:

 

Parts List:

Parts:
Arduino – https://www.sparkfun.com/products/11113
LEDs (x5) – https://www.sparkfun.com/products/13282
Power Supply – https://www.sparkfun.com/products/12889
Barrel Jack – https://www.sparkfun.com/products/10785
Push buttons (similar, x2) – https://www.sparkfun.com/products/9190
D20 Translucent – http://amzn.to/2hLp1iy

3D Files –¬†https://www.thingiverse.com/thing:2010875

 

Code:

Requires Neopixel libraries, move from the zipped libraries folder to your Arduino Libraries folder. ¬†Code was created for 5 LED’s and the following hookup-

Data Out (from Arduino) – Pin 3

SW1 (internal pullup used, connect one side to ground) – Pin 4

SW2 (internal pullup used, connect one side to ground) – Pin 5

D20 Lamp Code

/* SparkFun WS2812 Breakout Board Example
SparkFun Electronics
date: July 25, 2013
license: GNU GENERAL PUBLIC LICENSE
Requires the Adafruit NeoPixel library. It’s awesome, go get it.
https://github.com/adafruit/Adafruit_NeoPixel
This simple example code runs three sets of animations on a group of WS2812
breakout boards. The more boards you link up, the better these animations
will look.
For help linking WS2812 breakouts, checkout our hookup guide:
https://learn.sparkfun.com/tutorials/ws2812-breakout-hookup-guide
Before uploading the code, make sure you adjust the two defines at the
top of this sketch: PIN and LED_COUNT. Pin should be the Arduino pin
you’ve got connected to the first pixel’s DIN pin. By default it’s
set to Arduino pin 4. LED_COUNT should be the number of breakout boards
you have linked up.
*/
#include <Adafruit_NeoPixel.h>
#include “WS2812_Definitions.h”
#define LED_DATA 3
#define LED_COUNT 5
#define POT1 A0
#define POT2 A1
#define SW1 4
#define SW2 5
#define MENURUN 0
#define MENUBRIGHTNESS 1
#define MENUANIMATION 2
#define MENUANIMATIONCOLOR 3
#define MENUSTOP 4
#define RAINBOW 0
#define RACE 1
#define FULLFADE 2
#define FADE 3
#define RAINBOWFADE 4
#define LIGHT 1
#define DARK 0
#define MAXBRIGHTNESS 250
#define DEBOUNCEMAX 150
#define delaySpeedMax 750
unsigned char menuState = MENURUN;
unsigned char brightness = 125;
unsigned int menuButtonDebounceTime = DEBOUNCEMAX;
unsigned char menuButtonPressed = 0;
unsigned char menuButton = 0;
unsigned int menuSelectDebounceTime = DEBOUNCEMAX;
unsigned char menuSelectPressed = 0;
unsigned char menuSelect = 0;
unsigned char rainbowCounter = 0;
unsigned int delaySpeed = 150;
unsigned int delaySpeedCounter = delaySpeed;
unsigned char animationMode = RAINBOW;
unsigned long animationColor = RED;
unsigned char fadeBrightness = 0;
unsigned char fadeDirection = LIGHT;
unsigned char rainbowMode = 0;
unsigned long internalColor = RED;
unsigned int theaterJ = 0;
unsigned int theaterQ = 0;
unsigned char theaterON = 0;
// Create an instance of the Adafruit_NeoPixel class called “leds”.
// That’ll be what we refer to from here on…
Adafruit_NeoPixel leds = Adafruit_NeoPixel(LED_COUNT, LED_DATA, NEO_GRB + NEO_KHZ800);
void setup()
{
//pinMode(POT1, INPUT);
//pinMode(POT2, INPUT);
pinMode(SW1, INPUT);
digitalWrite(SW1, HIGH);
pinMode(SW2, INPUT);
digitalWrite(SW2, HIGH);
leds.begin(); // Call this to start up the LED strip.
clearLEDs(); // This function, defined below, turns all LEDs off…
leds.show(); // …but the LEDs don’t actually update until you call this.
randomSeed(analogRead(0));
animationColor = getRandomColor(0);
}
void loop()
{
unsigned int addedDelay = 0;
//unsigned int brightness = analogRead(POT1);
//unsigned int delaySpeed = analogRead(POT2);
if (!digitalRead(SW1)) {
if (menuButtonDebounceTime)
menuButtonDebounceTime–;
else {
if (!menuButtonPressed) {
menuButtonPressed = 1;
menuButton = 1;
}
else
menuButton = 0;
}
}
else {
if (menuButtonDebounceTime < DEBOUNCEMAX)
menuButtonDebounceTime++;
else
menuButtonPressed = 0;
}
if (!digitalRead(SW2)) {
if (menuSelectDebounceTime)
menuSelectDebounceTime–;
else {
if (!menuSelectPressed) {
menuSelectPressed = 1;
menuSelect = 1;
}
else
menuSelect = 0;
}
}
else {
if (menuSelectDebounceTime < DEBOUNCEMAX)
menuSelectDebounceTime++;
else
menuSelectPressed = 0;
}
if (menuButton) {
if (menuState < 4)
menuState++;
else
menuState = 0;
clearLEDs(); // This function, defined below, turns all LEDs off…
rainbowCounter = 0;
internalColor = animationColor;
rainbowMode = 0;
fadeBrightness = 0;
fadeDirection = LIGHT;
theaterJ = 0;
theaterQ = 0;
theaterON = 0;
}
switch (menuState) {
case MENURUN:
// Ride the Rainbow Road
if (menuSelect) {
if (delaySpeed < delaySpeedMax)
delaySpeed += 50;
else
delaySpeed = 50;
}
if ((animationMode == RAINBOW) || (animationMode == RACE))
addedDelay = 100;
else
addedDelay = 0;
if (delaySpeedCounter)
delaySpeedCounter–;
else {
delaySpeedCounter = delaySpeed + addedDelay;
switch (animationMode) {
case RAINBOW:
doRainbow();
break;
case RACE:
rainbowMode = 1;
doRace();
break;
case FULLFADE:
//rainbowMode = 1;
theaterChaseRainbow();
break;
case FADE:
doFade();
break;
case RAINBOWFADE:
rainbowMode = 1;
doFade();
break;
default:
break;
}
}
//delay(100); // Delay between rainbow slides
break;
case MENUBRIGHTNESS:
if (menuSelect) {
if (brightness < MAXBRIGHTNESS)
brightness += 25;
else
brightness = 25;
}
leds.setBrightness(brightness);
leds.setPixelColor(0, BLUE);
leds.setPixelColor(1, RED);
leds.setPixelColor(2, GREEN);
leds.setPixelColor(3, PURPLE);
leds.setPixelColor(4, WHITE);
break;
case MENUANIMATION:
if (menuSelect) {
if (animationMode < 4)
animationMode++;
else
animationMode = 0;
if (animationMode == 2 || animationMode == 4)
rainbowMode = 1;
else
rainbowMode = 0;
}
clearLEDs();
leds.setPixelColor(animationMode, RED);
break;
case MENUANIMATIONCOLOR:
if (menuSelect) {
animationColor = getRandomColor(animationColor);
}
leds.setPixelColor(0, GREEN);
leds.setPixelColor(1, animationColor);
break;
case MENUSTOP:
//leds.setPixelColor(0, PURPLE);
break;
default:
menuState = MENUSTOP;
break;
}
leds.show(); // …but the LEDs don’t actually update until you call this.
/*
// Indigo cylon
// Do a cylon (larson scanner) cycle 10 times
for (int i=0; i<10; i++)
{
// cylon function: first param is color, second is time (in ms) between cycles
cylon(INDIGO, 500); // Indigo cylon eye!
}
*/
/*
// A light shower of spring green rain
// This will run the cascade from top->bottom 20 times
for (int i=0; i<20; i++)
{
// First parameter is the color, second is direction, third is ms between falls
cascade(MEDIUMSPRINGGREEN, TOP_DOWN, 100);
}
*/
}
void doRainbow() {
if (rainbowCounter < 10 * 5)
rainbowCounter++;
else
rainbowCounter = 0;
rainbow(rainbowCounter);
}
void doRace() {
if (rainbowCounter < 4)
rainbowCounter++;
else {
if (rainbowMode)
internalColor = getRandomColor(internalColor);
else
internalColor = animationColor;
rainbowCounter = 0;
}
race(internalColor, rainbowCounter);
}
void doFade() {
unsigned char brightStep = brightness / 25;
if (fadeDirection == LIGHT) {
if (fadeBrightness < brightness – brightStep)
fadeBrightness += brightStep;
else {
fadeBrightness = brightness;
fadeDirection = DARK;
}
}
else {
if (fadeBrightness > brightStep)
fadeBrightness -= brightStep;
else {
fadeBrightness = 0;
fadeDirection = LIGHT;
if (rainbowMode)
internalColor = getRandomColor(internalColor);
else
internalColor = animationColor;
}
}
leds.setPixelColor(0, internalColor);
leds.setPixelColor(1, internalColor);
leds.setPixelColor(2, internalColor);
leds.setPixelColor(3, internalColor);
leds.setPixelColor(4, internalColor);
leds.setBrightness(fadeBrightness);
}
void race (unsigned long color, unsigned char pixel) {
byte red = (color & 0xFF0000) >> 16;
byte green = (color & 0x00FF00) >> 8;
byte blue = (color & 0x0000FF);
clearLEDs();
leds.setPixelColor(pixel, red, green, blue);
}
// Sets all LEDs to off, but DOES NOT update the display;
// call leds.show() to actually turn them off after this.
void clearLEDs()
{
for (int i = 0; i < LED_COUNT; i++)
{
leds.setPixelColor(i, 0);
}
}
// Prints a rainbow on the ENTIRE LED strip.
// The rainbow begins at a specified position.
// ROY G BIV!
void rainbow(byte startPosition)
{
// Need to scale our rainbow. We want a variety of colors, even if there
// are just 10 or so pixels.
int rainbowScale = 192 / LED_COUNT;
// Next we setup each pixel with the right color
for (int i = 0; i < LED_COUNT; i++)
{
// There are 192 total colors we can get out of the rainbowOrder function.
// It’ll return a color between red->orange->green->…->violet for 0-191.
leds.setPixelColor(i, rainbowOrder((rainbowScale * (i + startPosition)) % 192));
}
// Finally, actually turn the LEDs on:
//leds.show();
}
// Input a value 0 to 191 to get a color value.
// The colors are a transition red->yellow->green->aqua->blue->fuchsia->red…
// Adapted from Wheel function in the Adafruit_NeoPixel library example sketch
uint32_t rainbowOrder(byte position)
{
// 6 total zones of color change:
if (position < 31) // Red -> Yellow (Red = FF, blue = 0, green goes 00-FF)
{
return leds.Color(0xFF, position * 8, 0);
}
else if (position < 63) // Yellow -> Green (Green = FF, blue = 0, red goes FF->00)
{
position -= 31;
return leds.Color(0xFF – position * 8, 0xFF, 0);
}
else if (position < 95) // Green->Aqua (Green = FF, red = 0, blue goes 00->FF)
{
position -= 63;
return leds.Color(0, 0xFF, position * 8);
}
else if (position < 127) // Aqua->Blue (Blue = FF, red = 0, green goes FF->00)
{
position -= 95;
return leds.Color(0, 0xFF – position * 8, 0xFF);
}
else if (position < 159) // Blue->Fuchsia (Blue = FF, green = 0, red goes 00->FF)
{
position -= 127;
return leds.Color(position * 8, 0, 0xFF);
}
else //160 <position< 191 Fuchsia->Red (Red = FF, green = 0, blue goes FF->00)
{
position -= 159;
return leds.Color(0xFF, 0x00, 0xFF – position * 8);
}
}
uint32_t getRandomColor(uint32_t oldColor) {
uint32_t tempColor = oldColor;
tempColor = Wheel(random(255));
while (tempColor == oldColor) {
tempColor = Wheel(random(255));
}
return tempColor;
}
//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow() {
if (theaterON) {
//leds.setPixelColor(0, 0); //turn every third pixel off
//leds.setPixelColor(2, 0); //turn every third pixel off
//leds.setPixelColor(4, 0); //turn every third pixel off
leds.setPixelColor(1, Wheel( (1 + theaterJ) % 255)); //turn every third pixel on
leds.setPixelColor(3, Wheel( (3 + theaterJ) % 255)); //turn every third pixel on
theaterON = 0;
}
else {
//leds.setPixelColor(1, 0); //turn every third pixel off
//leds.setPixelColor(3, 0); //turn every third pixel off
leds.setPixelColor(0, Wheel( (0 + theaterJ) % 255)); //turn every third pixel on
leds.setPixelColor(2, Wheel( (2 + theaterJ) % 255)); //turn every third pixel on
leds.setPixelColor(4, Wheel( (4 + theaterJ) % 255)); //turn every third pixel on
theaterON = 1;
}
if (theaterJ < 255)
theaterJ++;
else
theaterJ = 0;
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r – g – b – back to r.
uint32_t Wheel(byte WheelPos)
{
WheelPos = 255 – WheelPos;
if (WheelPos < 85)
{
return leds.Color(255 – WheelPos * 3, 0, WheelPos * 3);
}
else if (WheelPos < 170)
{
WheelPos -= 85;
return leds.Color(0, WheelPos * 3, 255 – WheelPos * 3);
}
else
{
WheelPos -= 170;
return leds.Color(WheelPos * 3, 255 – WheelPos * 3, 0);
}
}

One thought on “D20 RGB Lamp Writeup

  1. Pingback: D20 Glowing RGB Lamp #3DPrinting #3DThursday « Adafruit Industries – Makers, hackers, artists, designers and engineers!

Leave a Reply

Your email address will not be published. Required fields are marked *