Arduino Interrupts not working

Hi all,
I'm making a shot clock for a beer pong table, that uses 4 seven segment displays in pairs of two, they mirror each other and the resetting of the clock is done by pressing a big arcade style button that uses a micro switch and has an led built in, I've programmed it so its turn based (i've called the sides Champions and Challengers) and the side whose turn it is the button LED will be on (switched by an npn transistor) and when you press the button the clock should return to 24 and the light should turn on the other side and then allow them to use the button, I'm 100% confident in the wiring of the project because i initially had the code set up with digital read's for the button however it would miss many button presses due to the use of delays and having to manually poll to see if the button is press so i reprogrammed it using interrupts for the buttons (this is my first try at interrupts read through a few tutorials) however now the counter doesn't work at all, but the lights seem to switch sides but only one side lights up, which is strange but the turn based part seems to work. I'm sure I've coded something wrong. Thanks for the help in advance it's a little messy but i've commented on a fair bit of it, I haven't touched displaydigit() and the old code used to work so i'm assuming I've implemented the intterups incorrectly.

const int a = 10;
const int b = A4;
const int c = 4;
const int d = 5;
const int g = 6;
const int f = 7;
const int e = 8;
int button = 0;
const byte buttonPin = 2;
const byte button2Pin = 3;
const int buzzerPin = 9;
volatile byte buttonState = 0;  
const int a2 = 13;
const int b2 = 12;
const int c2 = 11;
const int d2 = A0;
const int g2 = A1;
const int f2 = A2;
const int e2 = A3;
int num = 24;
int firstgo = 0;
const int champlight = A6;
const int challengelight = A5;
int champions = 0;
int challengers = 0;

void setup()
{
  //initialse pins
  Serial.begin(9600);
  pinMode(champlight, OUTPUT);
  pinMode(challengelight, OUTPUT);
  pinMode(a, OUTPUT);
  pinMode(a, OUTPUT);
  pinMode(b, OUTPUT);
  pinMode(c, OUTPUT);
  pinMode(d, OUTPUT);
  pinMode(e, OUTPUT);
  pinMode(f, OUTPUT);
  pinMode(g, OUTPUT);
  pinMode(buzzerPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(button2Pin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(buttonPin), champreset, LOW); 
  attachInterrupt(digitalPinToInterrupt(button2Pin), challengereset, LOW);
  pinMode(a2, OUTPUT);
  pinMode(b2, OUTPUT);
  pinMode(c2, OUTPUT);
  pinMode(d2, OUTPUT);
  pinMode(e2, OUTPUT);
  pinMode(f2, OUTPUT);
  pinMode(g2, OUTPUT);
  //flash all segements on and off
        digitalWrite(a, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(c, HIGH);
    digitalWrite(d, HIGH);
    digitalWrite(e, HIGH);
    digitalWrite(f, HIGH);
    digitalWrite(a2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(c2, HIGH);
    digitalWrite(d2, HIGH);
    digitalWrite(e2, HIGH);
    digitalWrite(f2, HIGH);
        digitalWrite(g, HIGH);
    digitalWrite(g2, HIGH);
    delay(250);
    turnoff();
       delay(250);
    digitalWrite(a, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(c, HIGH);
    digitalWrite(d, HIGH);
    digitalWrite(e, HIGH);
    digitalWrite(f, HIGH);
    digitalWrite(a2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(c2, HIGH);
    digitalWrite(d2, HIGH);
    digitalWrite(e2, HIGH);
    digitalWrite(f2, HIGH);
        digitalWrite(g, HIGH);
    digitalWrite(g2, HIGH);
       delay(250);
           turnoff();
       delay(250);
    digitalWrite(a, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(c, HIGH);
    digitalWrite(d, HIGH);
    digitalWrite(e, HIGH);
    digitalWrite(f, HIGH);
    digitalWrite(a2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(c2, HIGH);
    digitalWrite(d2, HIGH);
    digitalWrite(e2, HIGH);
    digitalWrite(f2, HIGH);
        digitalWrite(g, HIGH);
    digitalWrite(g2, HIGH);
           delay(250);
        turnoff();
          delay(250);
    digitalWrite(a, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(c, HIGH);
    digitalWrite(d, HIGH);
    digitalWrite(e, HIGH);
    digitalWrite(f, HIGH);
    digitalWrite(a2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(c2, HIGH);
    digitalWrite(d2, HIGH);
    digitalWrite(e2, HIGH);
    digitalWrite(f2, HIGH);
    digitalWrite(g, HIGH);
    digitalWrite(g2, HIGH);
    delay (500);
    turnoff();
    delay (500);
    //display 24 on the seven segment displays   
    digitalWrite(a2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(g2, HIGH);
    digitalWrite(e2, HIGH);
    digitalWrite(d2, HIGH);
    digitalWrite(f, HIGH);
    digitalWrite(g, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(c, HIGH);

  while(firstgo == 0){} //wait for either button to be pressed to determine which side is active and begin the countdown, the code works correctly up to here and displays 24 and waits for input
  Serial.println("start countdown");
}

void loop() 
{
      displayDigit(); //display what second the counter is up to
      num--; //subtract one
      delay(1000); //wait a second
            turnoff(); //turn off all segments
}


  void champreset() //when the 'champions side button is pressed
  {
 if (champions == 1) //check if its the champions sides turn
 { 
    champions = 0; //deactivate the active condition for the champions side
	digitalWrite(champlight, LOW); //turn off the champion side light
	challengers = 1; //activate challengers side condition
	digitalWrite(challengelight, HIGH); //turn the challengers side light on
	resetnum();
    }
else if (firstgo == 0) //check to see if it is the first loop
{
   digitalWrite(champlight, HIGH); //turn the champions light on
   champions = 1; //activate champions side condition
   firstgo = 1;	//deactivate the first loop condition
   resetnum();
}
  }
  
  
  void challengereset() //when the 'champions side button is pressed
  {
if (challengers == 1) //check if its the champions sides turn
 { 
    challengers = 0;  //deactivate the active condition for the challengers side
	digitalWrite(challengelight, LOW); //turn off the challenger side light
	champions = 1; //activate champions side condition
	digitalWrite(champlight, HIGH); //turn the champions side light on
	resetnum();
    }
else if (firstgo == 0) //check to see if it is the first loop
{
   digitalWrite(challengelight, HIGH);
   challengers = 1; //activate challengers side condition
   firstgo = 1;	//deactivate the first loop condition
   resetnum();
}
  }
  
  void resetnum()
{
num=24; //return the clock to 24
delay(100); //simple delay when switching sides
turnoff(); //turn off the seven segment displays 
loop();  //run the count down loop
}

  
void turnoff() 
{
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
  digitalWrite(a2, LOW);
  digitalWrite(b2, LOW);
  digitalWrite(c2, LOW);
  digitalWrite(d2, LOW);
  digitalWrite(e2, LOW);
  digitalWrite(f2, LOW);
  digitalWrite(g2, LOW);
}


void displayDigit()
{
  if (num == 0) //if it reaches 0 flash the displays and play a sound in the buzzer then wait for input from one of the buttons
  {
    Serial.println(num);
    digitalWrite(a, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(c, HIGH);
    digitalWrite(d, HIGH);
    digitalWrite(e, HIGH);
    digitalWrite(f, HIGH);
    digitalWrite(a2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(c2, HIGH);
    digitalWrite(d2, HIGH);
    digitalWrite(e2, HIGH);
    digitalWrite(f2, HIGH);
    tone(buzzerPin, 200);
    delay(250);
    turnoff();
       delay(250);
    digitalWrite(a, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(c, HIGH);
    digitalWrite(d, HIGH);
    digitalWrite(e, HIGH);
    digitalWrite(f, HIGH);
    digitalWrite(a2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(c2, HIGH);
    digitalWrite(d2, HIGH);
    digitalWrite(e2, HIGH);
    digitalWrite(f2, HIGH);
       delay(250);
           turnoff();
       delay(250);
    digitalWrite(a, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(c, HIGH);
    digitalWrite(d, HIGH);
    digitalWrite(e, HIGH);
    digitalWrite(f, HIGH);
    digitalWrite(a2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(c2, HIGH);
    digitalWrite(d2, HIGH);
    digitalWrite(e2, HIGH);
    digitalWrite(f2, HIGH);
           delay(250);
        turnoff();
          delay(250);
    digitalWrite(a, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(c, HIGH);
    digitalWrite(d, HIGH);
    digitalWrite(e, HIGH);
    digitalWrite(f, HIGH);
    digitalWrite(a2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(c2, HIGH);
    digitalWrite(d2, HIGH);
    digitalWrite(e2, HIGH);
    digitalWrite(f2, HIGH);
    noTone(buzzerPin);
    while (num == 0) {}
  }

  if (num == 1)
  {
        Serial.println(num);
    digitalWrite(c, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(a2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(c2, HIGH);
    digitalWrite(d2, HIGH);
    digitalWrite(e2, HIGH);
    digitalWrite(f2, HIGH);
  }

  if (num == 2)
  {
        Serial.println(num);
    digitalWrite(a, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(g, HIGH);
    digitalWrite(e, HIGH);
    digitalWrite(d, HIGH);
    digitalWrite(a2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(c2, HIGH);
    digitalWrite(d2, HIGH);
    digitalWrite(e2, HIGH);
    digitalWrite(f2, HIGH);
  }

  if (num == 3)
  {    Serial.println(num);
    digitalWrite(a, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(c, HIGH);
    digitalWrite(d, HIGH);
    digitalWrite(g, HIGH);
    digitalWrite(a2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(c2, HIGH);
    digitalWrite(d2, HIGH);
    digitalWrite(e2, HIGH);
    digitalWrite(f2, HIGH);
  }

  if (num == 4)
  {
        Serial.println(num);
    digitalWrite(f, HIGH);
    digitalWrite(g, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(c, HIGH);
    digitalWrite(a2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(c2, HIGH);
    digitalWrite(d2, HIGH);
    digitalWrite(e2, HIGH);
    digitalWrite(f2, HIGH);
  }

  if (num == 5)
  {
        Serial.println(num);
    digitalWrite(a, HIGH);
    digitalWrite(f, HIGH);
    digitalWrite(g, HIGH);
    digitalWrite(c, HIGH);
    digitalWrite(d, HIGH);
    digitalWrite(a2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(c2, HIGH);
    digitalWrite(d2, HIGH);
    digitalWrite(e2, HIGH);
    digitalWrite(f2, HIGH);
  }

  if (num == 6)
  {
        Serial.println(num);
    digitalWrite(a, HIGH);
    digitalWrite(f, HIGH);
    digitalWrite(e, HIGH);
    digitalWrite(d, HIGH);
    digitalWrite(c, HIGH);
    digitalWrite(g, HIGH);
    digitalWrite(a2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(c2, HIGH);
    digitalWrite(d2, HIGH);
    digitalWrite(e2, HIGH);
    digitalWrite(f2, HIGH);
  }

  if (num == 7)
  {
        Serial.println(num);
    digitalWrite(a, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(c, HIGH);
    digitalWrite(a2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(c2, HIGH);
    digitalWrite(d2, HIGH);
    digitalWrite(e2, HIGH);
    digitalWrite(f2, HIGH);
  }

  if (num == 8)
  {
        Serial.println(num);
    digitalWrite(a, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(c, HIGH);
    digitalWrite(d, HIGH);
    digitalWrite(e, HIGH);
    digitalWrite(f, HIGH);
    digitalWrite(g, HIGH);
    digitalWrite(a2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(c2, HIGH);
    digitalWrite(d2, HIGH);
    digitalWrite(e2, HIGH);
    digitalWrite(f2, HIGH);
  }

  if (num == 9)
  {
        Serial.println(num);
    digitalWrite(a, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(c, HIGH);
    digitalWrite(d, HIGH);
    digitalWrite(f, HIGH);
    digitalWrite(g, HIGH);
    digitalWrite(a2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(c2, HIGH);
    digitalWrite(d2, HIGH);
    digitalWrite(e2, HIGH);
    digitalWrite(f2, HIGH);
  }

  if (num == 10)
  {
        Serial.println(num);
    digitalWrite(a, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(c, HIGH);
    digitalWrite(d, HIGH);
    digitalWrite(e, HIGH);
    digitalWrite(f, HIGH);
    digitalWrite(c2, HIGH);
    digitalWrite(b2, HIGH);
  }

  if (num == 11)
  {
        Serial.println(num);
    digitalWrite(c2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(c, HIGH);
    digitalWrite(b, HIGH);
  }

  if (num == 12) {
        Serial.println(num);
    digitalWrite(c2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(a, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(g, HIGH);
    digitalWrite(e, HIGH);
    digitalWrite(d, HIGH);
  }

  if (num == 13) {
        Serial.println(num);
    digitalWrite(c2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(a, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(c, HIGH);
    digitalWrite(d, HIGH);
    digitalWrite(g, HIGH);
  }

  if (num == 14) {
        Serial.println(num);
    digitalWrite(c2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(f, HIGH);
    digitalWrite(g, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(c, HIGH);
  }

  if (num == 15) {
        Serial.println(num);
    digitalWrite(c2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(a, HIGH);
    digitalWrite(f, HIGH);
    digitalWrite(g, HIGH);
    digitalWrite(c, HIGH);
    digitalWrite(d, HIGH);
  }

  if (num == 16) {
        Serial.println(num);
    digitalWrite(c2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(a, HIGH);
    digitalWrite(f, HIGH);
    digitalWrite(e, HIGH);
    digitalWrite(d, HIGH);
    digitalWrite(c, HIGH);
    digitalWrite(g, HIGH);
  }

  if (num == 17) {
        Serial.println(num);
    digitalWrite(c2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(a, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(c, HIGH);
  }

  if (num == 18) {
        Serial.println(num);
    digitalWrite(c2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(a, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(c, HIGH);
    digitalWrite(d, HIGH);
    digitalWrite(e, HIGH);
    digitalWrite(f, HIGH);
    digitalWrite(g, HIGH);
  }

  if (num == 19) {
        Serial.println(num);
    digitalWrite(c2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(a, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(c, HIGH);
    digitalWrite(d, HIGH);
    digitalWrite(f, HIGH);
    digitalWrite(g, HIGH);
  }

  if (num == 20) {
        Serial.println(num);
    digitalWrite(a2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(g2, HIGH);
    digitalWrite(e2, HIGH);
    digitalWrite(d2, HIGH);
    digitalWrite(a, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(c, HIGH);
    digitalWrite(d, HIGH);
    digitalWrite(e, HIGH);
    digitalWrite(f, HIGH);
  }

  if (num == 21) {
        Serial.println(num);
    digitalWrite(a2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(g2, HIGH);
    digitalWrite(e2, HIGH);
    digitalWrite(d2, HIGH);
    digitalWrite(c, HIGH);
    digitalWrite(b, HIGH);
  }

  if (num == 22) {
        Serial.println(num);
    digitalWrite(a2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(g2, HIGH);
    digitalWrite(e2, HIGH);
    digitalWrite(d2, HIGH);
    digitalWrite(a, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(g, HIGH);
    digitalWrite(e, HIGH);
    digitalWrite(d, HIGH);
  }

  if (num == 23) {
        Serial.println(num);
    digitalWrite(a2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(g2, HIGH);
    digitalWrite(e2, HIGH);
    digitalWrite(d2, HIGH);
    digitalWrite(a, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(c, HIGH);
    digitalWrite(d, HIGH);
    digitalWrite(g, HIGH);
  }

  if (num == 24) {
        Serial.println(num);
    digitalWrite(a2, HIGH);
    digitalWrite(b2, HIGH);
    digitalWrite(g2, HIGH);
    digitalWrite(e2, HIGH);
    digitalWrite(d2, HIGH);
    digitalWrite(f, HIGH);
    digitalWrite(g, HIGH);
    digitalWrite(b, HIGH);
    digitalWrite(c, HIGH);
  }
}

You know in the reference, where it says don't do delays in interrupt context?

They're not joking.

And don't try calling loop from interrupt context either.

Its a big mistake of beginners that they think interruts are normal functions. They are NOT!! If you don't know exactly what happens with interrupts, do not use them. The make more problems than they solve in this case.

That's the point. It would make much more sense to learn how to program without delay. Than it's no problem to poll the buttons in loop.

Interrupts are a Catch 22. You shouldn't use them unless you know what you're doing. However, you'll never gain the experience necessary to know what you're doing unless you try using them and get burned a few times.

OP's case is typical of many newbie's. They paint themselves into a corner with poorly-organized, blocking code and then hope interrupts will rescue them. They won't.

2 Likes

Actually, only two possibilities here. Continue, or wait forever.

Yes that's true. But I think the OP has a lot of other things to learn - especially how to write well organised - nonblocking code :wink: - before get burned with interrupts :grinning:

Why not post that here (don't edit the first post)? It would at least be a starting point.

An MCU is so useful because of its capability of handling interrupts. Therefore, I would suggest every user to learn the "interrupt manangement" as quick as possible by performing available examples.

Objection - It makes no sense to deal with interrupts until you have learned the basics of cleanly structured and blocking-free programming. No book on programming starts with interrupts.

I'm with @gfvalvo :

The ATmega328P MCU has a good number of hardware modules including the interrupt, which must be learnt at least partially to chalk out a basic design of a MCU-based system. Therefore, learning of these hardware modules could be simultaneous (quick successions among the modules) other that "do full llearning of IO" and then "start learning of interrupt or any other module".

Learning how to drive a car, and learning how the drive train works, are two different things. Both important, but different. Also you can learn to drive a car very well, and never know exactly how the drive train works.

3 Likes

Scratched my head on this for a while.
It's a fantastic analogy, but the use of interrupts is a good idea when it comes to rotary encoders, hall sensors, and other deceives that need to record at high speed. Some of this stuff is available in libraries, but I don't think it all is, or that it covers all needs.
Learning how to properly handle interrupts is probably a good thing for anyone doing this for more than one project or more than one class to fill a degree requirement, but it is not absolutely necessary by any stretch.