I’m trying to create a long delay by cascading timers via the procedure outlined in Atmel Application Note AVR133. I’ve set timer #1 up to toggle the OCR1A (D9) pin and wired that to the T0 pin (D4) which clocks timer #0. Then I put the arduino to sleep and wait for the timer #0 interrupt to wake it. Or at least that’s what I’m trying to do. The values I’m using should toggle the pin 13 LED at a 1 minute frequency. A much longer delay is easily possible, but I can’t get it t work.
// AVR 133: Atmel Application Note Long Delay Generation
// T = 2/Fs x T1P x OCR1A x (256 - TCNT0)
// T = 2/16000000x256x7500x(256-6)
// T = 60 or 1 minute
//
// connect arduino D9 to D4:
// T0 = PD4 (Arduino D4 as input)
// OC1A = PB1 (Arduino D9 as output)
//
#include <avr/sleep.h>
#include <avr/power.h>
void setup() {
cli();
//set pins
DDRB |= (1<<PINB1) | (1<<PINB5); //set arduino D9 and D13 as outputs
PORTB &= ~(1<<PINB1); //set D9 low
PORTD &= ~(1<<PIND4); //set D4 low
//timer #1 toggles OCR1A on TCNT1=0 in turn toggling T0
TCCR1A = (1<<COM1A0); //TCCR1A toggle OC1A on compare match
TCCR1B = 0;
TCCR1C = 0;
OCR1A = 7500; //output compare register on division ratio of 7500
TIMSK1 = 0;
//timer #0 fires interrupt when TCNT0=0 waking arduino
TCCR0A = 0;
TCCR0B = 0;
TIMSK0 = (1<<TOIE0); //enable timer0 interrupt
sei();
}
void loop() {
//toggle led
PORTB ^= (1<<PINB5); //toggle led pin
//reset timers
TCNT0 = 6;
TCCR0B = (1<<CS00) | (1<<CS01) | (1<<CS02); //external source (t0) rising edge
TCNT1 = 0UL;
TCCR1B = (1<<WGM12) | (1<<CS12); //CTC mode 4 and 256 prescaler
set_sleep_mode(SLEEP_MODE_IDLE);
sleep_enable();
power_adc_disable();
power_spi_disable();
power_timer2_disable();
power_twi_disable();
sleep_mode();
//go to sleep here, wake on interrupt
sleep_disable();
power_all_enable();
//stop timers
TCCR1B = 0;
TCCR0B = 0;
}
edit: above code now works.