Christmas supercomputer
Note: it is the summer holidays DownUnder, so this blog (and YT channel) will be taking a little break for a month - see you in 2021!
Who doesn't love red and green flashing LEDs at Christmas? For the last couple of years we have had these little CR2032 driven ATTiny13 chips flashing a couple of 5mm LEDs strewn throughout the house (and outside).
The microcontrollers are running at 1MHz and they are mostly sleep, just pumping out alternate 1/8th second blips to the LEDs followed by a 4 second gap. In this guise the coin cells last around 6-9 months (!!), although they do get a bit dim towards the end of that run.
This year I decided to update the project, again using ATTiny13a chips, but this time ambling along at 128kHz (less power) which switch 1206 SMD LEDs (less power at 1/4W), but flashing more frequently (1/8th second on, 1/2 second off). So it will be very interesting to see how they last through the festive season and beyond. I can't remember if the original was coded in assembly or not, but this one sure is:
; ; Device: ATtiny13A, Package: 8-pin-PDIP_SOIC ; ; ______ ; 1 / |8 ; RESET o--| |--o VCC ; 2| |7 ; PB3 o--| |--o PB2 ; 3| |6 ; PB4 o--| |--o PB1 ; 4| |5 ; GND o--| |--o PB0 ; |_______| ; .nolist .include "tn13adef.inc" ; Define device ATtiny13A .list ; ********************************** ; R E G I S T E R S ; ********************************** .def rSreg = R15 ; Save/Restore status port .def rmp = R16 ; Define multipurpose register .def colour = R1 ; ********************************** ; S R A M ; ********************************** .dseg .org SRAM_START ; ********************************** ; C O D E ; ********************************** .cseg .org 000000 ; ********************************** ; R E S E T & I N T - V E C T O R S ; ********************************** rjmp Main ; Reset vector reti ; INT0 reti ; PCI0 reti ; OVF0 reti ; ERDY reti ; ACI reti ; OC0A reti ; OC0B rjmp mytimer_ISR ; watchdog timer interrupt reti ; ADCC ; ********************************** ; I N T - S E R V I C E R O U T . ; ********************************** ; Add all interrupt service routines mytimer_ISR: ; as I understand it, cli and sei are automatic on ; entry and exit respectively of ISR in r16, SREG ; save SREG push r16 ; do this if you want to use finishisr: pop r16 ; do this if you pushed SREG above out SREG, r16 ; restore SREG reti ; ********************************** ; M A I N P R O G R A M I N I T ; ********************************** Main: ldi rmp,Low(RAMEND) out SPL,rmp ; Init LSB stack pointer ldi r16, 0b00011000 ; output mode for PB3/4 out DDRB, r16 ldi r16, 0b00010000 mov colour, r16 ; red is on ; turn on PB4, enable internal pullups ; on the rest of the pins except PB3 ldi r16, 0b11110111 out PORTB, r16 ; ********************************** ; P R O G R A M L O O P ; ********************************** Loop: rcall waitabit ; 1/16 second subroutine rcall waitalot ; 1/2 second subroutine rjmp Loop waitabit: wdr ; reset watchdog timer ldi r16, 0b01000010 ; 1/8 second timer out WDTCR, r16 rcall sleepnow ; sleep subroutine rcall flipbit ; flip the led, if off then on, etc. ret waitalot: wdr ; reset watchdog timer ldi r16, 0b01000101 ; 1/2 second timer out WDTCR, r16 rcall sleepnow ; sleep subroutine rcall flipbit ; flip the leds ret sleepnow: ; sleep enable, power down mode ldi r16, 0b00110000 out MCUCR, r16 ; disable ADC ldi r16, 0b00010000 out ADCSRA, r16 ; disable interrupts to make sure the following ; timed sequence is not interrupted cli ; disable BOD - must be done in a timed sequence ; as follows, write 1 to BODS and BODSE then within ; four clock cycles write 1 to BODS and 0 to BODSE ; then within three clock cycles enable sleep ; page 33 on the datasheet ldi r16, 0b00000011 ldi r17, 0b00000010 out BODCR, r16 out BODCR, r17 sei sleep ; sleep disable ldi r16, 0b00000000 out MCUCR, r16 ret flipbit: in r16, pinb ; what is the state of the pins? andi r16, 0b00011000 ; load red or green on brbc 1, turnoff testred: mov r16, colour ldi r17, 0b00001000 cp r16, r17 brbs 1, greenon redon: ldi r16, 0b00001000 ; set colour red mov colour, r16 ; and make it so ldi r16, 0b00001000 out portb, r16 rjmp finishflip greenon: ldi r16, 0b00010000 ; set colour green mov colour, r16 ; and make it so ldi r16, 0b00010000 out portb, r16 rjmp finishflip turnoff: ldi r16, 0b00000000 out portb, r16 finishflip: ret ; End of source code
The only downside is that with the frantic flashing the place looks like an alien landing site or a Christmas super computer - good one!
In line with some other current projects, it is my solemn promise to make next year's batch from Pesky Padauk microcontrollers, probably the PMS150C.
No comments:
Post a Comment