Thursday, December 23, 2010

The Emerald Isle with a frosting of snow

This is a beautiful image of Ireland taken at about 11am this morning (23 December 2010) which I grabed from the ESA's Miravi service. This image is cropped to show just the island of Ireland and is contrast enhanced. The last week or so has been a particularly severe cold snap with record low temperatures for December. The Corrib lake is seen to be partially covered by ice.

The original image is here, (12MB).

There is a similar image available from the Irish Met Office here.

Tuesday, December 14, 2010

Arduino powered Christmas tree star

This is a quick little hack to put a little sparkle on the top of your Christmas tree. You'll need the following:
  • an Arduino (and suitable power supply eg USB connection to a laptop)
  • a nice powerful red-green-blue LED such as this one from Seeed Studio
  • a power supply for the LED (the Arduino cannot provide the required current). I used 4 x NiMH AA cells.
  • 3 x  NPN transistors that saturate with Ic as close as possible to the maximum allowed current for the LED. I used 3 x BC547 as it was the only ones I had handy. Unfortunately that saturates at only 100mA (I'm allowed up to 350mA per channel for this LED), but it was sufficient for the effect to be successful.
  • 3 x resistors (150 ohms or so) to limit the transistor base current which will be sourced from the Arduino PWM IO pins
  • a length of 4 core cable that will run the length of your tree down to your bread board
  • a breadboard (this is a very temporary hack)
A word of caution: while the voltage is low, the currents running up to the RBG LED are sufficient to pose a small (but non negligible) fire hazard should something go wrong (eg LED failure or a short circuit).  Only operate this while in the room and power off while not attended.

I soldered the LED onto a square of strip board and attached it to my star Christmas tree ornament.

This particular RGB LED can sink up to 350mA per channel (1A in total). There is no way you can source this much current directly from the Arduino IO pins.  Instead the Arduino switches transistors which in turn drive the LED current. The BC547 transistors I had on hand saturate at only 100mA but I found this sufficient for a reasonably good effect.

The transistor base current is provided by pins 9, 10 and 11 of the Arduino. These pins are capable of a simulated digital-to-analog conversion using pulse width modulation (PWM). A 150 ohm resistor limits the base current to about 33mA (the Arduino's limit is 40mA per pin). This is sufficient to ensure the transistor is fully on (saturated).  Failure to fully saturate the transistor can lead to excessive heat dissipation in the transistor. There is no need for a LED current limiting resistor – the transistor performs that function.

The following sketch is my "supernova" program. The idea is to use this as a lighting the tree ceremony. First the star slowly comes to life in a supernova effect (with buckets of artistic licence) and when it reaches full brightness you then power up all the other traditional lighting.

Here is a video of the effect:


You can easily adapt the sketch for other effects.

/*
 * Christmas tree star LED driver. Simulate "supernova" effect
 * with lots of artistic licence. You need 3 x transistors 
 * to power LEDs.
 *
 *
 * See blog post:
 * http://jdesbonnet.blogspot.com/2010/12/arduino-powered-christmas-tree-star.html
 *
 * Joe Desbonnet
 * jdesbonnet@gmail.com
 * This is public domain code. No copyright is asserted.
 */

// Define pins for Red, Green and Blue LEDs.
int LEDR = 9; 
int LEDG = 10;
int LEDB = 11;

void setup()  { 
  // nothing to setup
} 

void loop()  { 
    int i;
    
    setRGB(0,0,0);
    
    // Fist a red faint red glow... growing slowly
    for (i = 0; i < 16; i++) {
        setRGB(i,0,0);
        delay(500);
    }
    
    // Getting brighter faster now
    for (i = 16; i < 64; i++) {
        setRGB(i,0,0);
        delay(100);
    }
    
    // Add some gree to make the light yellow (like dawn)
    for (i = 64; i < 200; i++) {
        setRGB(i,i-64,0);
        delay(100);
    }
    
    // Now a bit of blue
    for (i = 200; i < 255; i++) {
        setRGB(i,i-64,i-200);
        delay(100);
    }
    
    // Flash
    setRGB(255,220,128);
    delay(10);
    setRGB(0,0,0);
        
    delay (100);
    
    // Another flash    
    setRGB(255,255,200);
    delay(10);
    setRGB(0,0,0);
    
    delay (100);
        
      
    // More flashes, with random color variations and intervals
    for (i = 0; i < 32; i++) {
      setRGB (random(192,255),
            random(192,255),
            random(192,255) );
      delay(20);
      setRGB(0,0,0);
       
      delay (random(50,200));
    }
 
   // End of program... switch LED on full all channels (~ white)
   setRGB(255,255,255);
   
   // Loop forever
   while (1);

}

void setRGB (int r, int g, int b) {
  analogWrite(LEDR,r);
  analogWrite(LEDG,g);
  analogWrite(LEDB,b);
}