How to make the built-in LED blink with a frequency of 5 Hz using interrupts

How to make the built-in LED(pin 13) blink with a frequency of 5 Hz using interrupts

Do you have to use interrupts or are other methods allowed ?

How strict is the requirement to use interrupts ? I ask because delay() uses interrupts, so you could meet the requirements to use interrupts if you used delay()

#include <TimerOne.h>

const byte PinLed = LED_BUILTIN;

const int Period = 25;
int cnt;

void isr (void) {
    if (Period <= ++cnt) {
        cnt = 0;
        digitalWrite (PinLed, ! digitalRead (PinLed));
    }
}

void
loop (void)
{
}

void
setup (void)
{
    Serial.begin (9600);

    pinMode (PinLed, OUTPUT);

    Timer1.initialize       (100000);
    Timer1.attachInterrupt (isr);
}

I used time interrupt 2, I don't know if I implemented it well, the task is: after five clicks on OK, the built-in LED starts flashing with a frequency of 5Hz using an interrupt. After the eighth click on OK, the flashing (and glowing) should stop:

bool ledState = false;
volatile bool ledOn = true;

void setup(){
TCCR2A = 0;
  TCCR2B = 0;
  TIMSK2 = 0;
  TCNT2 = 0;
  OCR2A = 77;
  TCCR2B |= (1 << CS22) | (1 << CS21) | (1 << CS20);
  TIMSK2 |= (1 << OCIE2A);
 pinMode(13, OUTPUT);
}

void loop(){
 if(button5.buttonPressedCount >= 5 && button5.buttonPressedCount < 8){
    ledState = true;
  }

  if(button5.buttonPressedCount > 7){
    ledState = false;
  }
}

ISR(TIMER2_COMPA_vect){
  if(ledState){
  digitalWrite(13, ledOn);
  ledOn = !ledOn;
  }
}

This is the first mention of a button as far as I remember. Are there any other details of the project that you have not shared yet ?

Where is the button input defined ?

the buttons from the remote control and the receiver

So now there is a remote control and a receiver in your project. As I said previously

In any case, the sketch that you posted does not compile

With a clock frequency of 16MHz and a max prescaler value of 1024, the lowest frequency TIMER2 is capable of is 16 000 000 / 1024 / 256 = 61.03515625 Hz. You then need to divide that 12 to get about 5Hz.

Here is what I coded (using Nick Gammon's tutorial) to blink an LED using interrupts :
TIMER2 generates an interrupt every 1ms.

/*****************************************/
/*      V2 :   Serial Dialog added       */
/*****************************************/

const int ON_DURATION    = 100;
const int OFF_DURATION   = 200-ON_DURATION;
const int SAFETY_MARGIN  = 10;

volatile unsigned int offInterval = OFF_DURATION;
volatile unsigned int pulseWidth  = ON_DURATION;

// internal to counting routine
unsigned int timerTicks  = 0;
unsigned int timerPeriod;
byte LedState = 0;

void startCounting()
{
  // reset Timer 2
  TCCR2A = 0;
  TCCR2B = 0;

  // Timer 2 - gives us our 1 ms counting interval
  // 16 MHz clock (62.5 ns per tick) - prescaled by 128
  TCCR2B =  bit(CS20) | bit(CS22) ;
  //  counter increments every 8 µs.
  // So we count 125 of them, giving exactly 1000 µs (1 ms)
  TCCR2A = bit(WGM21) ;   // CTC mode
  OCR2A  = 125 - 1;       // count up to 125 (zero relative !!!!)

  // Timer 2 - interrupt on match (ie. every 1 ms)
  TIMSK2 = bit(OCIE2A);   // enable Timer2 Interrupt

  TCNT2 = 0;      // Counter to zero

  // Reset prescalers
  GTCCR = bit(PSRASY);        // reset prescaler now
  // start Timer 2

}  // Ready to roll !!!

//******************************************************************
//  Timer2 Interrupt Service is invoked by hardware Timer 2 every 1 ms = 1000 Hz
//  16Mhz / 128 / 125 = 1000 Hz

ISR(TIMER2_COMPA_vect)
{
  // see if we have reached timing period
  if(++timerTicks >= timerPeriod)
  {
    timerTicks = 0;              // reset interrupt counter
    LedState = !LedState;        // inverser l'état (virtuel) de la LED
    digitalWrite(LED_BUILTIN, LedState); // commuter la LED
    if(LedState == HIGH)
    {
      timerPeriod = pulseWidth;
    }
    else
    {
      timerPeriod = offInterval;
    }
  }
}  // end of TIMER2_COMPA_vect

void setup()
{
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);  // configurer la broche de la LED comme sortie
  LedState = 0;
  digitalWrite(LED_BUILTIN, LedState);

  while(!Serial)
  {
    ;  // wait for serial port to connect. Needed for native USB port only
  }
  Serial.println("Timer Interrupt LED Blink V2");
  Serial.println("Type 'Pxxx' to set Period (ms) & 'Wxxx' to set Width (ms)");
  Serial.println("Enjoy !!!");

  startCounting();
} // end of setup

void loop()
{
  unsigned int MessageVal, localPulseWidth, LocalOffInterval;

  if(Serial.available())     //if data available
  {
    String Message = Serial.readStringUntil('\n');
    Message.trim();              // remove any \r \n whitespace at the end of the String
    switch(Message[0])
    {
      case 'P':
      case 'p':
        Message = Message.substring(1);
        MessageVal = Message.toInt();
        if(MessageVal > pulseWidth + SAFETY_MARGIN)
        {
          LocalOffInterval = MessageVal - pulseWidth;
          noInterrupts();
          offInterval = LocalOffInterval;
          interrupts();
          Serial.print("Period changed to ");
          Serial.println(MessageVal);
        }
        else
        {
          Serial.print("Command Discarded. Pulse Width is ");
          Serial.println(pulseWidth);
          Serial.print("Minimum Period : ");
          Serial.println(pulseWidth + SAFETY_MARGIN);
        }
        break;
      case 'W':
      case 'w':
        Message = Message.substring(1);
        localPulseWidth = Message.toInt();
        noInterrupts();
        pulseWidth = localPulseWidth;
        interrupts();
        Serial.print("Pulse Width changed to ");
        Serial.println(localPulseWidth);
        break;
      default:
        Serial.print("Unknown Command : '");
        Serial.print(Message);
        Serial.println("'");
        Serial.println("Type 'Pxxx' to set Period (ms) & 'Wxxx' to set Width (ms)");
        break;
    }
  }
}

It is very stable as long as timerPeriod is less than 256, probably because 16 bit comparison takes less time when high bytes are different : no need to compare low bytes. Little bit of jitter above 255.
I should tinker with union or highByte() lowByte() and exclusive or to solve this.

Not true, a previous version was spot on... Investigation required...

tips how to improve your posting style

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.