# Arduino Motion Sensor activated prop controls



## insomniac (Oct 15, 2012)

Thought I would add my test code for 2 working PIR sensors (all that I have right now). Maybe it will help someone that is playing with arduino right now...


```
/*
* Switch and LED PIR relay solenoid activation
 */

const int ledPin = 13; // LED is connected to pin 13 (for testing, solenoid on final version)
const int pir1 = 3;  // PIR1
const int pir2 = 4;  // PIR2
const int pir3 = 5;  // PIR3
const int pir4 = 6;  // PIR4
const int pir5 = 7;  // PIR5
const int pir6 = 8;  // PIR6
const int relay1 = 12;   // output to relay pin 12
const int relay2 = 11;   // output to relay pin 11
const int relay3 = 10;   // output to relay pin 10
const int relay4 = 9;   // output to relay pin 9
long previousMillis1 = 0; 
long previousMillis2 = 0; 
long previousMillis3 = 0; 
long previousMillis4 = 0; 
long interval1 = 15000;
long interval2 = 15000;
long interval3 = 15000;
long interval4 = 15000;


void setup() 
{
  pinMode(ledPin, OUTPUT); // Set the LED pin as output
  pinMode(pir1, INPUT);
  pinMode(pir2, INPUT);
  pinMode(pir3, INPUT);
  pinMode(pir4, INPUT);
  pinMode(pir5, INPUT);
  pinMode(pir6, INPUT);
  pinMode(relay1, OUTPUT); // relay1
  pinMode(relay2, OUTPUT); // relay2
  pinMode(relay3, OUTPUT); // relay3
  pinMode(relay4, OUTPUT); // relay4
}


void loop()
{
  int sensor_1 = digitalRead(pir1);
  int sensor_2 = digitalRead(pir2);
  int sensor_3 = digitalRead(pir3);
  int sensor_4 = digitalRead(pir4);
  int sensor_5 = digitalRead(pir5);
  int sensor_6 = digitalRead(pir6);
  unsigned long currentMillis1 = millis();

  if (sensor_1 == HIGH)
  {  
    if(currentMillis1 - previousMillis1 > interval1)
    {
      previousMillis1 = currentMillis1;   
      digitalWrite(relay1, HIGH); // activate solenoid
      delay(750);
      digitalWrite(relay1, LOW); // deactivate solenoid
    }
  }

  if (sensor_2 == HIGH)
  {
    if(currentMillis1 - previousMillis2 > interval2)
    { 
      previousMillis2 = currentMillis1;   
      digitalWrite(relay2, HIGH); // activate power
      delay(15000);
      digitalWrite(relay2, LOW); // deactivate power
    }
  }
}
```


----------



## jpbaily1 (Sep 21, 2009)

Very cool. I wish that I had the ability to do this.

Thanks for sharing.


----------



## insomniac (Oct 15, 2012)

Thanks. You would be surprised just how easy this stuff is to do. Most people are intimidated by stuff like this becuase they feel that they would be all alone in figuring it out. Luckily for us, we have this great forum with what seems to be a lot of helpful people that could help us out 



jpbaily1 said:


> Very cool. I wish that I had the ability to do this.
> 
> Thanks for sharing.


----------



## insomniac (Oct 15, 2012)

I modified the code to support clean*ish loops that will not be affected by independant delays that you set to each sensor.

A brief explanation of how you would modify prop delays, etc:

If you want sensor1 to only be allowed to be triggered every 20 seconds, you would change the existing code from "long interval1 = 15000;" to "long interval1 = 20000;"

If you wanted sensor2 to only be allowed to be triggered every 10 seconds, you would change the existing code from "long interval2 = 5000;" to "long interval2 = 10000;"

If you want your prop to stay on for "X" period of time, you would do this with the delay variables. So to keep prop1 on for 20 seconds, then turn off, you would change the existing code from "long delayinterval1 = 750;" to "long delayinterval1 = 20000;

etc....

No need to change any of the code below the void setup() section, unless you need to add more relays, need to change the characteristics a bit (leave them on and then turn them off for a period of time, etc).



