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();    

  }

}