Loop error with Interrupts

Hello everyone,

I keep getting the following error:

core.a(main.cpp.o): In function main': /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino/main.cpp:43: undefined reference to loop’
collect2: error: ld returned 1 exit status
Error compiling.

And I am not sure why. It’s my first time using interrupts so I may have made a mess of it.

int timer = 500;
int hold = 1000;
int ledpin = 10;
volatile byte f1 = LOW;
volatile byte f2 = LOW;
volatile byte f3 = LOW;
volatile byte f4 = LOW;
volatile int button = 0; 
int current;
int stopfloor;


void setup() {
  for (int ledpin = 10; ledpin<14; ledpin++){
    pinMode(ledpin, OUTPUT);
  }
  for (int buttonpin = 2; buttonpin<6; buttonpin++){
    pinMode(buttonpin, INPUT);
  }
  
}

void floorsetup(){
  if(digitalRead(2)==1){
    f1=HIGH;
  }
  if(digitalRead(3)==1){
    f2=HIGH;
  }
  if(digitalRead(4)==1){
    f3=HIGH;
  }
  if(digitalRead(5)==1){
    f4=HIGH;
  }
}

void switchfloor(int number){
  if(number == 1){
    digitalWrite(10,HIGH);
    digitalWrite(11,LOW);
    digitalWrite(12,LOW);
    digitalWrite(13,LOW);
  }
    if(number == 2){
    digitalWrite(10,LOW);
    digitalWrite(11,HIGH);
    digitalWrite(12,LOW);
    digitalWrite(13,LOW);
  }
    if(number == 3){
    digitalWrite(10,LOW);
    digitalWrite(11,LOW);
    digitalWrite(12,HIGH);
    digitalWrite(13,LOW);
  }
    if(number == 4){
    digitalWrite(10,LOW);
    digitalWrite(11,LOW);
    digitalWrite(12,LOW);
    digitalWrite(13,HIGH);
  }
}

void tofloor(int stopfloor, int current){
  if(stopfloor == current){
    switchfloor(stopfloor);
  }
  if(stopfloor>current){
    while(current <= stopfloor){
      switchfloor(current);
      delay(500);
      current = current+1;
    }
  }
  if(stopfloor<current){
    while(current >= stopfloor){
      switchfloor(current);
      delay(timer);
      current = current-1;
    }
  }
  delay(hold);
}


void floorcheck(){
  if(f1==HIGH){
    tofloor(1, current);
    current = 1;
    f1=LOW;
  }
  if(f2==HIGH){
    tofloor(2, current);
    current = 2;
    f2=LOW;
  }
  if(f3==HIGH){
    tofloor(3, current);
    current = 3;
    f3=LOW;
  }
  if(f4==HIGH){
    tofloor(4, current);
    current = 4;
    f4=LOW;
  }
  
}


void returnfloor() {
  switchfloor(1);
  attachInterrupt(2, floorcheck, HIGH);
  attachInterrupt(3, floorcheck, HIGH);
  attachInterrupt(4, floorcheck, HIGH);
  attachInterrupt(5, floorcheck, HIGH);

}

It’s telling you that there’s no loop() function in your sketch. There must be one and in your case it presumably should be calling one or more of those functions you’ve declared but which aren’t being called by anything.

Pete

There won't be any interrupts because the function which attaches them, returnfloor(), isn't called by anything either. Attaching interrupts is usually done once and usually from setup().

Pete

Thank you, that was a silly mistake. How do I incorporate an interrupt to start the "floorcheck" function if a button is pressed? I'd want it to interrupt the main loop which has been changed from returnfloor to "loop"

As I said, attachInterrupt should only be done once. Changing returnfloor so that it is your loop function means that those four attachInterrupt statements are going to be executed thousands of times a second.
Call the returnfloor function from setup so that the four interrupts are attached - once.

Then add a loop function

void loop(void)
{
}

Now, which Arduino are you using?

Pete

Right, I'll change that. I'm using an Uno R3

In that case, you're going to have a problem with:

  attachInterrupt(2, floorcheck, HIGH);
  attachInterrupt(3, floorcheck, HIGH);
  attachInterrupt(4, floorcheck, HIGH);
  attachInterrupt(5, floorcheck, HIGH);

because there are only two interrupts on UNO. Pins 2 (interrupt 0) and 3 (interrupt 1) can interrupt.
See attachInterrupt() - Arduino Reference

