No-solder Holiday Firefly Lights
This is a holiday extension of the firefly / lightning bug project. It's a no-solder, Arduino controlled strand of LEDs that are programmed to twinkle like red and green fireflies. You could program any kind of lighting, though. This project is very quick to assemble - by using an Arduino Nano and screw terminal shield, you only need to connect three wires with a screwdriver.
Rather than repeat the build instructions, you can see them at the other Instructable.
One note on power: Since this project is only twinkling a few LEDs at a time, it is being powered through the Arduino Nano regulator for battery operation from a USB cell phone backup battery. If you change the code or add a lot more LEDs, you should power them separately from the Arduino. Since these are 5V LEDs, you can use a 5V power supply to power the Arduino and the LEDs.
One difference from the firefly project is that the frequency for these lights is a bit higher.
The strand in the pictures has 150 LEDs - three 50 LED strands connected together. The code is configured for 200, but providing you have enough power, you could easily add more. See the other Instructable for power injection etc. info.
The Code
Below is the code used for this project. As before, it also shows how to do an animation without using delays for each light - allows for parallel actions.
There seems to be some spurious formatting in the code below, so I attached two newer versions of the code. Note the number of LEDs in each code sample - set to the number you are using. I had a larger number for my ESP8266 D1 Mini controllers on house lights.
<p>// Two Color Twinkle<br>// 9/3/18 - 12/13/19 Carl F Sutter</p><p>#include
#ifdef __AVR__
#include
#endif</p><p>// Neopixel constants
#define PIN 6
#define NUMLEDS 200</p><p>// App constants
// The RGB values for the first color 0-255
#define COLOR1_R 255
#define COLOR1_G 0
#define COLOR1_B 0</p><p>// The RGB values for the second color 0-255
#define COLOR2_R 0
#define COLOR2_G 255
#define COLOR2_B 0</p><p>// loop control - these are the main constants to control the animation
// note that the math is in integers right now, so if the step size is greater than the color values, it wil not work well
#define NUM_STEPS_UP 5 // the number of steps to fade the color up
#define NUM_STEPS_DOWN 30 // the number of stesp to fade the color down
#define LOOP_DELAY 10 // the ms delay for each loop
#define BLINK_ODDS 5 // the odds in 1000 that the loop will start each black pixel</p><p>// internal constants and vars - no need to change
#define STATE_BLACK 0
#define STATE_MOVING_UP_1 1
#define STATE_MOVING_DOWN_1 2
#define STATE_MOVING_UP_2 3
#define STATE_MOVING_DOWN_2 4</p><p>uint8_t state[NUMLEDS];
uint8_t color_r[NUMLEDS];
uint8_t color_g[NUMLEDS];
uint8_t color_b[NUMLEDS]; </p><p>// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino 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)
// NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMLEDS, PIN, NEO_GRB + NEO_KHZ800);</p><p>// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel. Avoid connecting
// on a live circuit...if you must, connect GND first.</p><p>void setup() {
// set all the LEDS to the no blink (black) state
for(int i=0; i</p><p> randomSeed(analogRead(0));</p><p> strip.begin();
strip.show(); // Initialize all pixels to 'off'
} // setup</p><p>void loop() {
for (int i=0; i</p><p> case STATE_MOVING_UP_1:
color_r[i] = min(COLOR1_R, color_r[i] + (COLOR1_R / NUM_STEPS_UP));
color_g[i] = min(COLOR1_G, color_g[i] + (COLOR1_G / NUM_STEPS_UP));
color_b[i] = min(COLOR1_B, color_b[i] + (COLOR1_B / NUM_STEPS_UP));
strip.setPixelColor(i, color_r[i], color_g[i], color_b[i]);
if ((color_r[i] == COLOR1_R) && (color_g[i] == COLOR1_G) && (color_b[i] == COLOR1_B)) {
state[i] = STATE_MOVING_DOWN_1;
}
// maybe someday make the code cleaner and use less memory - OK for now
//uint32_t ColorOfThePixel = MyPixels.getPixelColor(12);
//uint8_t r = ColorOfThePixel >> 16;
//uint8_t g = ColorOfThePixel >> 8;
//uint8_t b = ColorOfThePixel;
break;</p><p> case STATE_MOVING_UP_2:
color_r[i] = min(COLOR2_R, color_r[i] + (COLOR2_R / NUM_STEPS_UP));
color_g[i] = min(COLOR2_G, color_g[i] + (COLOR2_G / NUM_STEPS_UP));
color_b[i] = min(COLOR2_B, color_b[i] + (COLOR2_B / NUM_STEPS_UP));
strip.setPixelColor(i, color_r[i], color_g[i], color_b[i]);
if ((color_r[i] == COLOR2_R) && (color_g[i] == COLOR2_G) && (color_b[i] == COLOR2_B)) {
state[i] = STATE_MOVING_DOWN_2;
}
break;
case STATE_MOVING_DOWN_1:
color_r[i] = max(0, color_r[i] - max(1, (COLOR1_R / NUM_STEPS_DOWN)));
color_g[i] = max(0, color_g[i] - max(1, (COLOR1_G / NUM_STEPS_DOWN)));
color_b[i] = max(0, color_b[i] - max(1, (COLOR1_B / NUM_STEPS_DOWN)));
strip.setPixelColor(i, color_r[i], color_g[i], color_b[i]);
if ((color_r[i] == 0) && (color_g[i] == 0) && (color_b[i] == 0)) {
state[i] = STATE_BLACK;
}
break;
case STATE_MOVING_DOWN_2:
color_r[i] = max(0, color_r[i] - max(1, (COLOR2_R / NUM_STEPS_DOWN)));
color_g[i] = max(0, color_g[i] - max(1, (COLOR2_G / NUM_STEPS_DOWN)));
color_b[i] = max(0, color_b[i] - max(1, (COLOR2_B / NUM_STEPS_DOWN)));
strip.setPixelColor(i, color_r[i], color_g[i], color_b[i]);
if ((color_r[i] == 0) && (color_g[i] == 0) && (color_b[i] == 0)) {
state[i] = STATE_BLACK;
}
break;
} // switch
} // led loop
strip.show();
delay(LOOP_DELAY);
} // loop</p>