```
/*
* Switch and LED PIR relay solenoid activation
 */

const int ledPin = 13; // LED is connected to pin 13 (for testing, solenoid on final version)
const int pir1 = 3;  // PIR1
const int pir2 = 4;  // PIR2
const int pir3 = 5;  // PIR3
const int pir4 = 6;  // PIR4
const int pir5 = 7;  // PIR5
const int pir6 = 8;  // PIR6
const int relay1 = 12;   // output to relay pin 12
const int relay2 = 11;   // output to relay pin 11
const int relay3 = 10;   // output to relay pin 10
const int relay4 = 9;   // output to relay pin 9
long previousMillis1 = 0; 
long previousMillis2 = 0; 
long previousMillis3 = 0; 
long previousMillis4 = 0; 
long interval1 = 15000;
long interval2 = 5000;
long interval3 = 15000;
long interval4 = 15000;
long delayinterval1 = 750;
long delayinterval2 = 6000;
long delayinterval3 = 6000;
long delayinterval4 = 6000;
long previousdelay1 = 0;
long previousdelay2 = 0;
long previousdelay3 = 0;
long previousdelay4 = 0;

void setup() 
{
  pinMode(ledPin, OUTPUT); // Set the LED pin as output
  pinMode(pir1, INPUT);
  pinMode(pir2, INPUT);
  pinMode(pir3, INPUT);
  pinMode(pir4, INPUT);
  pinMode(pir5, INPUT);
  pinMode(pir6, INPUT);
  pinMode(relay1, OUTPUT); // relay1
  pinMode(relay2, OUTPUT); // relay2
  pinMode(relay3, OUTPUT); // relay3
  pinMode(relay4, OUTPUT); // relay4
}


void loop()
{
  int sensor_1 = digitalRead(pir1);
  int sensor_2 = digitalRead(pir2);
  int sensor_3 = digitalRead(pir3);
  int sensor_4 = digitalRead(pir4);
  int sensor_5 = digitalRead(pir5);
  int sensor_6 = digitalRead(pir6);
  unsigned long currentMillis1 = millis();
  unsigned long currentMillis2 = millis();
  unsigned long currentMillis3 = millis();
  unsigned long currentMillis4 = millis();
  unsigned long delay1 = millis();
  unsigned long delay2 = millis();
  unsigned long delay3 = millis();
  unsigned long delay4 = millis();
  int relayState1 = digitalRead(relay1);
  int relayState2 = digitalRead(relay2);
  int relayState3 = digitalRead(relay3);
  int relayState4 = digitalRead(relay4);

  if ((relayState1 == HIGH) && (delay1 - previousMillis1 > delayinterval1))
  {
    digitalWrite(relay1, LOW); // de-activate solenoid
  }

  if ((relayState1 == LOW) && (sensor_1 == HIGH) && (currentMillis1 - previousMillis1 > interval1))
  {
    previousMillis1 = currentMillis1;
    digitalWrite(relay1, HIGH); // activate solenoid
  }

  if ((relayState2 == HIGH) && (delay2 - previousMillis2 > delayinterval2))
  {
    digitalWrite(relay2, LOW); // de-activate solenoid
  }

  if ((relayState2 == LOW) && (sensor_2 == HIGH) && (currentMillis2 - previousMillis2 > interval2))
  { 
    previousMillis2 = currentMillis2;   
    digitalWrite(relay2, HIGH); // activate solenoid
  }
}
```
Now that I've gotten my feet wet in C+ and arduino, I cannot wait until I have more time next year. It's just too much fun writing logic for props (yes, I know im sick..). I already have more relay boards on the way...


----------



## jchauntedfl (Apr 13, 2012)

Ok here's my issue I have above code working but want to have the relays turn off and on 2-3 times at different lengths of time when pir detects motion is there a way to add this to the code plz help my haunt depends on it
I have pneumatic valves on the relays and I would like them to go off a few times per trip of the pir then reset any help would be greatly appreciated


----------



## pir8p3t3 (Oct 24, 2012)

Not sure if this is what you are looking for but I pulled this off the Arduino playground. You should be able to add lines to the code for a delay. I cannot vouch for the syntax, but it should give you a good starting point. I did not write the code above that was insomniac. Just trying to help out since the post was almost a year ago. I think the section you would be worried about is after the void setup.

int ledPin = 13; // LED connected to digital pin 13

void setup()
{
pinMode(ledPin, OUTPUT); // sets the digital pin as output
}

void loop()
{
digitalWrite(ledPin, HIGH); // sets the LED on
delay(1000); // waits for a second
digitalWrite(ledPin, LOW); // sets the LED off
delay(1000); // waits for a second


----------



## CreepyCreations (Oct 16, 2011)

Interesting use for an Arduino. Depending on the use case, though, it seems like over kill. For the basic "let the PIR trigger the device, the not allow another trigerr event for so long", that can be accomplished with a couple of 555 timers and some simple gates. 1/10 the cost of an Arduino, and you can adjust the timing on-the-fly without having to reprogram every time. That's how I have most of my entire haunt running.

However, for more complex sequences, I could see where it could have its uses, such as multiple trigger events, etc.

My two cents' worth.


----------



## jchauntedfl (Apr 13, 2012)

Yes but unfortunately delay halts all actions on the arduino so all pirs reset when I use delay 
Thx for the quick reply
Delay is fine with one pir sensor but when there's more than 1 at a time it won't work 
Still messing with it but so far nada


----------



## jchauntedfl (Apr 13, 2012)

Yes I would be triggering multiple props and sounds with one arduino I have never messed with any other electronics 
I followed a guide and was having fun with arduino but ill check into 555timers thx


----------



## EviLEye (Oct 21, 2012)

Man, the timing of this thread and everyone talking about this type of project just goes to show there's more than one nut thinking about this stuff cause I've been staring at these options for the last couple of days.

Ironically I'm on the road right now but I brought with me my Arduino and bread board to code something like this up in the hotel. As well as I gathered a parts list from Creepy's windowed timer with the 555 chip with the intention of swinging by Frys/Radio Shack tonight to get the parts and build it as well.

A key problem with the arduino and why I'm not using it to control the whole haunt is that it can't multi-task. It can't handle multiple threads so this jams it up if you're trying to respond to multiple events and then insert delays. The delays (e.g. wait state with a counter) essentially takes the controller out of commission. I started playing with the idea of setting a variable and then using a run counter as the program loops through and then increment and check various variables. But this has become cumbersome versus just doing individual control at each prop with something like Tyler's board. 

Even if you want to still use the Arduino to manage and respond to input, I'd probably still use a 556 timer to insert a delay and avoid multiple repeated triggers from the PIR (e.g. see Creepy's facebook page for the 'windowed' timer circuit using 2 555 chips). I absolutely love the Arduino (built iphone controlled solar RC car) but it's a PIA in certain aspects due to limited memory and lack of multi-threading. I have the wireless 802.11 shield that gives you the ability to connect in ad-hoc mode, and the concept of total wireless access to control stuff is great, but the board can be a pain to work with as well.


----------



## CreepyCreations (Oct 16, 2011)

Thanks, EviLEye... I was going to suggest checking the Facebook page for the windowed timer circuit. It's been working great for our purposes. Maybe not as "cool" as an Arduino (don't get me wrong.. I have an Arduino and it's awesome). It's just not suited for applications beyond a "single thread". One trigger, one device, etc. The minute you dive into the multiple trigger/multiple device arena, you need multi-thread capability. You can probably fake it with enough code, but it would be painful to develop and troubleshoot.


----------



## pir8p3t3 (Oct 24, 2012)

I didn't even think about suggesting the 555 timer, i was just trying to give an idea. i am glad you guys were around to nudge him in a better direction. Not to mention I never thought about using the Arduino to trigger and the 555 to set the delays. That may actually solve a problem for me i have been having with a project i have been messing with. Thank you both.


----------



## mejess68 (Mar 24, 2012)

Awesome, in the passed I have used Basic Stamp for my haunt controllers and have just bought my first arduino, have not done any programing with it yet so I am glad you posted this. Have you integrated any sound with it yet? I've got a WTV020-SD Micro SD Card / mp3 / Game player voice module to use for my sound but have not gotten any code written yet (haven't found any good examples yet) I'm wanting to set up a pir sensor then switch on a relay for "x" amount of time and play my sound clip at the same time, then go into an all clear pause for "x" time and reset. If you've done any thing like this I would love to see the code. I am a complete newbe with arduino.


----------



## nonsense (Sep 18, 2010)

I'm currently setting up an Arduino to read a PIR sensor and start up my coffin lid motor. The speed of the motor and length of time it's on will be random (within set min/max parameters) to give it a little more realism. Once it's all programmed and working (it's 99% done now) I'll use the Arduino to program the code to a ATTiny85 microcontroller so my $30 Arduino can sit inside while my $1.30 microcontroller does the work outside in the cold. 

If the ATTiny isn't enough for your needs you could always use a ATMega8 or something similar programmed with the Arduino. Think of the Arduino as a rapid prototyping tool, the final product should be smaller and cheaper.


----------



## xcetera (Aug 25, 2013)

I really have to say this code helped me allot with my Arduino project controlling 8 PIR sensors and 8 relays 
Thanks!


----------



## EviLEye (Oct 21, 2012)

Thought I'd add a follow-up to this post.

I had a chance to put insomniac's code to use and it works great. His approach of just checking for the delta avoids bogging down the Arduino where you'd normally want to insert a delay. My current use of the Arduino is pretty basic and for one particular scene that senses motion with a PIR and then triggers a Spirit jumping spider, and then triggers my zombie hoard along with triggering Creepycreation's suggested sound board from 123Electronics. I'm using the footpad/press button inputs on the devices.

What killed the theory to reality implementation was how the props seemed to inconsistently trigger. Two ground breakers are exactly the same, but one will trigger immediately when the try me input is opened while the other one will not trigger until the relay closes. The Spirit spider also will not trigger until the input is closed. Easily done with a quick toggle of a relay, but my idea of simply tying everything together via one relay got kind of busted. I also think it might've been a floating ground scenario that caused weirdness.

What really makes this easy to manage is having a multiple relay board.

I picked this up through Amazon and got it in a few days:

8 channel dc 5v relay modulel









I think if you were going to watch multiple PIRs and then perform various functions within that operation (like turn on/off a solenoid with varying times) you could still use the same method of doing time checks for various deltas to turn on a relay and then turn it off as the Arduino loops through the main code.


----------



## xcetera (Aug 25, 2013)

Here is a picture of my setup this year. 

My Arduino Mega is just running on idle this year. 
The setup:8 PIR sensors connected to Arduino since Arduino understand 3.3V as high input. and when it senses High input it closes a relay on the little relay board. 
This relay board triggers the inputs on BooBox from Fright-Ideas (the BooBox are triggered with GND signal) 
BooBox then triggers the 16 ports relay board. 

The code I uses allow Arduino to sense multiple sensors "simultaneously" and that code is a copy from this thread


----------



## insomniac (Oct 15, 2012)

Whoa. First time coming back since last year. Im glad that the code seemed to help a few. For my uses, with multiple PIR, a footpad trigger, Air cannon, and soundbox it worked perfectly. I was very happy and proud to see it all work on Halloween night.

Unfortunately I wont be doing a haunt this year due to buying a new house and moving just a few weeks ago. Just too much to take on for me.

If anyone has any improvements, please share. I will be adding more for next year. I will running PIR sensored tracking which will candle light a walkway as people pass by. I think it should add a nice creepy effect!


----------



## insomniac (Oct 15, 2012)

Great setup!



xcetera said:


> Here is a picture of my setup this year.
> 
> My Arduino Mega is just running on idle this year.
> The setup:8 PIR sensors connected to Arduino since Arduino understand 3.3V as high input. and when it senses High input it closes a relay on the little relay board.
> ...


