This example is a simplified version of what I really need to do, but I think it demonstrates the problem (= my misunderstanding?). I need to use a timer to count microseconds; my code shows how I set up the timer and indeed the timer produces 1 MHz square wave on pin 11 if setup_timer2()
is active.
However, when setup_timer2()
is active, the LED does not blink. If I comment out setup_timer2()
, the LED blinks as expected. In my more complex sketch, it appears that whatever I put in the loop is blocked when activating the timer.
It seems that activating the timer interferes with the blinking logic and I cannot figure out why. Relatively new to this stuff so quite possibly something simple.
// Logic to control on board LED derived from
// https://forum.arduino.cc/t/demonstration-code-for-several-things-at-the-same-time/217158
const int on_board_LED_pin = 13;
const int on_board_LED_interval = 3000;
const int on_board_LED_duration = 500;
byte on_board_LED_state = LOW;
unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
void setup() {
Serial.begin(9600);
Serial.println("Starting Demo");
pinMode(on_board_LED_pin, OUTPUT);
pinMode(11, OUTPUT); // 1 MHz square wave on this pin if timer activated
setup_timer2();
}
void loop() {
currentMillis = millis();
toggle_on_board_LED();
}
void toggle_on_board_LED() {
// change the state as needed
if (on_board_LED_state == LOW) {
if (currentMillis - previousMillis >= on_board_LED_interval) {
on_board_LED_state = HIGH;
previousMillis += on_board_LED_interval;
}
}
if (on_board_LED_state == HIGH) {
if (currentMillis - previousMillis >= on_board_LED_duration) {
on_board_LED_state = LOW;
previousMillis += on_board_LED_duration;
}
}
// implement the state
digitalWrite(on_board_LED_pin, on_board_LED_state);
}
void setup_timer2() {
cli(); //stop interrupts globally
TCCR2A = 0; // set entire TCCR0A register to 0
TCCR2B = 0; // same for TCCR0B
TCNT2 = 0; //initialize counter value to 0
OCR2A = 0;
TCCR2A |= (1 << WGM21); // CTC mode
TCCR2A |= (1 << COM2A0); // toggle pin OC2A on compare match (= pin 11)
TCCR2B |= (1 << CS21); // prescale by 8
TIMSK2 |= (1 << OCIE2A); // enable timer compare interrupt
sei(); // allow interrupts globally
}
EDIT
If I add the following declaration and ISR:
volatile unsigned long u_sec;
ISR(TIMER2_COMPA_vect) {
volatile unsigned long u_sec;
u_sec++;
}
The LED still does not blink.