Help with simple code please!

Hello all,

I am very new to this forum, as well as new to arduino (this project is on the Nano) and programming. I have this simple project I have been working on where essentially (as you will see from the code) I press a red button on my TV remote and I can turn a relay on, which works great. I can also hold any button down on the remote and turn the relay off, this works great too. The problem arises when I had wanted to add a PIR motion sensor.

My ultimate goal of the sensor was to have it to where I can press the green button on my remote and go into motion detection mode, but also be able to hold down any button and turn the relay off and go back to be able to use the red button from the beginning when necessary.

But as of now, the red button toggles the relay on and holding a button can toggle it off, and when I press the green button, it goes go into the "motion detection mode" (in the code I switch the relay a couple times just as an indicator). But once in this mode where the PIR is always searching and there is no way for me to hold a button down and turn the relay off without cutting the power to the arduino.

If someone could please help and guide me in coding some kind of interrupt or whatever I need to help fix this problem I would greatly appreciate it!

Cheers,

Adam

#include <IRremote.h>

int RECV_PIN = 11;
int relay = 10;
int val = 1;
int pir = 2;
int positive = 3;
int constant = 0;




IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn();
  pinMode(relay, OUTPUT);
  pinMode(pir, INPUT);
  pinMode(positive, OUTPUT);
  digitalWrite(positive, HIGH);
  //bool state = false;
  digitalWrite(relay, LOW);
  Serial.println("Starting...relay set to off.");
  
  
}

void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, DEC);

        if(results.value == 284101365){ //red button is pressed
        digitalWrite(relay, HIGH);
        Serial.println("Relay on!");
        delay(1000);
          }
          if(results.value == 4294967295){   //any button is being held down
            digitalWrite(relay, LOW);
            Serial.println("Relay off!");
          }

          if(results.value == 284134005) { //green button is pressed
            Serial.println("Entering motion detection mode!");
            digitalWrite(relay,HIGH);
            delay(250);
            digitalWrite(relay, LOW);
            delay(250);
            digitalWrite(relay,HIGH);
            delay(250);
            digitalWrite(relay, LOW);

            while(constant == 0){
            
            motion();

            
            
            }
           
          }
     
    
    irrecv.resume(); 
  }
  delay(400);
}

void motion(){ //motion detection mode
             
              val = digitalRead(pir);
              digitalWrite(relay, val);
              delay(100);
              if(val == 0){
                digitalWrite(relay, LOW);
                Serial.println("No motion detected and relay deactivated...");

              }
             
}
while(constant == 0){

Since nothing in the while loop will ever change constant, this is an infinite loop. And inside that loop you aren't doing anything with the remote.

Remember, the loop function is already looping for you. Checkjng the PIR doesn't need to be in a while loop. Just put a variable that dictates whether or not you want to run that section and put it in an if statement.

The trick is to keep track of when you are in "motion detect mode". Look for IR input every time through loop(). Act on the input depending on the mode:

    if (results.value == 4294967295) { //any button is being held down
      if (InMotionDetectMode) {
        InMotionDetectMode = false;
        Serial.println("Motion Detect Mode off!");
      }
      else {
        digitalWrite(relay, LOW);
        Serial.println("Relay off!");
      }
    }

Ohhh okay I think that makes sense now. I will give it a try, thank you both so much!