1

I am trying to use the timer interrupt on an Arduion Uno.

Here is a imple example code for displaying a progressive digit on a lcd display, which is updated with timer interupt every second:

#include <LCD_I2C.h>
LCD_I2C lcd(0x27);
volatile bool timerFlag = false; // Timer-Flag (timer-Interrupt)
int displayWidth = 16; // display width
int digit = 0; // current digit
void setup() {
 lcd.begin();
 lcd.backlight();
 lcd.setCursor(0, 0);
 lcd.print("Initializing...");
 noInterrupts();
 TCCR1A = 0;
 TCCR1B = (1 << CS12) | (1 << CS10); // set Prescaler to 1024 
 TCNT1 = 0;
 OCR1A = 15624; // should be 1 second with a prescaler of 102
 TIMSK1 |= (1 << OCIE1A); // Enable timer interrupt
 interrupts();
}
ISR(TIMER1_COMPA_vect) {
 timerFlag = true;
}
void loop() {
 static int position = 0;
 char displayString[17]; // +1 null termination
 
 if (timerFlag) {
 lcd.clear(); // clear display
 
 // update digit and progress
 digit = (digit + 1) % 10;
 position = (position + 1) % (displayWidth + 1);
 memset(displayString, ' ', displayWidth);
 displayString[displayWidth] = '0円'; add null termination
 displayString[position] = '0' + digit; // Character for the current digit
 
 // Show updated progress on the display
 lcd.setCursor(0, 1);
 lcd.print(displayString);
 
 timerFlag = false;
 }
}

The values for setting up he inteupt timer 1 for 1 second is arround everywhere. BUt the updates generated by this code is clearly much slower than 1 second, it's more about 4 seconds. So i did a comparison with a delay based version of the same example:

#include <LCD_I2C.h>
LCD_I2C lcd(0x27);
int displayWidth = 16; // display width
void setup() {
 lcd.begin();
 lcd.backlight();
 lcd.setCursor(0, 0);
 lcd.print("Initializing...");
}
void loop() {
 for (int digit = 0; digit < 10; digit++) {
 char displayString[17]; // +1 null termination
 int position = digit % (displayWidth + 1);
 // Update progression
 memset(displayString, ' ', displayWidth);
 displayString[displayWidth] = '0円'; // add null termination
 displayString[position] = '0' + digit; // Character for the current digit
 
 // Show updated progress on the display
 lcd.clear(); // Clear display
 lcd.setCursor(0, 1);
 lcd.print(displayString);
 delay(1000);
 }
}

This one works as expected and updates every second.

So what is wrong with my interrupt settings?

asked Aug 11, 2023 at 5:08
0

2 Answers 2

3

There is a flag in TCCR1A/B called WGM12 which sets the wave generation mode (WGM) to Clear Timer on Compare Match (CTC). This causes the timer to count up to the value in OCR1A and then automatically reset to 0.

This flag was forgotten, so the interrupt simply ignores the setting OCR1A = 15624; and counts through to 65535, which corresponds to the observed factor of about 4. Therefore the setting line for TCCR1B must be changed to

TCCR1B = (1 << WGM12) | (1 << CS12) | (1 << CS10); 
// Set CTC mode and set Prescaler to 1024

Now the interrupt is triggered correctly every second.

answered Aug 18, 2023 at 10:26
1
  • "This still got me some time to find out what it means and what i needed to do, so:" I'm pleased that it was a useful learning exercise for you and your description looks good. Much more valuable than receiving a ready made and complete solution. Commented Aug 18, 2023 at 11:01
2

It is ignoring this OCR1A = 15624; and simply rolling over at 65535 instead., hence the error factor of 4. You have to set the wave generation mode as CTC in registers TCCR1A/B.

answered Aug 11, 2023 at 6:31
2
  • Thank you for the answer. Unfortunately, I won't be able to try it out until after the weekend. I will see if it works (but I am pretty confident) Commented Aug 11, 2023 at 19:36
  • This still got me some time to find out what it means and what i needed to do, so: The ctc mode means "Clear Timer on Compare Match" and is controled by the WGM12 flag in the TCCR1A/B register. As I'm using the TCCR1b, the line gets: ` TCCR1B = (1 << WGM12) | (1 << CS12) | (1 << CS10);` Commented Aug 18, 2023 at 10:10

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.