Skip to main content
added 211 characters in body
Source Link

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.

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.

Source Link

Timer setup interferes with LED blinking logic

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
}