Read digital input XX sec. after a loop has finished

Hi everyone

I have a setup with two PIR motion sensors and four relays.
Sensor 1 controls relay 1 and 2.
Sensor 2, relay 3 and 4.

When sensor 1 (or 2) has been activated, the loop is running and when the loop is at the end, I would like to ignore any digital reads from the motion sensor 1 for one minute or so.

I have Googled and have tried to mess with StateMachine, TimeMachine, Timer Interrups, but with no useful outcome, so I think I'm approaching this in the wrong way.

Any suggestions on how I do it?

I'm not an expert in coding and I hope you can help me.

The sketch I'm working on and I want to add the "timer" on sensor inputs:



#define potPin4 A3      // Time 1 
#define potPin5 A4      // Time 2 

#define pirPin1 2       // PIR 1 sensor 
#define pirPin2 3       // PIR 2 sensor 

const int relayPin1 = 9;    // Blower 1 (Relay for AC 220V)
const int relayPin2 = 10;    // Blower 2 (Relay for AC 220V)
const int relayPin3 = 11;    // Valve 1 (Relay for DC 12V)
const int relayPin4 = 12;    // Valve 2 (Relay for DC 12V)

int pirState1 = LOW;
int pirState2 = LOW;

int relayValue1 = 0;
int relayValue2 = 0;
int relayValue3 = 0;
int relayValue4 = 0;

int relayState1 = 0;
int relayState2 = 0;
int relayState3 = 0;
int relayState4 = 0;
int val = 0;

#define pirType1 'L' // PIR trigger type. L for low and H for high
#define pirType2 'L' // PIR trigger type. L for low and H for high

#define relayType1 'L' // Relay trigger type. L for low and H for high
#define relayType2 'L' // Relay trigger type. L for low and H for high
#define relayType3 'L' // Relay trigger type. L for low and H for high
#define relayType4 'L' // Relay trigger type. L for low and H for high

const long maxTime1 = 30000;// maximum timer time in milliseconds. for one minute =60000, 1 hours =3600000
const long minTime1 = 3000; // miniimum timer time in milliseconds
const long maxTime2 = 30000;// maximum timer time in milliseconds. for one minute =60000, 1 hours =3600000
const long minTime2 = 3000; // miniimum timer time in milliseconds


long duration1;
long duration2;
long duration3;
long duration4;
int potValue4;
int potValue5;
long rememTime1;
long rememTime2;
long rememTime3;
long rememTime4;


void setup()
{
  Serial.begin(115200);// initialize serial monitor with 9600 baud

  pinMode(pirPin1, INPUT);     // PIR Input
  pinMode(pirPin2, INPUT);     // PIR Input
  pinMode(relayPin1, OUTPUT);  //Relay for BLOWER 1
  pinMode(relayPin2, OUTPUT);  //Relay for BLOWER 2
  pinMode(relayPin3, OUTPUT);  //Relay for VALVE 1
  pinMode(relayPin4, OUTPUT);  //Relay for VALVE 2


  if (pirType1 == 'L')
  {
    digitalWrite(relayPin1, LOW);// turn the OFF and keep it OFF
  } else {
    digitalWrite(relayPin1, HIGH);// turn the relay OFF and keep it OFF
  }

  if (pirType2 == 'L')
  {
    digitalWrite(relayPin2, LOW);// turn the OFF and keep it OFF

  } else {
    digitalWrite(relayPin2, HIGH);// turn the relay OFF and keep it OFF
  }

  if (relayType1 == 'L')
  {
    digitalWrite(relayPin1, HIGH);// turn the relay OFF and keep it OFF
  } else {
    digitalWrite(relayPin1, LOW);// turn the relay OFF and keep it OFF
  }

  if (relayType2 == 'L')
  {
    digitalWrite(relayPin2, HIGH);// turn the relay OFF and keep it OFF
  } else {
    digitalWrite(relayPin2, LOW);// turn the relay OFF and keep it OFF
  }

  if (relayType3 == 'L')
  {
    digitalWrite(relayPin3, HIGH);// turn the relay OFF and keep it OFF
  } else {
    digitalWrite(relayPin3, LOW);// turn the relay OFF and keep it OFF
  }

  if (relayType4 == 'L')
  {
    digitalWrite(relayPin4, LOW);// turn the relay OFF and keep it OFF
  } else {
    digitalWrite(relayPin4, HIGH);// turn the relay OFF and keep it OFF
  }
}

