Interrupt condition not working

Hi Brains trust.

I am relatively new to Arduino. This is my second project.

I am trying to setup a relay timer where the trigger switch can be used to both initiate the timer and activate the relay, as well as reset the relay and turn it off if required. Currently I have the duration set to 10sec, but in my live environment it will be 5 minutes. Hence the requirement to reset / manually turn off the relay.

Currently I have the initial trigger of the interrupt working perfectly. But the reset function is not working at all. Below is my code. Any help is welcomed.

#define relayPin 2 // the pin relay is connected
#define triggerPin 3 // the pin where start switch is connected

long triggerTime = 0;
int duration = 10000;
volatile byte relayState;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);// initialize serial monitor with 9600 baud
  pinMode(relayPin, OUTPUT);
  digitalWrite(relayPin, LOW);
  pinMode(triggerPin, INPUT);
  attachInterrupt(digitalPinToInterrupt(triggerPin), trigger, RISING);
  Serial.println("Routine Begin");
}

void loop() {
  // put your main code here, to run repeatedly:
  if( (millis() - triggerTime) > duration && relayState == HIGH)
    {
      controlRelay();
      Serial.print("Time - ");
      Serial.println(millis() - triggerTime);
      triggerTime = 0;
    }
  else
    {
      delay(50);
    }
}// loop end

 void trigger()
 {
    if(relayState == HIGH)
      {    
        controlRelay();
        Serial.println("Relay RESET");
        triggerTime = 0;
      }
    else
      {
        triggerTime = millis();
        controlRelay();
        Serial.print("Time - ");
        Serial.println(triggerTime / 1000); 
      }  
 }// trigger end

 void controlRelay()
 {
    if(relayState == HIGH)
      {
        digitalWrite(relayPin, LOW);
        relayState = LOW;
        Serial.println("Relay OFF");
      }
    else
      {
        digitalWrite(relayPin, HIGH);
        relayState = HIGH;
        Serial.println("Relay ON");
      }
 }

You shouldn’t do any serial prints inside interrupt routine

The interrupt service routine trigger() should simply set a flag that the interrupt occurred, and exit. All other actions are carried out by the main program.

That flag might be a volatile global variable set equal to 1, which is reset to zero when the main program finishes the intended action.

You have the triggerPin set as INPUT. That suggests you have the switch wired with one side connected to the trigger pin and the other to 5V. If the is the case, when the switch is pressed, the pin will go high but when you release the switch it will be floating unless you have a resistor attached which pulls it low.

Another way of hooking up a button is to tie the switch to the pin and Ground and then set the pin mode to INPUT_PULLUP. With that configuration the pin is HIGH when the switch is open and low when the switch is closed. You can then change your code to do whatever you want when it is High or LOW . Example: ```
attachInterrupt(digitalPinToInterrupt(triggerPin), trigger, FALLING);

Your sketch is working alright in my UNO; where, simulated realy (L at DPin-13) gets resetted wel.

Time - 9
Relay OFF
Relay RESET
Relay ON
Time - 9
Relay OFF
Relay RESET
Relay ON
Time - 9
Relay OFF
Time - 10010

Thanks @PickyBiker, I got it working with your solution. Also had to introduce some debounce code for the input.

Here's my final code for critique and / or assistance for anyone else with a similar situation. (PS, i still need to clean it up a bit and remove all the serialprint's I was using to assist with debugging.)

#define relayPin 2 // the pin relay is connected
#define triggerPin 3 // the pin where start switch is connected

long triggerTime = 0;
long duration = 300000;
volatile byte relayState;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);// initialize serial monitor with 9600 baud
  pinMode(relayPin, OUTPUT);
  digitalWrite(relayPin, LOW);
  pinMode(triggerPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(triggerPin), trigger, FALLING);
  Serial.println("Routine Begin");
}

void loop() {
  // put your main code here, to run repeatedly:
  if( (millis() - triggerTime) > duration && relayState == HIGH)
    {
      controlRelay();
      Serial.print("Time - ");
      Serial.println(millis() - triggerTime);
      triggerTime = 0;
    }
  else
    {
      delay(50);
    }
}// loop end

 void trigger()
 {
    static unsigned long last_interrupt_time = 0;
    unsigned long interrupt_time = millis();
    if (interrupt_time - last_interrupt_time > 300)
      {
        if(relayState == HIGH)
          {    
            controlRelay();
            Serial.println("Relay RESET");
            triggerTime = 0;
          }
        else
          {
            triggerTime = millis();
            controlRelay();
            Serial.print("Time - ");
            Serial.println(triggerTime / 1000); 
          }
      }
      last_interrupt_time = interrupt_time;  
 }// trigger end

 void controlRelay()
 {
    if(relayState == HIGH)
      {
        digitalWrite(relayPin, LOW);
        relayState = LOW;
        Serial.println("Relay OFF");
      }
    else
      {
        digitalWrite(relayPin, HIGH);
        relayState = HIGH;
        Serial.println("Relay ON");
      }
 }

Agreed, I was just using them to assist with debugging. Production code will not have these.

Glad it's working for you and thanks for the feedback.

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