Created
March 1, 2017 19:10
-
-
Save davidegironi/3144efdc6d67e5df55438cc3cba613c8 to your computer and use it in GitHub Desktop.
Arduino Random Rainbow Stop
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Arduino Random Rainbow Stop | |
Random Led Strip Selection | |
Copyright (c) Davide Gironi, 2015 | |
References: | |
+ https://github.com/technobly/NeoPixel-KnightRider | |
+ https://github.com/adafruit/Adafruit_NeoPixel | |
Released under GPLv3. | |
Please refer to LICENSE file for licensing information. | |
*/ | |
#include <Adafruit_NeoPixel.h> | |
#include <avr/power.h> | |
// Stop/Start button pin | |
#define BUTTONPIN 6 | |
// Pin number for the led strip | |
#define LEDPIN 5 | |
// Number of led connected | |
#define LEDNUM 12 | |
// Random minimum led increase interval for selection | |
#define LEDSELMIN 25 | |
// Random minimum led increase interval for selection | |
#define LEDSELMAX 45 | |
// Minimum time to delay on rainbow random select loop | |
#define RAINBOWSPEEDMIN 50 | |
// Maximum time to delay on rainbow random select loop | |
#define RAINBOWSPEEDMAX 80 | |
// With of the previous dim led | |
#define PREVIOUSLEDDIMWITH 10 | |
// Loop back and forth or circular | |
#define LOOPBACKANDFORTH 0 | |
// Delay used for rainbow (ms) | |
#define RAYINBOWDELAYMS 20 | |
// Enabled the idle loop after a button is selected | |
#define IDLELOOPENABLEDONSELECT 1 | |
// Time to enable the idle loop (ms) | |
#define IDLELOOPENABLEDTIMEMS 30000 | |
// NeoPixel library initialization | |
Adafruit_NeoPixel strip = Adafruit_NeoPixel(LEDNUM, LEDPIN, NEO_GRB + NEO_KHZ800); | |
// Actual led | |
static uint16_t current_led = 0; | |
// Actual color number | |
static uint8_t colornum = 0; | |
// Actual direction | |
static uint8_t dir = 1; | |
// Idle loop | |
static uint8_t idleloop = 1; | |
// Setup the Arduino | |
void setup() { | |
uint8_t i; | |
//set button | |
pinMode(BUTTONPIN, INPUT); | |
//set first led | |
current_led = 0; | |
//set first color | |
colornum = 0; | |
//initialize random | |
randomSeed(analogRead(0)); | |
//start NeoPixel | |
strip.begin(); | |
//set all off | |
for(i=0; i< strip.numPixels(); i++) { | |
strip.setPixelColor(i, 0, 0, 0); | |
strip.show(); | |
} | |
//wait a little | |
delay(1000); | |
} | |
// Main Arduino loop | |
void loop() { | |
uint16_t i, j; | |
//perform an idleloop | |
while(idleloop) { | |
for(j=0; j<256; j++) { | |
for(i=0; i<strip.numPixels(); i++) { | |
strip.setPixelColor(i, colorWheel((i+j) & 255)); | |
} | |
strip.show(); | |
if(digitalRead(BUTTONPIN) == HIGH) { | |
while(digitalRead(BUTTONPIN) == HIGH); | |
idleloop = 0; | |
//set all off | |
for(i=0; i< strip.numPixels(); i++) { | |
strip.setPixelColor(i, 0, 0, 0); | |
strip.show(); | |
} | |
delay(500); | |
break; | |
} | |
delay(RAYINBOWDELAYMS); | |
} | |
} | |
//set the stop led | |
uint16_t stop_led = random(LEDSELMIN, LEDSELMAX); | |
//do the rainbox selection | |
stopRainbow(stop_led, RAINBOWSPEEDMIN, RAINBOWSPEEDMAX, PREVIOUSLEDDIMWITH); | |
//set all off | |
for(i=0; i<LEDNUM; i++) { | |
strip.setPixelColor(i, 0, 0, 0); | |
strip.show(); | |
} | |
//stay on the select led until button is pressed, or idle timer is passed | |
uint32_t preMillis = millis(); | |
while(digitalRead(BUTTONPIN) == LOW) { | |
#if IDLELOOPENABLEDONSELECT == 1 | |
uint32_t curMillis = millis(); | |
if(curMillis - preMillis > IDLELOOPENABLEDTIMEMS) { | |
idleloop = 1; | |
break; | |
} | |
#endif | |
colornum++; | |
uint32_t color = colorWheel(colornum); | |
strip.setPixelColor(current_led, color); | |
strip.show(); | |
delay(RAYINBOWDELAYMS); | |
} | |
//wait for the button to release | |
while(digitalRead(BUTTONPIN) == HIGH); | |
} | |
// Loop colors and stop on selected led | |
// stop_led - led to stop on | |
// speedmin - timed led on/off minimum speed | |
// speedmax - timed led on/off maxmimum speed | |
// width - preious leds dim width | |
void stopRainbow(uint16_t stop_led, uint16_t speedmin, uint16_t speedmax, uint8_t width) { | |
uint16_t prev_color[LEDNUM]; | |
uint16_t current_stopled = 0; | |
uint32_t color = 0; | |
uint16_t x = 0; | |
uint8_t changeddir = 0; | |
//rest previous color | |
for(x=0; x<LEDNUM; x++) { | |
prev_color[x] = 0; | |
} | |
while(1) { | |
//set a color | |
color = colorWheel(colornum); | |
prev_color[current_led] = color; | |
strip.setPixelColor(current_led, color); | |
//dim previous colors | |
for(x=0; x<LEDNUM; x++) { | |
if(x != current_led) { | |
prev_color[x] = dimColor(prev_color[x], width); | |
strip.setPixelColor(x, prev_color[x]); | |
} | |
} | |
//show strip | |
strip.show(); | |
//next color | |
colornum++; | |
//stop on destination led | |
current_stopled++; | |
if(current_stopled>stop_led) { | |
//stop running | |
break; | |
} | |
//next led | |
#if LOOPBACKANDFORTH == 1 | |
if(dir) { | |
current_led++; | |
if(current_led == LEDNUM-1) { | |
dir = 0; | |
} | |
} else { | |
if(current_led == 0) { | |
current_led++; | |
dir = 1; | |
} else | |
current_led--; | |
} | |
#else | |
current_led++; | |
if(current_led == LEDNUM) | |
current_led = 0; | |
#endif | |
//delay a little | |
uint16_t speed = random(speedmin, speedmax); | |
delay(speed); | |
} | |
} | |
// Dim a color given a width | |
uint32_t dimColor(uint32_t color, uint8_t width) { | |
return (((color&0xFF0000)/width)&0xFF0000) + (((color&0x00FF00)/width)&0x00FF00) + (((color&0x0000FF)/width)&0x0000FF); | |
} | |
// Input a value 0 to 255 to get a color value. | |
// The colours are a transition r - g - b - back to r. | |
uint32_t colorWheel(uint8_t pos) { | |
if(pos < 85) { | |
return strip.Color(pos * 3, 255 - pos * 3, 0); | |
} else if(pos < 170) { | |
pos -= 85; | |
return strip.Color(255 - pos * 3, 0, pos * 3); | |
} else { | |
pos -= 170; | |
return strip.Color(0, pos * 3, 255 - pos * 3); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment