Attiny10 Heart Beat

Attiny10 Heartbeat I made for the wife.. with two modes. Sleeps at .1ua after displaying for about 2 minutes in mode one (were it beats like a heartbeat with PWM at low current) then in mode 2 its about 1 minute of Morse code. Its a total mistreatment of interrupt and reset.. but it works..

Attiny10 main page

/*

* PWM Heartbeat

* Sherman Stebbins

* 2021-10-23

*

* Attiny10

; +====+

; SCK -> PB0 |* | PB3 (RESET)

; GND | | Vcc

; MOSI -> PB1 | | PB2

; +====+


convert to binary sort of:

..-. ..- -.-. -.- / -- .



*/

#ifndef F_CPU

#define F_CPU 1000000UL

#endif

#include <avr/interrupt.h>

#include <util/delay.h>

#define EXT_RESET (1 << EXTRF)

#define dashT 32000

#define dotT 15000

volatile unsigned char count __attribute__((section(".noinit"))); // Not cleared on RESET



volatile uint16_t loopCount=0;

volatile uint16_t pwmCount=0;

volatile uint8_t upDown=1;

volatile bool hbDir=1;

volatile uint16_t heartBeatCount=0;

const volatile bool up=1;

const volatile bool down=0;


//volatile long dtyCycl = 0;

int main(void){

if ((RSTFLR & EXT_RESET) != 0) {

//if ((RSTFLR & 1) != EXT_RESET) {

// If External RESET then increment count and output to pins

RSTFLR = RSTFLR & ~EXT_RESET;

//MCUSR = MCUSR & ~EXT_RESET;

//PORTB = ++count;

count++;

} else {

// Else, set count to zero and output to pins

count = 0;

}

if (count>1){

count=0;

}

//DDRB = 0x01; //set pb0 output

DDRB |= (1<<0) | (1<<1);

//TCCR0A = (1<<WGM02)|(1<<WGM01); //14 1110 Fast PWM ICR0 TOP TOP

TCCR0A = (1<<WGM02)|(1<<WGM01)|(1<<WGM00); //15 1111 Fast PWM OCR0A TOP TOP //worked


OCR0A = 1;//976; //7812; //worked

TIMSK0 = (1<<OCIE0A);//time mask when OCR0A is matched, intrerupt //worked

sei();

TCCR0B |= (1<<CS01); //set prescaler to /8 and start

//TCCR0B |= (1<<CS02); //set prescaler to /256 and start

//TCCR0B |= (1<<CS01)|(1<<CS00); //set prescaler to /64 and start

//TCCR0B |= (1<<CS00); //set prescaler to /1 and start



while(1){

}

}



ISR(TIM0_COMPA_vect){

switch(count){

case 0:

hearBeat();

break;


case 1:

morseCode();

break;


default:

hearBeat();

break;

}

}


void morseCode(void){

// ..-. ..- -.-. -.- / -- .

dot();

dot();

dash();

dot();

my_delay_ms(600);

dot();

dot();

dash();

my_delay_ms(600);

dash();

dot();

dash();

dot();

my_delay_ms(600);

dash();

dot();

dash();



my_delay_ms(1000);

dash();

dash();

my_delay_ms(600);

dot();

my_delay_ms(3000);

loopCount++;

if(loopCount>3){

loopCount=0;

DDRB = 0;

PORTB = 0;

goToSleep();


}


}


void dot(void){

PORTB |= (1<<PB1);

my_delay_ms(150);

PORTB &= ~(1<<PB1);

my_delay_ms(200);

}


void dash(void){

PORTB |= (1<<PB1);

my_delay_ms(500);

PORTB &= ~(1<<PB1);

my_delay_ms(500);

}


void my_delay_ms(uint16_t n){

while(n--) {

_delay_ms(1);

}

}



void goToSleep(void)

{

//make all pins inputs with pullups enabled


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

__asm__ __volatile__("sleep") ; //enter sleep, waiting for interrupt -- This worked great!!!

}


void hearBeat(void){

//long beat getting brighter

if(upDown==1){

pwmCount++;

OCR0A=pwmCount;

if(pwmCount>40+(heartBeatCount*2)){

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>40+(heartBeatCount*2)){

upDown=3;

if(hbDir==down){

heartBeatCount--;

}else{

heartBeatCount++;

}

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

}else{

heartBeatCount++;

}

if (heartBeatCount>40){

hbDir=down;

}

if (heartBeatCount<1){

hbDir=up;

}

loopCount++; //count loops for beats to sleep

}

}

PORTB ^= (1<<PB1);

//after so many beats, go to sleep

if(loopCount>90){

loopCount=0;

DDRB = 0;

PORTB = 0;

goToSleep();


}

}