Week 2 Candle
Candle
After I lit up the Neopixel, I played with the RGB and HSI then I tried the example code from Tom’s GitHub. I add more random delay to create a blinking effect. Then I found the color turns out to be a bit too red when putting an actual candle side by side, so I extract the color code of a flame in Illustrator and play with it a little bit.
/* Candle example Runs only on SAMD boards (Nano 33 IoT, MKR series) uses Adafruit's NeoPixel library and the ColorHSV function therein Also uses Scheduler library, which runs only on SAMD boards. created 6 Jun 2020 modified 6 Feb 2023 by Tom Igoe */ #include <Adafruit_NeoPixel.h> #include <Scheduler.h> const int neoPixelPin = 5; // control pin const int pixelCount = 7; // number of pixels // set up strip: Adafruit_NeoPixel candle = Adafruit_NeoPixel(pixelCount, neoPixelPin, NEO_GRBW + NEO_KHZ800); int hues[pixelCount]; int saturations[pixelCount]; int intensities[pixelCount]; int changeValues[] = {1, 1, 1, 1, 1, 1, 1}; //change here does not make too much difference int highPixels[] = {6, 3}; //lighter towards yellow int lowPixels[] = {1, 4}; // darker towards red int bluePixel = 0; int lightPixels[] = {2, 5}; //in the middle -orange color void setup() { Serial.begin(9600); candle.begin(); // initialize pixel strip candle.clear(); // turn all LEDs off candle.show(); // update strip // set all initial hues, sats, intensities, and colorConverters for (int p = 0; p < 2; p++) { int thisPixel = highPixels[p]; hues[thisPixel] = random(1200) + 10000; //random(1200) + 1200; need to go future yellow (10012) saturations[thisPixel] = random(10) + 240; intensities[thisPixel] = random(20) + 200; } for (int p = 0; p < 2; p++) { int thisPixel = lowPixels[p]; hues[thisPixel] = random(800) + 9000; //random(800) + 300; red 1274 saturations[thisPixel] = 255; intensities[thisPixel] = random(120) + 100; } for (int p = 0; p < 2; p++) { int thisPixel = lightPixels[p]; hues[thisPixel] = random(2800) + 10000; // random(1500) + 800; orange 5825 saturations[thisPixel] = random(20) + 220; intensities[thisPixel] = random(140) + 110; } hues[bluePixel] = random(200) + 30000; // blue 39679 saturations[bluePixel] = random(10) + 230; intensities[bluePixel] = random(20) + 30; // set up some loops for timing: Scheduler.startLoop(fastLoop); Scheduler.startLoop(medLoop); Scheduler.startLoop(slowLoop); } void loop() { for (int p = 0; p < 2; p++) { int thisPixel = highPixels[p]; // change the hue: hues[thisPixel] = hues[thisPixel] + changeValues[thisPixel]; // keep the change within the min/max range, // but change directions at the extremes: if (hues[thisPixel] < 8 || hues[thisPixel] > 18) { changeValues[thisPixel] = -changeValues[thisPixel]; } long thisColor = candle.ColorHSV(hues[thisPixel], saturations[thisPixel], intensities[thisPixel]); candle.setPixelColor(thisPixel, thisColor); } candle.show(); delay(500); yield(); //candle.clear(); // turn all LEDs off } void fastLoop() { for (int p = 0; p < 2; p++) { int thisPixel = lowPixels[p]; // change the hue: hues[thisPixel] = hues[thisPixel] + changeValues[thisPixel]; // keep the change within the min/max range, // but add a random -1 to 2: hues[thisPixel] += (random(3) - 1); hues[thisPixel] = constrain(hues[thisPixel], 4, 16); long thisColor = candle.ColorHSV(hues[thisPixel], saturations[thisPixel], intensities[thisPixel]); candle.setPixelColor(thisPixel, thisColor); } candle.show(); delay(30); //candle.clear(); // turn all LEDs off } void medLoop() { for (int p = 0; p < 2; p++) { int thisPixel = lightPixels[p]; // change the hue: hues[thisPixel] = hues[thisPixel] + changeValues[thisPixel]; // keep the change within the min/max range, // but change directions at the extremes: if (hues[thisPixel] < 4 || hues[thisPixel] > 20) { changeValues[thisPixel] = -changeValues[thisPixel]; } long thisColor = candle.ColorHSV(hues[thisPixel], saturations[thisPixel], intensities[thisPixel]); candle.setPixelColor(thisPixel, thisColor); } candle.show(); delay(60); //candle.clear(); // turn all LEDs off } void slowLoop() { // change the hue: hues[bluePixel] = hues[bluePixel] + changeValues[bluePixel]; // change the intensity and constrain it: intensities[bluePixel] += (random(3) - 1); intensities[bluePixel] = constrain(intensities[bluePixel], 0, 20); // keep the change within the min/max range, // but change directions at the extremes: if (hues[bluePixel] < 200 || hues[bluePixel] > 280) { changeValues[bluePixel] = -changeValues[bluePixel]; } long thisColor = candle.ColorHSV(hues[bluePixel], saturations[bluePixel], intensities[bluePixel]); candle.setPixelColor(bluePixel, thisColor); candle.show(); delay(random(5000)+1000); //add random flikering yield(); candle.clear(); // turn all LEDs off, for flikering effect }
The second I am thinking is to use the same code to program an ATtiny 85 using the method from Homemade Hardware and use a coin cell battery to power it, so it can fit into a small case. I disassembled a LED candle and took out the battery case and switch. It took me a while to figure out the polarity of how the battery case work.
But when I program the ATtiny 85, I realized that the code I used above only works on Nano, so I changed the code and added a capacitive sensor. I want to create a lantern that flickers slowly but once you pick up the metal handle, the light will start shaking and flicker fast.
#include <Adafruit_NeoPixel.h> #include <CapacitiveSensor.h> const int neoPixelPin = 0; // control pin attiny85 //const int neoPixelPin = 5; // control pin Arduino const int pixelCount = 7; // number of pixels int change = 200; // increment to change hue by // CapacitiveSensor cs_4_2 = CapacitiveSensor(4, 2); // 10M resistor between pins 4 & 2, pin 2 is sensor pin, add a wire and or foil if desired CapacitiveSensor cs_4_2 = CapacitiveSensor(4, 1); // attiny-10M resistor between pins 4 & 2, pin 2 is sensor pin, add a wire and or foil if desired const int threshold = 1500; // set up strip: Adafruit_NeoPixel strip = Adafruit_NeoPixel(pixelCount, neoPixelPin, NEO_GRBW + NEO_KHZ800); //use this website to convert hsi //https://www.had2know.org/technology/hsi-rgb-color-converter-equations.html int h = 1000; // hue, 0-65535 int s = 255; // saturation 0-255 int i = 255; // intensity 0-255 // int highPixels[] = {6, 3}; //lighter towards yellow // int lowPixels[] = {1, 4}; // darker towards red // int bluePixel = 0; // int lightPixels[] = {2, 5}; //in the middle -orange color void setup() { cs_4_2.set_CS_AutocaL_Millis(0xFFFFFFFF); // turn off autocalibrate on channel 1 - just as an example strip.begin(); // initialize pixel strip strip.clear(); // turn all LEDs off strip.show(); // update strip Serial.begin(9600); } void loop() { // create a single color from hue, sat, intensity: long color = strip.ColorHSV(h, s, i); long start = millis(); long total1 = cs_4_2.capacitiveSensor(30); Serial.print(millis() - start); // check on performance in milliseconds Serial.print("\t"); // tab character for debug windown spacing Serial.println(total1); // print sensor output 1 if (total1 > threshold) { Serial.println("yes"); for (int pixel = 0; pixel < 8; pixel += 1) { strip.setPixelColor(pixel, strip.ColorHSV(h, s, i)); strip.setPixelColor(pixel + 1, strip.ColorHSV(0, 0, 0)); strip.show(); // update the strip delay(10); if (pixel > 0) { strip.setPixelColor(pixel, strip.ColorHSV(0, 0, 0)); strip.show(); delay(random(300)); } } } else { // loop over all the pixels: for (int pixel = 0; pixel < 8; pixel++) { strip.setPixelColor(pixel, color); strip.show(); // update the strip delay(random(100)+30); //strip.clear(); // turn all LEDs off } } h = h + change; if (h <= 1000 || h >= 3500) { change = -change; } h = constrain(h, 1000, 3500); }
For the light diffusers, below are some tests I did, using diffent color acrylic, paper at diffent thickness and combined.
Observation Assignment: Early morning, Exterior
The time is around 7 am, and my apartment is toward the north side so I cannot see the direct sunrise. But I can always see the rays of sunrise cast toward the northern sky.
The sky was originally a gradient from blue to orange and pink, and as time goes on, the orange gradually fades out into the horizon and the sky turns back to blue.