colorful sparkling lights for your offspring

This project was made to enjoy my baby boy with random colorful sparkling lights. The result was pretty beautiful and the programming code can easily be changed to a more disco like appearence.

I recently entered the world of arduino and was estonished how fast you are making ideas come to life. One of my finished projects is to use a digispark with ATtiny85 micro controller and USB power supply to drive daisy chained WS2812 LEDs. Using Arduino or mini pro will also do the job done. One of the key problems you might run into is the current limitation of you power source. The presented project however uses little current because the source code will only switch on one light at a time. Maximum brightness can be defined and you will never have a pure white light.

You will need

  1. a PC Win/Linux/Mac with the arduino IDE 1.6.5 or higher for programming.
  2. Digispark, Digistump or Arduino Uno/mini/pro mini – I bought some cheap Shenzhen versions of digispark at aliexpress for less than 2,- Euros including shipping
  3. single WS2812B LEDs such as NeoPixel or single parts auf WS2811 strip
  4. some wires, e.g. flat ribbon cable you could salvage from your old computer’s parallel ATA hard drive
  5. diffusor, e.g. white table tennis balls; grumbled paper or origami figures, white plastic cups
  6. tools such as a soldering iron and lead; super glue/hot glue

To use the digispark with your arduino IDE you will probably need to install some USB drivers and include the digispark via IDE’s board manager, see instructions.

Before soldering everything you should start testing the micro controller and LEDs with a breadboard. Note: digispark will wait for 5 seconds to get programmed after powering up, then the (already) uploaded code will run. Therfore unplug before programming and connect to you computer when you are asked to.

Since I don’t want white or grey colors included, the approach is to utilize the HSV color modell, especially the so called hue. Hue is essentially a one-variable-value to specify a color wheel. To use hue for a RGB model, it need to be converted, see the wikipedia article for HSL/HSV.

The source  code uses random values to select color, blinking duration and pauses.


#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif

/* * *** Baby Light with DigiSpark and WS2812 NeoPixels *** */
// Which pin on the Arduino is connected to the NeoPixels?
// On a Trinket or Gemma we suggest changing this to 1
#define PIN 1
#define __AVR_ATtiny85__

// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS 5
#define MAX_BRIGHT 96

// When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
// Note that for older NeoPixel strips you might need to change the third parameter--see the strandtest
// example for more information on possible values.
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
 // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
#if defined (__AVR_ATtiny85__)
 if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
 // End of trinket special code
 randomSeed(analogRead(0));
 pixels.begin(); // This initializes the NeoPixel library.
}

bool between(int val, int min, int max) {
 if ((val > min) && (val <= max)) { return 1; }
 else { return 0; }
}

byte hue2red(int hue) {
 if (hue <= 43) { return 255; };
 if (between(hue, 43, 85)) { return map(hue, 43, 85, 255, 0); };
 if (between(hue, 85, 128)) { return 0; };
 if (between(hue, 128, 171)) { return 0; };
 if (between(hue, 171, 213)) { return map(hue, 171, 213, 0, 255); };
 if (hue > 213) { return 255; };
}
byte hue2green(int hue) {
 if (hue <= 43) { return map(hue, 0, 43, 0, 255); };
 if (between(hue, 43, 85)) {return 255; };
 if (between(hue, 85, 128)) { return 255; };
 if (between(hue, 128, 171)) { return map(hue, 128, 171, 255, 0); };
 if (between(hue, 171, 213)) { return 0; };
 if (hue > 213) { return 0; };
}
byte hue2blue(int hue) {
 if (hue <= 43) {return 0;};
 if (between(hue, 43, 85)) { return 0; };
 if (between(hue, 85, 128)) { return map(hue, 85, 138, 0, 255); };
 if (between(hue, 128, 171)) { return 255; };
 if (between(hue, 171, 213)) { return 255; };
 if (hue > 213) { return map(hue, 213, 255, 255, 0); };
}

void loop() {
 byte randNumber = random(NUMPIXELS);
 int randColor = random(256);
 int randDelay = random(1000);
 int starSpeed = random(15, 30);

 for (int b = 0; b < MAX_BRIGHT; b++) {
 pixels.setPixelColor(randNumber, pixels.Color(hue2red(randColor) / MAX_BRIGHT * b, hue2green(randColor) / MAX_BRIGHT * b, hue2blue(randColor) / MAX_BRIGHT * b));
 pixels.show(); // This sends the updated pixel color to the hardware.
 delay(starSpeed); // Delay for a period of time (in milliseconds).
 }
 for (int b = MAX_BRIGHT - b; b >= 0; b--) {
 pixels.setPixelColor(randNumber, pixels.Color(hue2red(randColor) / MAX_BRIGHT * b, hue2green(randColor) / MAX_BRIGHT * b, hue2blue(randColor) / MAX_BRIGHT * b));
 pixels.show(); // This sends the updated pixel color to the hardware.
 delay(starSpeed); // Delay for a period of time (in milliseconds).
 }
 delay(randDelay);
}

… This is an unfinished blog entry. Sorry, other projects are waiting to be published… 

Advertisements