ATtiny10 Christmas Star
On the left is watching full tree, on the right is when it sleeps for about 2 seconds each cycle to save battery.
ATtiny10 how I programmed Attiny10
/*
* ATtiny10-PWM-Christmas_Star-WDT.c
*
* UPDated: 6/2/2022 17:41:01
* Cleaned up code.
*
* PWM Star v1.1
*
* Sherman Stebbins
* Created: 2021-10-23
* Need to clean up more and retest.. (fix lock up)
* Update 4/27/23: Lockup fixed :)
* Moved loopCount to different location fixed the issue.
*
* Need to fix sleep function and test with correct code (see notes)
*
* Attiny10
+====+
SCK -> PB0 |* | PB3 (RESET)
GND | | Vcc
LEDs MOSI -> PB1 | | PB2
+====+
*/
#ifndef F_CPU
#define F_CPU 1000000UL
#endif
#include <avr/interrupt.h>
#include <util/delay.h>
volatile unsigned char loopCount __attribute__((section(".noinit"))); // Not cleared on RESET
static volatile uint16_t pwmCount=0;
static volatile uint8_t upDown=1;
static volatile uint8_t hbDir=1;
static volatile uint16_t heartBeatCount=0;
const volatile uint8_t up=1;
const volatile uint8_t down=0;
void hearBeat(void);
void my_delay_ms(uint16_t n);
void goToSleep(void);
int main(void){
//This restores the PWM properly!!!!
RSTFLR &= ~(1<<WDRF);
CCP=0xD8;
WDTCSR &= ~(1<<WDE); //must have or won't sleep
WDTCSR &= ~(1<<WDIE);
DDRB = 0b00000010;
TCCR0A = (1<<WGM01)|(1<<WGM00); //15 1111 Fast PWM OCR0A TOP TOP //worked
OCR0A = 1;//set timer counter A
TIMSK0 = (1<<OCIE0A);//time mask when OCR0A is matched, interrupt //worked
sei();
TCCR0B |= (1<<CS01); //set prescaler to /8 and start
while(1){
}
}
ISR(TIM0_COMPA_vect){
hearBeat();
}
void my_delay_ms(uint16_t n){
while(n--) {
_delay_ms(1);
}
}
void goToSleep(void)
{
SMCR |= (1<<2); //SMCR.SM bit 2 (010) Power-down
SMCR |= (1<<0); //SMCR.SE =1; SET JUST before Sleep starts
sei() ; //set Global Interrupt Enable - if you don't add this, it will not restart.
//CCP = 0xd8; Unknown if needed 20230630
//below line is wrong. should be 0b01100000 because its a reserved number not a valid time hence sleeping 4 seconds.
WDTCSR = 0b01100110; //1000 4 sec 0111 2 sec -- sherm recheck this line!! why 16ms?
__asm__ __volatile__ ( "sleep" "\n\t" :: ); //Sleep instruction to put controller to sleep (found this syntax)
}
void hearBeat(void){
//long beat getting brighter
if(upDown==1){
pwmCount++;
OCR0A=pwmCount;
if(pwmCount>80+(heartBeatCount*2)){
//count loops for beats to sleep
loopCount++; //(fixed, had to move to this location cleared lock up problem)
upDown=0;
if(hbDir==down){
heartBeatCount--;
}else{
heartBeatCount++;
}
if (heartBeatCount>40){ //faster
hbDir=down;
}
if (heartBeatCount<1){ //slower
hbDir=up;
}
}
//long beat getting dimmer
}else if(upDown==0){
pwmCount--;
OCR0A=pwmCount;
if(pwmCount<=1){
upDown=2;
if(hbDir==down){
heartBeatCount--;
}else{
heartBeatCount++;
}
if (heartBeatCount>40){
hbDir=down;
}
if (heartBeatCount<1){
hbDir=up;
}
}
//short beat getting brighter
}else if(upDown==2){
pwmCount=pwmCount+4;
OCR0A=pwmCount;
if(pwmCount>80+(heartBeatCount*2)){
upDown=3;
if(hbDir==down){
heartBeatCount-=4;
}else{
heartBeatCount+=4;
}
if (heartBeatCount>40){
hbDir=down;
}
if (heartBeatCount<1){
hbDir=up;
}
}
//short beat getting dimmer
}else if(upDown==3){
pwmCount=pwmCount-3;
OCR0A=pwmCount;
if(pwmCount<=3){
upDown=1;
if(hbDir==down){
heartBeatCount-=4;
}else{
heartBeatCount+=4;
}
if (heartBeatCount>40){
hbDir=down;
}
if (heartBeatCount<1){
hbDir=up;
}
// loopCount++; //count loops for beats to sleep
}
}
PORTB ^= (1<<PB1);
if(loopCount >= 200){ // was 6 but lock up issue is fixed.
loopCount=0;
DDRB = 0;
goToSleep();
}
}