void loop() {
  {
    potValue4 = analogRead(potPin4) / 2;  // reads the value of the potentiometer (value between 0 and 1023)
    duration1 = map(potValue4, 0, 102, minTime1, maxTime1);// convert A0 value to time set at minTime and maxTime
    if (digitalRead(pirPin1) == HIGH)
    {
      rememTime1 = millis();
      relayState1 = 1;
      controlRelay1();// send command to turn the relay ON
    }
    if (  (millis() - rememTime1) > duration1 )
    {
      relayState1 = 0;
      controlRelay1();
    }
  }

  potValue5 = analogRead(potPin5) / 2;  // reads the value of the potentiometer (value between 0 and 1023)
  duration2 = map(potValue5, 0, 102, minTime2, maxTime2);// convert A0 value to time set at minTime and maxTime
  if (digitalRead(pirPin2) == HIGH)
  {
    rememTime2 = millis();
    relayState2 = 1;
    controlRelay2();// send command to turn the relay ON
  }
  if (  (millis() - rememTime2) > duration2 )
  {
    relayState2 = 0;
    controlRelay2();
  }
}



void controlRelay1() {
  if (pirType1 == 'L')
  {
    if (relayState1 == 1)
    {
      digitalWrite(relayPin1, LOW); // turn OFF RELAY Blower 1
      digitalWrite(relayPin3, HIGH); // turn OFF RELAY Valve 1

    } else {
      digitalWrite(relayPin1, HIGH);// Turn ON RELAY Blower 1
      digitalWrite(relayPin3, LOW);// Turn ON RELAY Valve 1
    }
  }
}


void controlRelay2() {
  if (pirType2 == 'L')
  {
    if (relayState2 == 1)
    {
      digitalWrite(relayPin2, LOW); // turn OFF RELAY Blower 1
      digitalWrite(relayPin4, HIGH); // turn OFF RELAY Valve 1

    } else {
      digitalWrite(relayPin2, HIGH);// Turn ON RELAY Blower 1
      digitalWrite(relayPin4, LOW);// Turn ON RELAY Valve 1
    }
  }

Hmmm. You're testing the PIR type and then setting a RELAY pin? Are you sure this isn't a cut and paste error? Especially as you set the same RELAY pin later.

  if (relayType1 == 'L')
  {
    digitalWrite(relayPin1, HIGH);// turn the relay OFF and keep it OFF
  } else {
    digitalWrite(relayPin1, LOW);// turn the relay OFF and keep it OFF
  }

You have extraneous braces {} in your code that adds confusion.
You have no state change detection on your PIR code.
Your timing logic (using millis() ) is very confusing and not documented.
You have used 'long' variables for time stamps, they must be 'unsigned long' to work properly.
You have identical code for relay1 and relay2, it should be factored using arrays and for loops.
The code you posted isn't complete, it won't compile.

But, the most difficult aspect of solving this problem with you, is that there is no complete description of how it should operate. Without that, it's nearly impossible to interpret your description of what you want to achieve (which also needs to be fleshed out considerably).

Well, there is definitely room for improvement in my code.
But it is acutually working as it is right now.

If I write unsigned in front of long, would that be OK?

try it

You say you are aware that the program needs some improvements. It would be much wiser to make those improvements before you make additions to it. It's especially important now that you're sharing it and asking for help. In particular, the lack of inline and/or external documentation makes it difficult for third parties to work with it.

Thanks, I really apprecitate your comments and I don't hope you are giving up on me.

@paulpaulson I will try it out.
@anon57585045 As I mentioned, I'm not an expert and therefore I wasn't aware of the problems with my code, because I made it do what I want it to do.

If we disregards my previous code.
How would you folks then ignore the sensor input on pin 2 for a minute after the loop has executed and then again listen to the input?

Can I do that in this loop or can you suggest a better way to do it?

void controlRelay1() {
  if (pirType1 == 'L')
  {
    if (relayState1 == 1)
    {
      digitalWrite(relayPin1, LOW); 
      digitalWrite(relayPin3, HIGH); 

    } else {
      digitalWrite(relayPin1, HIGH);
      digitalWrite(relayPin3, LOW);
    }
  }
}

Sorry, I think I forgot this:
The code, that call the controlRelay1:

void loop() {
  {

    //######## TIMER 1 Blower 1 and Valve 1 #########
    potValue4 = analogRead(potPin4) / 2;  // reads the value of the potentiometer (value between 0 and 1023)
    duration1 = map(potValue4, 0, 102, minTime1, maxTime1);// convert A0 value to time set at minTime and maxTime
    if (digitalRead(pirPin1) == HIGH)
    {
      rememTime1 = millis();
      relayState1 = 1;
      controlRelay1();// send command to turn the relay ON
    }
    if (  (millis() - rememTime1) > duration1 )
    {
      relayState1 = 0;
      controlRelay1();
    }

    //Serial.print("Time Blower 1 and Valve 1 : ");
    //Serial.print(duration1 / 1000);
    //Serial.println(" Seconds");
    //delay(200); // wait for 200 milliseconds

  }

If I didn't have to do anything else during that time period, I would:

delay(1000L * 60);

@anon57585045

If I didn't have to do anything else during that time period, I would:

delay(1000L * 60);

It must be possible to run the second sensor. Therefore I ask how about to fix it.

Then you would use millis() to implement a round robin multitasking, "more than one thing at a time" as shown in the BlinkWithoutDelay example that ships with the IDE. I've given my reasons why you would probably be doing that without help.

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