NeoPixels + Blynk.io control program on Arduino to animate a piece of art called Self-Reflected.
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
#include <Adafruit_NeoPixel.h> | |
#include <BlynkSimpleEsp8266.h> | |
#define PIN 14 // Data pin of LED strip | |
#define NUMPIXELS 59 // Number of pixels in strip | |
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); | |
char ssid[] = "XXXX"; | |
char password[] = "XXXX"; | |
char token[] = "XXXX"; | |
int black[] = {0, 0, 0}; | |
int white[] = {255, 255, 255}; | |
int color[] = {255, 255, 255}; | |
float filter[NUMPIXELS]; | |
unsigned int chaseIndex1 = 0; | |
unsigned int chaseIndex2 = NUMPIXELS / 2; | |
float minDelay = 10; | |
float maxDelay = 50; | |
float loopDelay = maxDelay; // Speed of chase | |
float sigma = 1.0; // Width of chase kernel | |
bool isOn = true; // Lights/on off | |
bool isChasing = false; // Chase on/off | |
float brightness = 1; // Master brightness | |
WidgetTerminal terminal(V8); | |
void setup() | |
{ | |
Serial.begin(19200); | |
Blynk.begin(token, ssid, password); | |
strip.begin(); | |
} | |
BLYNK_CONNECTED() | |
{ | |
terminal.clear(); | |
Blynk.syncAll(); | |
} | |
// Main loop | |
void loop() | |
{ | |
Blynk.run(); | |
if(isOn && isChasing) | |
{ | |
chaseStep(); | |
} | |
} | |
// Master on/off switch | |
BLYNK_WRITE(V0) | |
{ | |
int buttonState = param.asInt(); | |
isOn = buttonState == 1; | |
if(isOn and !isChasing) | |
{ | |
setFixedColor(color); | |
} | |
if(!isOn) | |
{ | |
setFixedColor(black); | |
} | |
} | |
// Start/stop chase | |
BLYNK_WRITE(V1) | |
{ | |
int buttonState = param.asInt(); | |
isChasing = buttonState == 1; | |
} | |
// Set chase speed | |
BLYNK_WRITE(V2) | |
{ | |
loopDelay = minDelay + (maxDelay - minDelay) * (1 - param.asInt() / 100.0); | |
} | |
// Set chase kernel width | |
BLYNK_WRITE(V3) | |
{ | |
sigma = param.asInt() / 2.0; | |
setFilter(); | |
} | |
// Set brightness | |
BLYNK_WRITE(V4) | |
{ | |
brightness = param.asInt() / 255.0; | |
if(isOn && !isChasing) | |
{ | |
setFixedColor(color); | |
} | |
strip.show(); | |
} | |
// Set color | |
BLYNK_WRITE(V5) | |
{ | |
color[0] = param[0].asInt(); | |
color[1] = param[1].asInt(); | |
color[2] = param[2].asInt(); | |
if(isOn && !isChasing) | |
{ | |
setFixedColor(color); | |
} | |
} | |
// Set pixels for current step of chase animation | |
void chaseStep() | |
{ | |
for(uint16_t i=0; i<NUMPIXELS; i++) | |
{ | |
float activation1 = filter[(chaseIndex1 + i) % NUMPIXELS]; | |
float activation2 = filter[(chaseIndex2 + i) % NUMPIXELS]; | |
strip.setPixelColor(i, | |
color[0] * brightness * activation1 + color[0] * brightness * activation2, | |
color[1] * brightness * activation1 + color[1] * brightness * activation2, | |
color[2] * brightness * activation1 + color[2] * brightness * activation2); | |
} | |
chaseIndex1 = mod(chaseIndex1 - 1, NUMPIXELS); | |
chaseIndex2 = mod(chaseIndex2 - 1, NUMPIXELS); | |
strip.show(); | |
delay(loopDelay); | |
} | |
int mod(int x, int y) | |
{ | |
return x < 0 ? (x + y) % y : x % y; | |
} | |
void setFilter() | |
{ | |
for(uint16_t i=0; i<NUMPIXELS; i++) | |
{ | |
filter[i] = kernel(i, NUMPIXELS/2.0, sigma); | |
} | |
} | |
float kernel(float x, float mu, float sig) | |
{ | |
return exp(-pow(x - mu, 2.0) / (2 * pow(sig, 2.0))); | |
} | |
void setFixedColor(int color[]) | |
{ | |
int finalColor[] = {(int) (color[0] * brightness), (int)(color[1] * brightness), (int) (color[2] * brightness)}; | |
for(uint16_t i=0; i<strip.numPixels(); i++) | |
{ | |
strip.setPixelColor(i, strip.Color(finalColor[0], finalColor[1], finalColor[2])); | |
} | |
strip.show(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment