Interrupt not working correctly

Im trying to make an elevator like project, with a remote controller. It has two limit switches one at the top and one at the bottom.
Each time the controller is pressed the elevator should stop or go in the opposite direction it was going before stopping.
Im having trouble with the interrupts, it looks like the interrupts are getting triggered all at once, I tried separating the interrupt functions, defining debounce functions, doing the on off thing on the loop function, but can't get it to work properly. Does someone know what can I do? I'm doing it on an arduino nano every.
What I've found is that all the interrupts are getting triggered at the same time, each time I press the button on the remote and trigger the remote interrupt, the functions for the other interrupts are triggered too.
Please someone help me! :sob:

Here is the code I have:

const int limitSwitchTopPin = 8;
  const int limitSwitchDownPin = 7;
  const int remoteInput = 2;
  
  volatile int goUpOutput = 9;
  volatile int goDownOutput = 4;

  int stoppedState = 0;
  int goingUpState = 1;
  int goingDownState = 2;

  volatile int currentState = stoppedState;
  volatile int previousState = goingDownState;


void setup() {
  // put your setup code here, to run once:
    
    //INPUTS
    pinMode(limitSwitchTopPin, INPUT_PULLUP);
    pinMode(limitSwitchDownPin, INPUT_PULLUP);
    pinMode(remoteInput, INPUT_PULLUP);

    //OUTPUTS
    pinMode(goUpOutput, OUTPUT);
    pinMode(goDownOutput, OUTPUT);

//    INTERRUPTS
    attachInterrupt(digitalPinToInterrupt(limitSwitchTopPin), interruptFnc, FALLING);
    attachInterrupt(digitalPinToInterrupt(limitSwitchDownPin), interruptFnc, FALLING);
    attachInterrupt(digitalPinToInterrupt(remoteInput), interruptFnc, FALLING);

}

void limitSwitchTopFnc(){
  
    currentState = stoppedState;
    previousState = goingUpState;
    
  }

void limitSwitchBotFnc(){
   
    currentState = stoppedState;
    previousState = goingDownState;
}

void remoteButtonFnc(){  

  if(currentState != stoppedState){
      previousState = currentState;
      currentState = stoppedState;
   }
   else {
      if(previousState == goingDownState){
          previousState = stoppedState;
          currentState = goingUpState;
       }
       else if(previousState == goingUpState){
          previousState = stoppedState;
          currentState = goingDownState;
       }
    }
}

 
void interruptFnc(){
  
    bool topLimitState = digitalRead(limitSwitchTopPin);
    bool botLimitState = digitalRead(limitSwitchDownPin);
    bool remoteLimitState = digitalRead(remoteInput);
    if(!remoteLimitState){
      remoteButtonFnc();
    }

    else if(!topLimitState){
      limitSwitchTopFnc();
    }

    else if(!botLimitState){
      limitSwitchBotFnc();
    }
    
    
}

void loop() {
  if(currentState == stoppedState){
    digitalWrite(goUpOutput, LOW);
    digitalWrite(goDownOutput, LOW);
  }
  else if(currentState == goingUpState){
    digitalWrite(goUpOutput, HIGH);
    digitalWrite(goDownOutput, LOW);
  }
  else if(currentState == goingDownState){
    digitalWrite(goUpOutput, LOW);
    digitalWrite(goDownOutput, HIGH);
  }

}

Can you please edit your opening post, select all code and click the </> button to apply code tags and next save your post. It makes it easier to read, easier to copy and prevents the forum software from incorrect interpretation of the code.

1 Like

Look up this function to see which pins on a Nano can be used.

It says all pins are available on the nano every

Which one is it, a Nano or a Nano Every?

The nano every, sorry

To start with, interrupts are not needed for this. Just reading the switches in loop() will do the job. Is there any reason why ou want to use interrupts?

Further, I suspect that bouncing of yourlimit switches / button causes the problem.

On a side note, for this project till now, you only need one pin and you can connect the limit switches / button to the same pin.

