Digital candle — Version 2
Date: May 7, 2009 | CommentAs can be seen from the dates between postings, I took an awful lot of time with this project – and yet, I never really accomplished my goal, which was to have five LEDs independently fading in and out like a candle, driven by an Atmel ATTiny13.
I spent a lot of time with some code that had been created for a Microchip PIC12F675 but it turned out that it was merely random on-off, not fading the way a flickering candle operates. I then spent some time with a second code set, also for a PIC12F675, that did fade nicely, but which had a problem with brightness that I was never able to rectify (it is a duty-cycle issue, I know; I just don’t know how to fix it).
But that second code set did point me in the direction of how to control individual LEDs while within a loop, using bitwise manipulation.
I decided on Sunday that I had a few hours to work on this project and I wanted it finally finished. While the result is not exactly what I wanted, it will suffice.
What I’ve built is a group of four LEDs that fade in and out in an inverse manner. While LED1 fades in, LED2 fades out and LED1 and LED3 work in synch, as do LED2 and LED4. So, when LED1 and LED3 fade out, LED2 and LED4 fade in and when LED2 and LED4 fade out, LED1 and LED3 fade in. It is random enough – and fast enough – that you can’t really tell they’re working inversely.
The fifth LED staying on all the time helps by keeping the candle from ever going completely dark. This effect would work just as well with only three LEDs, but the two extras throw off more light.
The finished code is at the end of this article.
In the prototype I’m using 10mm warm white LEDs that are rated at 85,000 millicandles; they have a 3.3-volt forward voltage, so I’m using 100-ohm, one-eighth watt resisters between the five pins of the microcontroller and the positive leg of the LED.
I have provided two circuit schematics; one is for a circuit to program and test the ATTiny13; the other is an operational circuit. I will be using this candle on my backyard railroad; you can see how I built the other flickering lights on the railroad here and you can assume I’ll use a similar plastic-canistter/wood/glue/screws building technique for this.
These schematics don’t detail the circuit that takes the raw Malibu 12-volt AC of my layout and turns it into filtered, five-volt DC for the microprocessor and LEDS; you can rest assured I built something eerily similar to this circuit.
I will build both circuits on a piece of RS project board, though I plan to attach the LEDs with one-inch long wire in order to be able to point them in various directions.
I’ve provided a video of the LEDs, one scene where they’re running on the breadboard bare and a second with a plastic canister, to give you an idea of how they will look on the layout.
/* * Digital candle V2 * ----------- * Use random numbers to emulate a flickering candle on five LEDs without hardware PWM * * David M. Cole <dmcole at dmcole dot net> * License: 2009 Creative Commons Attribution-Noncommercial-Share Alike 3.0 U.S. * Target: ATTiny13 * Compiler: AVR-GCC */ #include <avr/io.h> // Defines pins, po #define led1_on PORTB |= 1 << 0 // PortB0 = on #define led1_off PORTB &= ~(1 << 0) // PortB0 = off #define led2_on PORTB |= 1 << 1 // PortB1 = on #define led2_off PORTB &= ~(1 << 1) // PortB1 = off #define led3_on PORTB |= 1 << 2 // PortB2 = on #define led3_off PORTB &= ~(1 << 2) // PortB2 = off #define led4_on PORTB |= 1 << 3 // PortB3 = on #define led4_off PORTB &= ~(1 << 3) // PortB3 = off #define led5_on PORTB |= 1 << 4 // PortB4 = on #define led5_off PORTB &= ~(1 << 4) // PortB4 = off // Declare variables // ============================================== uint8_t y, z, i, j; // ============================================== int main(void) { DDRB = 0b11111111; // PortB all outputs for(;;) // loop forever { y = rand(1,255); // bottom of first loop z = rand(63,255); // top of first loop for (i = z; i < y; i++) // first fade loop { led1_off; led2_on; led3_off; // set up for first fade led4_on; led5_on; // led5 is always on for (j=0; j < y; j++) { if (j > i) { led1_on; led2_off; // turn off lamps that were on led3_on; // turn on lamps that were off led4_off; led5_on; // led5 is always on } } } // end first fade loop y = rand(1,255); // bottom of second looop z = rand(63,255); // top of second looop for (i = y; i > z; i--) // second fade loop { led1_on; led2_off; led3_on; // note lamps swap state led4_off; // from first loop led5_on; // led5 is always on for (j=0; j < y; j++) { if (j > i) { led1_off; led2_on; led3_off; // and again, change state led4_on; led5_on; // led5 is always on } } } // end second fade loop } } |


Leave a reply