While waiting for my bread to rise the other day, I moved my breadboard ATtiny13 circuit that blinked two leds to a small Radio Shack perfboard, added a couple of switching transistors (2N3904s) to power the LEDs, and built a small 7805 regulator (which doesn’t yet have any filter caps, I’ll get to that). But, I couldn’t resist powering it on. And after finding a small solder bridge (a hairlike strand that spattered and connected two of the microcontroller pins), it worked!
Hopefully this stuff will get mounted in a hat this weekend. Stay tuned for the final video.
Addendum: I received one request for the source code. It’s trivial. Here you go.
[sourcecode lang=”cpp”]
#define F_CPU 1200000UL
#include <avr/io.h>
#include <util/delay.h>
/*
* xmas.c
*
* A small program for the ATtiny13 that can control two strands of
* Christmas lights. I found a set of batter powered LED Christmas
* lights at CVS on sale for $.99 each. I took the lights out, and
* found that they consisted of two strands: one of 4 red and 4 yellow
* LEDs, and the other of 4 blue and 3 green LEDS. Each strand is
* wired in parallel and draws about 20ma at 3 volts. I have a few
* ATtiny13’s lying around, which can use between 2.7 and 5.5 volts supply.
* I think for this test, I’ll wire up a little 7805 regulator to provide
* 5V, and then control each strand with one of the two PWM outputs.
* If I want to drive the strings directly from the microcontroller,
* I’ll have to insert another 50 ohms of resistance to limit the current
* to around 20ma per pin. I could also add a 1K resistor and a small
* NPN transistor to drive each pin at the higher voltage. At 5V, the
* strand will draw about 120ma.
*/
#define LED0 PB0 /* pin 5 on the ATtiny13 */
#define LED1 PB1 /* pin 6 on the ATtiny13 */
#define SWITCH PB4 /* pin 3 on the ATtiny13 */
int brite, dir ;
int swd = 0 ;
int swu = 0 ;
int
main(void)
{
DDRB |= (1 << LED0) ; /* set both LEDs as outputs */
DDRB |= (1 << LED1) ;
DDRB &= ~(1 << SWITCH) ; /* and the switch as an input */
PORTB |= (1 << SWITCH) ; /* and activate the internal pull up */
/* This configures the PWM outputs to be in "Fast PWM" mode. */
TCCR0A |= (1 << WGM01) | (1 << WGM00) ;
/* Timer is clocked at F_CPU/8 */
TCCR0B |= (1 << CS01) ;
/* COM01 COM00
* 0 0 | normal port operation, output compare disconnected
* 0 1 | toggle output on compare match
* 1 0 | clear output on compare match
* 1 1 | set output on compare match
*/
TCCR0A |= ((1 << COM0A1)) ;
TCCR0A |= ((1 << COM0B1)) ;
OCR0A = 0;
OCR0B = 0;
for (;;) {
/* SOLID ON */
for (;;) {
OCR0A = 0xff ;
OCR0B = 0xff ;
_delay_ms(1) ;
if ((PINB & (1<<SWITCH)) == 0)
break ;
}
while ((PINB & (1<<SWITCH)) == 0) ;
/* CROSS FADE */
brite = 0 ;
dir = 1 ;
for (;;) {
OCR0A = brite ;
OCR0B = brite ^ 0xFF ;
brite += dir ;
if (brite == 0 || brite == 255)
dir = -dir ;
_delay_ms(2) ;
if ((PINB & (1<<SWITCH)) == 0)
break ;
}
while ((PINB & (1<<SWITCH)) == 0) ;
/* BLINK */
brite = 0xff ;
for (;;) {
OCR0A = brite ;
OCR0B = brite ;
_delay_ms(500) ;
brite ^= 0xff ;
if ((PINB & (1<<SWITCH)) == 0)
break ;
}
while ((PINB & (1<<SWITCH)) == 0) ;
/* CROSS BLINK */
for (;;) {
OCR0A = 0xff ;
OCR0B = 0 ;
_delay_ms(500) ;
if ((PINB & (1<<SWITCH)) == 0)
break ;
OCR0A = 0 ;
OCR0B = 0xff ;
_delay_ms(500) ;
if ((PINB & (1<<SWITCH)) == 0)
break ;
}
while ((PINB & (1<<SWITCH)) == 0) ;
}
}
[/sourcecode]
I know you like to wear your Santa Hat this time of year. Are you trading up for an electric Santa hat?