Newbie question regarding interrupts


This is my first post here… so hello and hope I have done this post properly, according to the posting rules.

I’m a newbie to Arduino and I’m an old assembler dude who is very familiar with 8080/85, Z80, 6800 and 6502 hardware/software, but I am keen to get into the Arduino.

I have a simple project that I am building to allow an Arduino to countdown in seconds, using the Timer1 interrupt, and display hours and minutes on 3 x 7 segment LED displays. At then end of the time period the relay is switched off. It will also have 2 push buttons. Button A will activate the unit, where it will commence counting down. If I hit Button A during the countdown it will set back to the start again. Button B is to stop counting immediately, and thereby de-activate the relay.

To make sure I got my interrupt timing working I am sending the values to my PC via serial print. Once I get that sorted I can then add the LED displays and button, with the subsequent code.

The code I am using is below, and I do apologise if it is rubbish, but I am still learning. My issue is, when the countdown goes to 0, I expect the serial print to say “0:0:0” for hours, minutes and seconds, respectively, followed by “Timer Expired” message. However, I don’t get this. I do if I comment out the “noInterrupts” line, but then the thing keeps counting down. Can someone point out what I have done wrong.

I am using Arduino 1.8.1 running on a PC with Windows10, and using an Arduino UNO.

The TimerOne library I got from an example in “Exploring the Arduino” book by Jeremy Blum.


// Timer1 interrupt using seconds countdown
  // to derive hours and minutes
  #include <TimerOne.h>
  unsigned int start_count = 5;  // Initial count in seconds
  int flag = 0;                  // Interrupt flag
  int end_flag = 0;              // Flag for printing "Timer Expired" just once
  unsigned int hour;             // hours
  unsigned int minute;           // minutes
  unsigned int second;           // seconds
void setup() {
  // put your setup code here, to run once:
 end_flag = 0;                   // Clear flag for "Timer Expired" routine
 Serial.begin(9600);             // Set up serial port
 Serial.print("\n");             // Send carriage return
 Timer1.initialize(1000000);     // Intialise Timer1 for 1 second interrupt
 Timer1.attachInterrupt(CountDown);  // Activate Timer1 and interrupts

void loop() 
  // Execute uppon each timer interrupt 
  if (flag == 1)                 // Execute serial prints if interrupt flag is set
    Serial.print(start_count);   // serial print intial countdown of seconds
    Serial.print(" - ");         // and hours:minutes:seconds
    Serial.print(hour);          // and followed by carriage return
    start_count = start_count - 1;  // Decrement seconds counter
    flag = 0;                    // clear interrupt flag so only above is printed once
                                 // per interrupt

  if (start_count == 65535 && end_flag == 0) // Kludge to determine when decremented beyond
                                             // 0 seconds remaining
    Serial.print("\n");                      // print carriage return
    Serial.print("Timer Expired");           // and "Timer Expired" message
    end_flag = 1;                            // Set flag so "Timer Expired" is omnly printed once
    noInterrupts();                          // Time expired so disable interrupts

void CountDown()                                        // Timer1 expired interrupt service routine
  hour = start_count / 3600;                            // derive remaining hours
  minute = (start_count % 3600) / 60;                   // derive remaining minutes
  second = start_count - (hour * 3600) - (minute * 60); // derive remaining seconds
  flag = 1;                                             // Set interrupt flag


river: I have a simple project that I am building to allow an Arduino to countdown in seconds, using the Timer1 interrupt...

Why? Blink-without-delay is a far better choice.

Why?... because I don't know better, and didn't know what to search for such a thing. I'll go look for it. Thanks.

These are a good place to start...

"flag" should be volatile.

hour, minute and second should also be volatile.


Never do this

    noInterrupts();                          // Time expired so disable interrupts

It stops ALL interrupts !


There is nothing wrong (or unusual) about using noInterrupts() but it should be followed very very quickly by interrupts() to turn them back on.

But it will probably be a lot simpler not to use interrupts at all in this project. The demo Several Things at a Time is an extended example of BWoD and illustrates the use of millis() to manage timing. It may help with understanding the technique.



Thanks for your replies. Much appreciated.

I have gone and checked some of the links and, by using the sample code from Robin2, I got a LED flashing without "delay", and I understand the logic on how it works. I can build up on this now, with a clearer understanding.

Many thanks to the other posters regarding interrupts, volatile and other links - which I will read up on and check out.

To give some clarity about my project.... I have a nice audio-visual room, which has an AV amp and a nice old school stereo amp (restoration/repair old amplifiers is one of my hobbies). They need to share the same sets of speakers, and by default the speakers connect to the AV amp. I could use or build a speaker switch to select the speakers between the 2 amps, but that seems crude and too simple, so I decided to use an Arduino.

The concept is to have the Arduino activate a set of relays to switch the speakers to the stereo amp, with 3 x 7seg LED displays, which count down minutes from 8:00 to 0:00 (8 hours). When at 0:00 the relays are de-energised, which means the speakers will then connect to the AV amp, and the LED display to go blank. The Arduino has 2 buttons. Pressing Button A activates the relays and starts the time at 8:00, and therefore connects the speakers to the stereo amp. Button B de-activates the relays and the LED display will go off and speakers will be connected to the AV amp.

The whole "timing" thing I am doing is to count down and display minutes remaining, with the ability of the Arduino to still be able to check for buttons.

Hopefully, when I get this done, I can progress onto more adventurous Arduino projects.

regards River

Thank you for the follow-up.

Skip the relay - look at an analog mux chip.



Haven’t looked into analog mux’s yet. May do so at a later stage but first I’ll use relays, especially as the amps push out 150W RMS.

Anyway, I was quite industrious today, did a lot of reading and experimenting and now have some code which uses “milli()” to decrement at one second intervals, and display this on an SPI 4-digit, 7-seg display. When the count reaches zero the relay (current code uses LedPin 13) goes off.

I need to add the buttons and also convert count to time (initial value will be 28800 for 8hours in seconds), but I’m pretty chuffed at what I got done so far. It may be a simple thing and no doubt poor coding for you guys, but for me it’s good progress.

Thanks for your assistance :slight_smile:

/* Speaker Relay
 * Application using Arduino UNO to switch relays to connect 
 * speakers between 2 amplifiers.
 * Button A switches on the relays and commences a countdown
 * from 8hrs, displaying hours & minutes on a 4-digit 7-segment
 * LED display. If Button A is pressed during the count down, it 
 * will start back at 8 hours.
 * Button B cancels the count down, blanks the display and deactivates
 * the relays
 * Button pins are :-
 *     Pin 9 - Button A
 *     Pin 8 - Button B
 * The display is controlled via SPI, using the following pins :-
 *     Pin 12 - MSI (data in)
 *     Pin 11 - SCK (clock)
 *     Pin 10 - CS (select) *  
 *  The display is the "Serial 7-seg Display" from Mikroelektronika
 *  A small slave relay provides power for the 4 large speaker relays.
 *  Slave relay pin is...
 *     Pin 7 - Slave Relay
 *  The count down is acheived by using "milli()" function, and checking
 *  expired time. RTC accuracy is not required for this application.
 * Modification History
 * ===============================================================
 * Date     | Vers | Comments
 * 26/02/17 | 100  | Initial version - uses LED Pin13 to emulate relay

#include <LedControl.h>

const int LEDpin = 13;         // Emulate relay on/off
const int timeInterval = 1000; // 1 second time interval

unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
int ctr = 9999;                  // Countdown in seconds

LedControl lc = LedControl(12,11,10,1);  // Setup SPI display

void setup() {
  // Set up code - run once
  pinMode (LEDpin, OUTPUT);    // Output for Relay
  digitalWrite(LEDpin, HIGH);  // Relay energised
  lc.shutdown(0,false);        // Initialise display

void loop()
  // Mainline code
  currentMillis = millis();    // Get current run time in millisecs

  if (currentMillis - previousMillis >= timeInterval)
    previousMillis += timeInterval;  // Keep track of expired millisecs
    ctr = ctr - 1;                   // Decremenr remaining time 1 second
  ShowTimer(ctr);                    // Display remaining time

  if (ctr == 0)                      // if counter expired
    digitalWrite(LEDpin,LOW);        // De-activate relay

void ShowTimer(int v)               // Display count down
  int ones;                        
  int tens;
  int hundreds;
  int thousands;

  ones=v%10;                        // Derive values to display
  thousands = v; 

  lc.setDigit(0,3,(byte)thousands,false); // Display the countdown


Analog multiplexers:


Thanks for the link. I'll check it out :)