Pete

That’ll be a problem. Is there any way around this?

You don't need interrupts for what you're doing. I see the delays, you don't.

What kind of buttons are you using? Contact switches bounce, they might bounce your interrupt too.

Here is VERY GOOD information about contact switches/buttons:
http://www.gammon.com.au/switches

If your buttons are not contact switches and getting activated 1000+ times a second, then think of interrupts.

Here is VERY GOOD information about interrupts:
http://www.gammon.com.au/interrupts

And just so you know, I am not Nick Gammon but I do appreciate his site tremendously.

Don't use interrupts is one solution; I doubt you really need them.

Or use pinchange interrupt. In the interrupt, you can read the Arduino pins.

Okay I tried that and now have this:

int timer = 500;
int hold = 1000;
int ledpin = 10;
volatile byte f1 = LOW;
volatile byte f2 = LOW;
volatile byte f3 = LOW;
volatile byte f4 = LOW;
volatile int button = 0; 
int current=1;
int stopfloor;


void setup() {
  for (int ledpin = 10; ledpin<14; ledpin++){
    pinMode(ledpin, OUTPUT);
  }
  InitialiseIO();
  InitialiseInterrupt();
}

void InitialiseIO(){    
  pinMode(A1, INPUT);    
  digitalWrite(A1, HIGH);   
  pinMode(A2, INPUT);   
  digitalWrite(A2, HIGH);   
   pinMode(A3, INPUT);    
  digitalWrite(A3, HIGH);  
  pinMode(A4, INPUT);    
  digitalWrite(A4, HIGH);  
}

void InitialiseInterrupt(){ 
  cli();     
  PCICR =0x02;        
  PCMSK1 = 0b00011110;
  sei();    
}

ISR(PCINT1_vect){
  if(digitalRead(A4)==1){
    f1=HIGH;
  }
  if(digitalRead(A3)==1){
    f2=HIGH;
  }
  if(digitalRead(A2)==1){
    f3=HIGH;
  }
  if(digitalRead(A1)==1){
    f4=HIGH;
  }
}

void switchfloor(int number){
  if(number == 1){
    digitalWrite(10,HIGH);
    digitalWrite(11,LOW);
    digitalWrite(12,LOW);
    digitalWrite(13,LOW);
  }
    if(number == 2){
    digitalWrite(10,LOW);
    digitalWrite(11,HIGH);
    digitalWrite(12,LOW);
    digitalWrite(13,LOW);
  }
    if(number == 3){
    digitalWrite(10,LOW);
    digitalWrite(11,LOW);
    digitalWrite(12,HIGH);
    digitalWrite(13,LOW);
  }
    if(number == 4){
    digitalWrite(10,LOW);
    digitalWrite(11,LOW);
    digitalWrite(12,LOW);
    digitalWrite(13,HIGH);
  }
}

void tofloor(int stopfloor, int current){
  if(stopfloor == current){
    switchfloor(current);
    delay(hold);
    return;
  }
  if(stopfloor>current){
    while(current <= stopfloor){
      switchfloor(current);
      delay(timer);
      current = current+1;
    }
    
  }
  else if(stopfloor<current){
    while(current >= stopfloor){
      switchfloor(current);
      delay(timer);
      current = current-1;
    }
    
  }
  //tofloor(stopfloor, current);??
  delay(hold);
}

void loop(){
  current = 1;
  if(f1==HIGH){
    tofloor(1, current);
    current = 1;
    f1=LOW;
  }
  if(f2==HIGH){
    tofloor(2, current);
    current = 2;
    f2=LOW;
  }
  if(f3==HIGH){
    tofloor(3, current);
    current = 3;
    f3=LOW;
  }
  if(f4==HIGH){
    tofloor(4, current);
    current = 4;
    f4=LOW;
  }
  returnfloor();
}


void returnfloor() {
  if(current==1){
    digitalWrite(10,HIGH);
    delay(hold);
    return;
  }
  if(current>1){
    while(current>=1){
      current = current-1;
      switchfloor(current);
      delay(timer);
      
    }
  }current = current +1;
}

It seems like it always lights up all LED’s in sequence (1-4) no matter which button i press

So you push a button (e.g. A4) and interrupt fires.
You check the states
A4 is LOW so f1 is not affected
A3, A2 and A1 are HIGH so f2, f3 and f4 will be set to HIGH.

You have to redesign your logic a little :wink: