Interrupt clashing with Loop.

I'm trying to built a motion sensor light with an override switch. Override switch (push button) will turn on the LEDs permanently even if there's no motion, then another push will turn it back to previous state (motion sensing). I used interrupt for the switch (along with millis() for debouncing) and Loop for PIR. My problem is, when I push the button LEDs won't lit up, even though serial monitor prints "switched on". I don't think it's related to bouncing because serial monitor is printing just fine, and instead related to Loop which is also controlling those LEDs. Maybe it's possible to make another interrupt for motion sensor? Please help me.

const byte PIR_override = 3;         // push button pin
volatile boolean override = false;
int LED = 13;                // pin for the LED
int inputPin = 2;               // input pin for PIR sensor
int pirState = LOW;             // assuming no motion detected
int val = 0;                    // variable for reading the pin status
int DELVAR = 500;             // Delay in milliseconds
int override_state = LOW;      // the current state of the output pin

// set states for PIR override switch
int state = LOW;      // the current state of the output pin
int reading;           // the current reading from the input pin
int previous = HIGH;    // the previous reading from the input pin

///////////////////////////////////////////////////////
void setup() {
  pinMode(LED, OUTPUT);      // declare LED as output
  pinMode(inputPin, INPUT);     // declare sensor as input
  pinMode(PIR_override, INPUT);
  attachInterrupt(digitalPinToInterrupt(PIR_override), motionOverride, HIGH);
  Serial.begin(9600);
}


void loop() {
  if (!override)
  {
    val = digitalRead(inputPin);  // read PIR input value
    if (val == HIGH)  
    {
      digitalWrite(LED, HIGH);  // turn LED ON
    }
    else
    {
      digitalWrite(LED, LOW); // turn LED OFF
    }
  }
}
void motionOverride()
{
  static unsigned long last_interrupt_time = 0;
  unsigned long interrupt_time = millis();
  // If interrupts come faster than 400ms, assume it's a bounce and ignore
  if (interrupt_time - last_interrupt_time > 400)
  {
    if (override) // overriding motion and the button has been pressed - got to PIR mode
    {
      Serial.println("switched off");
      digitalWrite(LED, LOW);  // turn LED off
      override = false;               // set the override flag
    }
    else // not overriding motion and the button has been pressed - go to override mode
    {
      Serial.println("switched on");
      digitalWrite(LED, HIGH);  // turn LED on
      override = true;                // set the override flag
    }
  }
  last_interrupt_time = interrupt_time;
}

It is extremely unlikely that you will need an interrupt to detect a human pushing if your program is suitably organized. Humans are verrryyy slooooowwww.

Have a look at how the code is organized in Several Things at a Time

Note how each function runs very briefly and returns to loop() so the next one can be called. None of the functions tries to complete a task in one call. And there may be dozens of calls to a function before it is actually time for it to do anything.

By the way, the whole purpose of an interrupt is to clash with everything else :slight_smile:

...R

How is the switch wired? Is there a pulldown resistor?

I think you want "RISING" and not "HIGH" for your interrupt condition.

const byte PIRInputPin = 2;               // input pin for PIR sensor
const byte OverrideButtonPin = 3;         // push button pin


volatile boolean Override = false;


///////////////////////////////////////////////////////
void setup() 
{
  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);      // declare LED as output
  pinMode(OverrideButtonPin, INPUT);     // declare sensor as input
  pinMode(PIRInputPin, INPUT);
  attachInterrupt(digitalPinToInterrupt(OverrideButtonPin), motionOverride, RISING);
}


void loop()
{
  boolean pirOn = digitalRead(PIRInputPin);


  digitalWrite(LED_BUILTIN, pirOn || Override );  // turn LED ON if PIR or Override
}


void motionOverride()
{
  static unsigned long last_interrupt_time = 0;
  unsigned long interrupt_time = millis();


  // If interrupts come faster than 400ms, assume it's a bounce and ignore
  if (interrupt_time - last_interrupt_time > 400)
  {
    // Toggle the override
    Override = !Override;
  }


  last_interrupt_time = interrupt_time;
}