Skip to content

Instantly share code, notes, and snippets.

@ondrejh
Created November 29, 2020 07:59
Show Gist options
  • Save ondrejh/27dbf9a58ca6e823209e271567270513 to your computer and use it in GitHub Desktop.
Save ondrejh/27dbf9a58ca6e823209e271567270513 to your computer and use it in GitHub Desktop.
Slowly changing color light strip using arduino and neopixels
/**
* Slowly changing color light strip using arduino and neopixels. Suitable for mood lights.
* recent usage: sauna pool downlight, advent candlestick ..
*/
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 2
#define NUMPIXELS 28
#define PERIOD 20 //ms
//#define DEBUG
uint8_t r[NUMPIXELS];
uint8_t g[NUMPIXELS];
uint8_t b[NUMPIXELS];
uint8_t last_color = 0, new_color = 0;
#define COLS 7
#define WAVDIV 3
const uint8_t colors[COLS * 3] = {
0xFF, 0x00, 0x00, // red
0x00, 0xFF, 0x00, // green
0x00, 0x00, 0xFF, // blue
0x80, 0x80, 0x00, // yellow
0x00, 0x80, 0x80, // cyan
0x80, 0x00, 0x80, // magenta
0x56, 0x56, 0x56, // white
};
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
#ifdef DEBUG
Serial.begin(9600);
#endif
randomSeed(analogRead(0));
memset(r, 0x00, NUMPIXELS);
memset(g, 0x00, NUMPIXELS);
memset(b, 0x00, NUMPIXELS);
pixels.begin();
}
bool change(int n, int spd, int wav) {
static uint8_t o_r = 0, o_g = 0, o_b = 0, n_r = 0, n_b = 0, n_g = 0;
static int ln = 0;
static uint32_t cnt = 0;
if (ln != n) {
o_r = n_r;
o_g = n_g;
o_b = n_b;
int p = n*3;
n_r = colors[p++];
n_g = colors[p++];
n_b = colors[p];
ln = n;
cnt = 0;
if (wav > 0)
cnt = -wav * WAVDIV * NUMPIXELS;
}
static int d = 0;
if (d++ >= spd) {
uint8_t rr = 0;
uint8_t gg = 0;
uint8_t bb = 0;
for (int i=0; i<NUMPIXELS; i++) {
int c = cnt + (wav * WAVDIV * i);
if (c<0)
c = 0;
if (c>0xFF) {
r[i] = n_r;
g[i] = n_g;
b[i] = n_b;
}
else {
uint8_t cc = c;
r[i] = (uint16_t)(((n_r * cc) + (o_r * (0x100 - cc))) >> 8);
g[i] = (uint16_t)(((n_g * cc) + (o_g * (0x100 - cc))) >> 8);
b[i] = (uint16_t)(((n_b * cc) + (o_b * (0x100 - cc))) >> 8);
}
}
d = 0;
cnt ++;
}
return ((r[0] == n_r) && (g[0] == n_g) && (b[0] == n_b) && (r[NUMPIXELS-1] == n_r) && (g[NUMPIXELS-1] == n_g) && (b[NUMPIXELS-1] == n_b));
}
void loop() {
static uint32_t t = 0;
if ((millis() - t) >= PERIOD) {
static uint32_t cnt = 0, tim=0;
static int col = 0;
static int spd = 0;
static int wav = 0;
static bool done = true;
//if ((cnt >= tim) && done) {
if (done) {
int nc = col;
while (nc == col)
nc = random(COLS);
col = nc;
spd = random(3);
wav = random(-2,3);
tim = random(50 * 15);
cnt = 0;
#ifdef DEBUG
Serial.print(col);
Serial.print(" ");
Serial.print(spd);
Serial.print(" ");
Serial.print(wav);
Serial.print(" ");
Serial.print(tim);
Serial.print("\n");
#endif
}
done = change(col, spd, wav);
for (int i=0; i<NUMPIXELS; i++)
pixels.setPixelColor(i, pixels.Color(r[i],g[i],b[i]));
pixels.show();
t += PERIOD;
cnt ++;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment