Last night I did a trivial yet surprisingly satisfying hardware hack, of the kind that can only be accomplished when the brain is in holiday mode. Our son has that very simple airplane toy, which turned out to become one of his most loved ones, enough to have deserved wheel repairs before. He’s also reportedly a fan of all kinds of light-emitting or reflecting objects (including the sun, and specially the moon). So the idea sparkled: how easily can that airplane get a blinking led?
With an attiny85, a CR2032 battery, a LED, and half an hour of soldering work, this was the result:
The code loaded in the chip is small enough to be listed here, and it gets away with blinking without waking up the main CPU clock:
; Set inverse OC1B pin as output for the led. sbi _SFR_IO_ADDR(DDRB), 3 ; Enable timer TC1 with PCK/16k prescaling (attiny85 p.89) ldi r18, (1<<CS10)|(1<<CS11)|(1<<CS12)|(1<<CS13) out _SFR_IO_ADDR(TCCR1), r18 ; Set OC1B on compare match (250), clear on 0x00 (attiny85 p.86,90) ldi r18, (1<<PWM1B) | (1<<COM1B0) out _SFR_IO_ADDR(GTCCR), r18 ldi r18, 250 out _SFR_IO_ADDR(OCR1B), r18 ; Set the sleep mode to idle (attiny85 p.39). ldi r18, (1<<SE) out _SFR_IO_ADDR(MCUCR), r18 ; Shutdown unnecessary MCU modules (attiny85 p.38) ldi r18, (1<<PRTIM0)|(1<<PRUSI)|(1<<PRADC) out _SFR_IO_ADDR(PRR), r18 sleep rjmp .-4
The power consumption in the idle mode plus the blinks should keep the coin battery running for a couple of weeks, at least. A vibration sensor would improve that significantly, by enabling the MCU to go into powerdown mode and be awaken externally, but I don’t have a sensor at hand that is small enough.
This is the assembly, and the final result:
He’s enjoying it. :-)