----------



## EviLEye (Oct 21, 2012)

insomniac said:


> If anyone has any improvements, please share. I will be adding more for next year. I will running PIR sensored tracking which will candle light a walkway as people pass by. I think it should add a nice creepy effect!


I didn't have time to really play around with all of the kewl ideas you could implement cause it was all I could do to just get my first haunt up and running. But I agree in that the lighted walkway would be pretty neat as well as there's just a ton of sensoring and feedback you could do.

One other item the arduino helped me on was the ability to act as if a try me button was being held down for an extended period of time while the Spirit voltage box went through its program. Otherwise someone has to manually flip the lever and the door comes popping open. Given I wanted it automated as well as the door has a mind of its own, I wanted to get away with remotely controlling just for the audio/light flashing action.

So the code helped in easily closing the relay, and after 28 seconds open it up after the voltage box completed its cycle.

Here's my adhoc build. I'm going to make sure to get it into an enclosure with screw blocks for next year.









Thanks again for the code.


----------



## insomniac (Oct 15, 2012)

No problem. Glad it helped. Looks like we will have something more to share next year (if we end up with enough free time to get a haunt together).



EviLEye said:


> I didn't have time to really play around with all of the kewl ideas you could implement cause it was all I could do to just get my first haunt up and running. But I agree in that the lighted walkway would be pretty neat as well as there's just a ton of sensoring and feedback you could do.
> 
> One other item the arduino helped me on was the ability to act as if a try me button was being held down for an extended period of time while the Spirit voltage box went through its program. Otherwise someone has to manually flip the lever and the door comes popping open. Given I wanted it automated as well as the door has a mind of its own, I wanted to get away with remotely controlling just for the audio/light flashing action.
> 
> ...


----------



## Funtient (Nov 1, 2013)

xcetera said:


> Here is a picture of my setup this year.
> 
> My Arduino Mega is just running on idle this year.
> The setup:8 PIR sensors connected to Arduino since Arduino understand 3.3V as high input. and when it senses High input it closes a relay on the little relay board.
> ...



Do you have links for your BooBox?


----------



## xcetera (Aug 25, 2013)

I just checks in on my projects from last year since it starts to be that time of the year again.


----------



## xcetera (Aug 25, 2013)

I also notice the post asking for a link to the BooBox is old, but i put a link here anyway since maybe some others need it. 
http://www.frightprops.com/controll...llers/boobox-controllers/boobox-flex-max.html

(have to split up my post since the forum did not let me post a link....)


----------



## daford (Aug 30, 2016)

*Electronic delay*

Just to add some additional delay options to this older thread. Instead of trying to build delays into the code you could use a delay module. I have a behind the grave popup monster running off the simply motion sensor. To prevent the prop from popping up over and over I added a delay component. They can be found on Amazon and other sites by looking for Power-Supply-Adjustable-Trigger-Module. They typically can delay from 1 second to 1 hour. I set mine to two minutes. So the prop only popped up for new unsuspecting people or re-scarred the lingering ones.


----------



## insomniac (Oct 15, 2012)

I've been out of the Halloween mix for a few years, and started setting up props today. I realized that my last program that I used for my air cannon, as well as step lighting was broken. Anyway, I came back to look at the code i posted and found what was wrong. I was using variables from the first prop for the second prop by accident. Too quick to copy and paste i suppose. So if anyone was having problems with my code, here is working code for 2 props and the framework for 4 props:


```
/*
* Switch and LED PIR relay solenoid activation
 */

const int ledPin = 13; // LED is connected to pin 13 (for testing, solenoid on final version)
const int pir1 = 3;  // PIR1
const int pir2 = 4;  // PIR2
const int pir3 = 5;  // PIR3
const int pir4 = 6;  // PIR4
const int pir5 = 7;  // PIR5
const int pir6 = 8;  // PIR6
const int relay1 = 12;   // output to relay pin 12
const int relay2 = 11;   // output to relay pin 11
const int relay3 = 10;   // output to relay pin 10
const int relay4 = 9;   // output to relay pin 9
long previousMillis1 = 0; 
long previousMillis2 = 0; 
long previousMillis3 = 0; 
long previousMillis4 = 0; 
long interval1 = 15000;
long interval2 = 15000;
long interval3 = 15000;
long interval4 = 15000;


void setup() 
{
  pinMode(ledPin, OUTPUT); // Set the LED pin as output
  pinMode(pir1, INPUT);
  pinMode(pir2, INPUT);
  pinMode(pir3, INPUT);
  pinMode(pir4, INPUT);
  pinMode(pir5, INPUT);
  pinMode(pir6, INPUT);
  pinMode(relay1, OUTPUT); // relay1
  pinMode(relay2, OUTPUT); // relay2
  pinMode(relay3, OUTPUT); // relay3
  pinMode(relay4, OUTPUT); // relay4
}


void loop()
{
  int sensor_1 = digitalRead(pir1);
  int sensor_2 = digitalRead(pir2);
  int sensor_3 = digitalRead(pir3);
  int sensor_4 = digitalRead(pir4);
  int sensor_5 = digitalRead(pir5);
  int sensor_6 = digitalRead(pir6);
  unsigned long currentMillis1 = millis();
  unsigned long currentMillis2 = millis();
  unsigned long currentMillis3 = millis();
  unsigned long currentMillis4 = millis();

  if (sensor_1 == HIGH)
  {  
    if(currentMillis1 - previousMillis1 > interval1)
    {
      previousMillis1 = currentMillis1;   
      digitalWrite(relay1, HIGH); // activate solenoid
      delay(750);
      digitalWrite(relay1, LOW); // deactivate solenoid
    }
  }

  if (sensor_2 == HIGH)
  {
    if(currentMillis2 - previousMillis2 > interval2)
    { 
      previousMillis2 = currentMillis2;   
      digitalWrite(relay2, HIGH); // activate power
      delay(15000);
      digitalWrite(relay2, LOW); // deactivate power
    }
  }
}
```


----------



## insomniac (Oct 15, 2012)

Woohoo! While the above code did work, it still introduced minor delays to other props. I hadn't had the time to figure out the code to check deltas for delay times. This is now fully resolved. All props are now in real-time without arduino delay! 

The only things that you need to edit are Interval and PropOpenClose settings. They are labeled with small examples:

// set below variables to how often you will allow your prop to trigger. e.g. Prop 1 can only trigger every 5000 milliseconds (5 seconds).
long int interval1 = 5000;
long int interval2 = 10000;
long int interval3 = 15000;
long int interval4 = 15000;

// set below variables to how long you want to have your prop open. e.g. Prop 1 will open and close in 200 milliseconds
long Prop1OpenClose = 1000;
long Prop2OpenClose = 3000;
long Prop3OpenClose = 5000;
long Prop4OpenClose = 10000;

Here is the complete code:


```
/*
* Switch and LED PIR relay solenoid activation
 */

//you need to set your pinouts to wherever you have your sensors and relays. Or copy mine for testing.
const int ledPin = 13; // LED is connected to pin 13 (for testing, solenoid on final version)
const int pir1 = 3;  // PIR1
const int pir2 = 4;  // PIR2
const int pir3 = 5;  // PIR3
const int pir4 = 6;  // PIR4
const int pir5 = 7;  // PIR5
const int pir6 = 8;  // PIR6
const int relay1 = 12;   // output to relay pin 12
const int relay2 = 11;   // output to relay pin 11
const int relay3 = 10;   // output to relay pin 10
const int relay4 = 9;   // output to relay pin 9

// used for reference. Do not change.
long previousMillis1 = 0; 
long previousMillis2 = 0; 
long previousMillis3 = 0; 
long previousMillis4 = 0; 

//set prop open 
bool P1 = false;
bool P2 = false;
bool P3 = false;
bool P4 = false;

// set below variables to how often you will allow your prop to trigger. e.g. Prop 1 can only trigger every 5000 milliseconds (5 seconds).
long int interval1 = 5000;
long int interval2 = 10000;
long int interval3 = 15000;
long int interval4 = 15000;

// set below variables to how long you want to have your prop open. e.g. Prop 1 will open and close in 200 milliseconds
long Prop1OpenClose = 1000;
long Prop2OpenClose = 3000;
long Prop3OpenClose = 5000;
long Prop4OpenClose = 10000;


void setup() 
{
  pinMode(ledPin, OUTPUT); // Set the LED pin as output
  pinMode(pir1, INPUT);
  pinMode(pir2, INPUT);
  pinMode(pir3, INPUT);
  pinMode(pir4, INPUT);
  pinMode(pir5, INPUT);
  pinMode(pir6, INPUT);
  pinMode(relay1, OUTPUT); // relay1
  pinMode(relay2, OUTPUT); // relay2
  pinMode(relay3, OUTPUT); // relay3
  pinMode(relay4, OUTPUT); // relay4
}

//////////////////////////////////////////////////////////////////////////////////  Do not touch anything below this line!! ////////////////////////////////////////////////////////////////
void loop()
{
  int sensor_1 = digitalRead(pir1);
  int sensor_2 = digitalRead(pir2);
  int sensor_3 = digitalRead(pir3);
  int sensor_4 = digitalRead(pir4);
  int sensor_5 = digitalRead(pir5);
  int sensor_6 = digitalRead(pir6);

//if prop is closed
 if (sensor_1 == HIGH)
 {  
   if (!P1) Prop1();
 }
 if (sensor_2 == HIGH)
 {  
   if (!P2) Prop2();
 }
  if (sensor_3 == HIGH)
 {  
   if (!P3) Prop3();
 }
 if (sensor_4 == HIGH)
 {  
   if (!P4) Prop4();
 }
 
 //if prop is open
 if(P1) Prop1();
 if(P2) Prop2();
 if(P3) Prop3();
 if(P4) Prop4();
}


void Prop1(){
  long currentMillis1 = millis();
  if (!P1)
  {
      if(currentMillis1 - previousMillis1 > interval1)
      {
        previousMillis1 = currentMillis1; 
        digitalWrite(relay1, HIGH); // activate Prop1
        P1 = true;
      }
  }
  else
  {
    if (currentMillis1 - previousMillis1 >= Prop1OpenClose)
    {
      digitalWrite(relay1, LOW); // deactivate Prop1
      P1 = false;
    }
  }
}

void Prop2(){
  long currentMillis2 = millis();
  if (!P2)
  {
      if(currentMillis2 - previousMillis2 > interval2)
      {
        previousMillis2 = currentMillis2; 
        digitalWrite(relay2, HIGH); // activate Prop2
        P2 = true;
      }
  }
  else
  {
    if (currentMillis2 - previousMillis2 >= Prop2OpenClose)
    {
      digitalWrite(relay2, LOW); // deactivate Prop2
      P2 = false;
    }
  }
}

void Prop3(){
  long currentMillis3 = millis();
  if (!P3)
  {
      if(currentMillis3 - previousMillis3 > interval3)
      {
        previousMillis3 = currentMillis3; 
        digitalWrite(relay3, HIGH); // activate Prop3
        P3 = true;
      }
  }
  else
  {
    if (currentMillis3 - previousMillis3 >= Prop3OpenClose)
    {
      digitalWrite(relay3, LOW); // deactivate Prop3
      P3 = false;
    }
  }
}

void Prop4(){
  long currentMillis4 = millis();
  if (!P4)
  {
      if(currentMillis4 - previousMillis4 > interval4)
      {
        previousMillis4 = currentMillis4; 
        digitalWrite(relay4, HIGH); // activate Prop4
        P4 = true;
      }
  }
  else
  {
    if (currentMillis4 - previousMillis4 >= Prop4OpenClose)
    {
      digitalWrite(relay4, LOW); // deactivate Prop4
      P4 = false;
    }
  }
}
```
Anyone that was using my old code should switch to this immediately. There is no comparison


----------