The problem is that i haven't even connected the limit switches, the pins are connected to a pull up resistor :upside_down_face:, im only using the remote controller on a pin, and when I action it, all the interrupts are dispatched.
I'll try again only with the loop function, the initial problem was that sometimes when I clicked the button on the controller, the loop function didn't read the input.

Hello
In short words:

  1. If (remote) -> lift up
  2. If (limit) -> lift stopp
  3. If (remote) -> lift down
  4. If (limit) -> lift stopp
  5. and so on.

When this description match to your needs the following software modules are required:

  1. input scan
  2. derive values for motor control
  3. run motor control

All these software modules can be realizied w/o using interrrupt business. Take a piece of paper and a pencil and design a flow diagram before to do a redesign of your sketch.

How do you determine that? You use the same ISR for all three interrupts.

But as already mentioned, there is no need to use an interrupt in this project.

Since you have separate interrupts for the three pins, it makes sense to use separate ISR's rather than running them all through the same ISR.

const byte limitSwitchTopPin = 8;
const byte limitSwitchBottomPin = 7;
const byte remoteInput = 2;

const byte goUpOutput = 9;
const byte goDownOutput = 4;

enum States {StoppedState, GoingUpState, GoingDownState};

volatile States currentState = StoppedState;
volatile States previousState = GoingDownState;

void setup()
{
  // put your setup code here, to run once:

  //INPUTS
  pinMode(limitSwitchTopPin, INPUT_PULLUP);
  pinMode(limitSwitchBottomPin, INPUT_PULLUP);
  pinMode(remoteInput, INPUT_PULLUP);

  //OUTPUTS
  pinMode(goUpOutput, OUTPUT);
  pinMode(goDownOutput, OUTPUT);

  // Initial states
  currentState = StoppedState;

  if (digitalRead(limitSwitchTopPin) == LOW) // At Top
    previousState = GoingUpState;

  if (digitalRead(limitSwitchBottomPin) == LOW) // At Bottom
    previousState = GoingDownState;

  //    INTERRUPTS
  attachInterrupt(digitalPinToInterrupt(limitSwitchTopPin), limitSwitchTopISR, FALLING);
  attachInterrupt(digitalPinToInterrupt(limitSwitchBottomPin), limitSwitchBottomISR, FALLING);
  attachInterrupt(digitalPinToInterrupt(remoteInput), remoteButtonISR, FALLING);
}

void limitSwitchTopISR()
{
  currentState = StoppedState;
  previousState = GoingUpState;
}

void limitSwitchBottomISR()
{
  currentState = StoppedState;
  previousState = GoingDownState;
}

void remoteButtonISR()
{
  // If moving, stop
  if (currentState != StoppedState)
  {
    previousState = currentState;
    currentState = StoppedState;
  }
  else
  {
    // Currently stopped, reverse direction
    if (previousState == GoingDownState)
    {
      previousState = StoppedState;
      currentState = GoingUpState;
      // If we were stopped at the top, go down instead
      if (digitalRead(limitSwitchTopPin) == LOW) // At Top
        currentState = GoingDownState;
    }
    else if (previousState == GoingUpState)
    {
      previousState = StoppedState;
      currentState = GoingDownState;
      // If we were stopped at the bottom, go up instead
      if (digitalRead(limitSwitchBottomPin) == LOW) // At Top
        currentState = GoingUpState;
    }
  }
}

void loop()
{
  switch (currentState)
  {
    case StoppedState:
      digitalWrite(goUpOutput, LOW);
      digitalWrite(goDownOutput, LOW);
      break;

    case GoingUpState:
      digitalWrite(goUpOutput, HIGH);
      digitalWrite(goDownOutput, LOW);
      break;

    case GoingDownState:
      digitalWrite(goUpOutput, LOW);
      digitalWrite(goDownOutput, HIGH);
      break;
  }
}

I tried programing a pic12f629, and im having the same issues.
I found that it works find before connecting 120AC to the board on the relays, I think i'm having interference issues, i'll try using relay modules that have optocouplers integrated to see if that fixes the problem. :grinning_face_with_smiling_eyes:
Thanks everybody for your comments!

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