# Need help with Arduino Mega 2560



## Cole&Jacksdad (Jan 20, 2011)

I'm using a Mega 2560 to control my props this year. When I upload the code I get this error message.
"Serial Port 'COM 4' not found. Did you select the right one from tools >serial port menu?"

When I click on the serial port option, nothing happens.
What am I doing wrong?


----------



## goneferal (Sep 8, 2010)

Did you make sure you loaded the correct driver? Does the arduino show up identified as such when you look at "my computer"?


----------



## Cole&Jacksdad (Jan 20, 2011)

goneferal said:


> Did you make sure you loaded the correct driver? Does the arduino show up identified as such when you look at "my computer"?


I'm not sure how to load up the correct driver and no it doesn't show up.


----------



## Cole&Jacksdad (Jan 20, 2011)

It does show up in documents.


----------



## Cole&Jacksdad (Jan 20, 2011)

I used an UNO last year and remember having the same issue. I just can't remember how it got fixed.


----------



## JeffHaas (Sep 7, 2010)

Here are the troubleshooting tips I'd go through:

1. Get the latest version of the Arduino software from their website and install it. http://www.arduino.cc/

2. Then plug in any Arduino you have with the USB cable. Start up the the Arduino software, and look on the Tools menu. Look at the Serial Port sub-menu. You should be able to see the serial port of the Arduino board listed there. It should have a checkmark next to it.

3. Look on the Tools menu, in the Board sub-menu. Make sure the right type of Arduino is checked.

4. Now try loading the Blink sketch to see if your computer can download a program to the Arduino and make the built-in LED blink. Go to this menu and sub-menus:

File > Examples > Basics > Blink

This will load up a new window with the Blink sketch. (You can check the Tools menu, this new window will get all the settings from the first window.) Now hit the Upload button and see if the Blink sketch downloads and makes the LED blink.


----------



## Cole&Jacksdad (Jan 20, 2011)

JeffHaas said:


> Here are the troubleshooting tips I'd go through:
> 
> 1. Get the latest version of the Arduino software from their website and install it. http://www.arduino.cc/
> 
> ...


I did all of that. The uno works fine, but the mega is not(bad controller?). When I plug in the uno, I hear the sound that you hear when you plug something in. When I plug the mega in, I hear a different sound which makes me think someing is wrong with the mega. I am able to load the basic blink code on the uno. I can't with the mega.


----------



## goneferal (Sep 8, 2010)

I don't have my setup here, but I could go over it with you when I'm done with work. I had the same issue when I went from Uno to Mega. The other thing is to make sure you have the Mega selected as your device in the software.


----------



## Cole&Jacksdad (Jan 20, 2011)

I had the mega selected. 
I orderd an uno(should be here Wed) just incase. If I can't get the mega working, I will run both uno's.


----------



## Cole&Jacksdad (Jan 20, 2011)

goneferal said:


> I don't have my setup here, but I could go over it with you when I'm done with work.


That would be great!


----------



## HomeyDaClown (Oct 3, 2009)

That is a common issue with 2560 Megas.

As soon as you plug in the 2560 you should see a virtual com port in device manager appear. It should appear without any warnings or errors.
The Arduino IDE is looking for that virtual port when it loads. The uno and other borads use the FTDI driver which always works fine, the Mega 2560 uses the common CDC drivers which Windows does not do a very good job emulating.

Try these solutions first:
http://arduino.cc/forum/index.php?topic=115010.0


----------



## Cole&Jacksdad (Jan 20, 2011)

Thanks everyone! My wife saved my butt and fixed it.


----------



## HomeyDaClown (Oct 3, 2009)

Cole&Jacksdad said:


> Thanks everyone! My wife saved my butt and fixed it.


What did she do? So now we know the real Arduino expert in the house.


----------



## Cole&Jacksdad (Jan 20, 2011)

HomeyDaClown said:


> What did she do? So now we know the real Arduino expert in the house.


She followed this
http://www.nerdonarock.com/2011/08/24/the-arduino-mega-2560-driver-not-found-win7/

But now I am having code issues.
The arduino keeps triggering all of the props.

Here is the code I wrote.

/*
* 2012 Haunt code
*/
int rat = 2; //rat strobe light is connected to pin 2
int morgue1 = 3; //morgue1 is connected to pin 3
int morgue2 = 4; //morgue2 is connected to pin 4
int morgue3 = 5; //morgue3 is connected to pin 5
int morgue4 = 6; //morgue4 is connected to pin 6
int coffin = 7; //coffin is connected to pin 7
int clownstrobe = 8; //clown strobe is conected to pin 8
int clownpop = 9; //clown pop is connected to pin 9
int dropstrobe = 10; //drop strobe is connected to pin 10
int dropdoor = 11; //drop door is connected to pin 11
int firecracker = 12; //firecracker is connected to pin 12
int PIR1 = 22; //PIR1 is connected to pin 22
int PIR2 = 23; //PIR2 is connected to pin 23
int PIR3 = 24; //PIR3 is connected to pin 24
int PIR4 = 25; //PIR4 is coneected to pin 25
int PIR5 = 26; //PIR5 is connected to pin 26
int PIR6 = 27; //PIR6 is connected to pin 27
int val; // variable for reading the pin status

void setup() {

pinMode(rat, OUTPUT); 
pinMode(morgue1, OUTPUT); 
pinMode(morgue2, OUTPUT);
pinMode(morgue3, OUTPUT);
pinMode(morgue4, OUTPUT);
pinMode(coffin, OUTPUT); 
pinMode(clownstrobe, OUTPUT);
pinMode(clownpop, OUTPUT);
pinMode(dropstrobe, OUTPUT);
pinMode(dropdoor, OUTPUT);
pinMode(firecracker, OUTPUT);
pinMode(PIR1, INPUT);
pinMode(PIR2, INPUT);
pinMode(PIR3, INPUT);
pinMode(PIR4, INPUT);
pinMode(PIR5, INPUT);
pinMode(PIR6, INPUT);
}

void loop(){
val = digitalRead(PIR1); 
if (val == HIGH) { 
digitalWrite(rat, HIGH); 
delay(500);
digitalWrite(rat, LOW);
delay(2000);
}
if (val == LOW) { 
digitalWrite(rat, LOW);
}
val = digitalRead(PIR2);
if (val == HIGH) {
digitalWrite(morgue1, HIGH);
delay(250);
digitalWrite(morgue1, LOW);
delay(500);
digitalWrite(morgue2, LOW);
delay(250);
digitalWrite(morgue2, HIGH);
delay(500);
digitalWrite(morgue3, LOW);
delay(750);
digitalWrite(morgue3, HIGH);
delay(250);
digitalWrite(morgue4, HIGH);
delay(250);
digitalWrite(morgue4, LOW);
delay(500);
digitalWrite(morgue2, HIGH);
delay(250);
digitalWrite(morgue2, LOW);
delay(500);
digitalWrite(morgue4, HIGH);
delay(250);
digitalWrite(morgue4, LOW);
delay(500);
digitalWrite(morgue1, HIGH);
delay(500);
digitalWrite(morgue1, LOW);
delay(500);

}
if (val== LOW) {
digitalWrite(morgue1, LOW);
digitalWrite(morgue2, LOW);
digitalWrite(morgue3, LOW);
digitalWrite(morgue4, LOW);
}
val = digitalRead(PIR3);
if (val == HIGH); {
digitalWrite(coffin, HIGH);
delay(500);
digitalWrite(coffin, LOW);
delay(2000);
}
if (val== LOW) {
digitalWrite(coffin, LOW);
} 
val = digitalRead(PIR4);
if (val == HIGH); {
digitalWrite(clownstrobe, HIGH);
delay(300);
digitalWrite(clownstrobe, LOW);
delay(2000);
digitalWrite(clownpop, HIGH);
delay(300);
digitalWrite(clownpop, LOW);
delay(2000);
}
if (val== LOW) {
digitalWrite(clownstrobe, LOW);
digitalWrite(clownpop, LOW);
}
val = digitalRead(PIR5);
if (val == HIGH); {
digitalWrite(dropstrobe, HIGH);
delay(250);
digitalWrite(dropdoor, HIGH);
delay(250);
digitalWrite(dropstrobe, LOW);
delay(2000);
digitalWrite(dropdoor, LOW);
delay(2000);
}
if (val== LOW) {
digitalWrite(dropstrobe, LOW);
digitalWrite(dropdoor, LOW);
}
val = digitalRead(PIR6);
if (val == HIGH); {
digitalWrite(firecracker, HIGH);
delay(250);
digitalWrite(firecracker, LOW);
delay(2000);
}
if (val== LOW) {
digitalWrite(firecracker, LOW);
}
}


----------



## JeffHaas (Sep 7, 2010)

I see two things...

1. You're not letting the PIRs warm up. A PIR usually needs about 60 seconds to get used to looking at the area so it gets used to it. Otherwise it triggers at the wrong times.

2. You're not debouncing the PIRs, and it's possible for them to get set off without something there. Air currents or whatever, they're finicky.

Here's code that I wrote for our local CalHaunts Make & Take, it was set up to work with one PIR and a couple of relays. It's based on code for PIRs from Adafruit. Try it out with your Arduino and change the pins to match a PIR and relay on your setup. It should work for you and you'll see it run, and can try out triggering a PIR and setting off a couple of relays. Use the Serial Monitor after uploading the code (CTRL-M) to see what's going on.

Then to adapt your code, try adding the variables for the PIR value and timer, the warmup time for all the PIRs before the rest of the code, and the section right after Void Loop that is the debouncing section for the PIRs. Don't forget the delay(5) at the very end of the loop, it's part of the debouncing!

Jeff


```
/*
 * CalHaunts PIR and Relays, for Make & Take workshop, Sept. 2012
 * Based on AdaFruit example code
 * To be used with Evil Mad Science's Diavolino [but is compatible with any Arduino], a PIR, and dual relay board
 * 8/13/2012 by Jeff Haas
 */
// Allows an Arduino to act as a 3-Stage Timer and control two relays, with optional delay between relays.
// Includes blinking LED for PIR warmup, and easy to change Prop Timing variables.
//
// After uploading sketch, hit CTRL + SHIFT + M to see debug info on Serial Monitor.
// 
/////////////////////////////
//VARIABLES 
int pirPin = 6;                 // input pin for PIR sensor
int relay1 = 2;                 // digital pin connected to relay1
int relay2 = 3;                 // digital pin connected to relay2
int ledPin = 13;                // pin for the built-in LED

int pirState = LOW;             // we start, assuming no motion detected
int PirVal = 0;                 // variable for reading the pin status
int TIMER = 0;                  // For tracking PIR debounce

//Prop Timing variables
int calibrationTime = 60;       // Set PIR calibration time.  Should be 60 seconds for good warmup.  Time in seconds.
int PropWait = 2;               // Pause before props go off after motion is detected.  Time in seconds.
int Rly1Run = 1;                // How long Relay1 runs.  Time in seconds.
int PropGap = 2;                // Time between first relay going off and second relay going off.  Time in seconds.
int Rly2Run = 1;                // How long Relay2 runs.  Time in seconds.
int ResetTime = 20;             // Run time of prop + PIR cool down + desired wait time for next trigger.  Time in seconds.

/////////////////////////////
//SETUP 
void setup() {
  pinMode(pirPin, INPUT);       // declare PIR sensor as input
  pinMode(relay1, OUTPUT);      // declare relay1 as output
  pinMode(relay2, OUTPUT);      // declare relay2 as output
  pinMode(ledPin, OUTPUT);      // declare LED as output
 
  Serial.begin(9600);           // Use Serial Monitor to debug


//Give the PIR sensor some time to calibrate
  Serial.print("Calibrating sensor");  
    for(int i = 0; i < calibrationTime; i++){
      Serial.print(".");
        digitalWrite(ledPin, HIGH);  // Blink LED while PIR is calibrating
        delay (500);
        digitalWrite(ledPin, LOW);
        delay (500);
      }
    Serial.println("done.");
    Serial.println("SENSOR ACTIVE");
    delay(50); 
}

////////////////////////////
//LOOP 
void loop(){

  PirVal = digitalRead(pirPin);       // Read input value
  TIMER = TIMER + 5 * PirVal;         // PIR debounce code
//  Serial.println(TIMER);            // Show value of TIMER for setting sensitivity of debounce
  if (TIMER > 100) {                  // Wait for 0.1 sec input
  
  Serial.println("Motion detected");   
    if (pirState == LOW) {          // The PIR has just turned on, but the variable for the PIR's state is LOW...
      pirState = HIGH;              // ...so change the value to HIGH.  Print only on the output change, not state.
    }

// Now turn everything on to trigger the props!

    for(int j = 0; j < PropWait; j++){    // Delay before the first relay is triggered  
      Serial.print(".");
      delay(1000);
      }
    Serial.println("Relay 1!");
    
    digitalWrite(ledPin, HIGH);           // Turn LED ON for a visual indicator
    digitalWrite(relay1, HIGH);           // Turn relay1 ON

      for(int j = 0; j < Rly1Run; j++){   // Time Relay1 runs
      Serial.print(".");
      delay(1000);
      }
    
    digitalWrite(relay1, LOW);            // Turn relay1 OFF

      for(int j = 0; j < PropGap; j++){  // Delay between triggering Relay1 and Relay2
      Serial.print(".");
      delay(1000);
      }

    Serial.println("Relay 2!");       

    digitalWrite(relay2, HIGH);           // Turn relay2 ON

      for(int j = 0; j < Rly2Run; j++){   // Time Relay2 runs
      Serial.print(".");
      delay(1000);
      }

    digitalWrite(ledPin, LOW);      // Turn LED OFF
    digitalWrite(relay2, LOW);      // Turn relay2 OFF

    TIMER = 0;                      // Reset TIMER byte
    
    Serial.print("Reset");          // Prop reset time.
             
    for(int j = 0; j < ResetTime; j++){  
      Serial.print(".");
      delay(1000);
      }

  } else {
    if (pirState == HIGH){     // We have just turned off, so pirState is HIGH
      Serial.println("Ready"); // We only want to print on the output change, not state
      pirState = LOW;          // Reset variable that tracks the PIR's state.
    }
  }
  delay(5);        // Brief pause on the checking loop.  Acts as debounce delay.
}
```


----------



## HomeyDaClown (Oct 3, 2009)

Yeah what he said....

Delays are everything when it comes to PIR sensors and prop control, they need time to stabilize and that time can vary due to many factors including the ambient temperature.

It gets cold here often below 40 degrees on haunt nights and that drives PIR sensors nuts without extra time to warm up. I would also get rid of the var variable being shared by each loop. Check the PIR pin status and do your digitalwrites directly, no need to store the status each time for comparison.


----------



## Cole&Jacksdad (Jan 20, 2011)

This is as far as I got on Jeff's code. I'm not sure whaat to do next.

/*
* CalHaunts PIR and Relays, for Make & Take workshop, Sept. 2012
* Based on AdaFruit example code
* To be used with Evil Mad Science's Diavolino [but is compatible with any Arduino], a PIR, and dual relay board
* 8/13/2012 by Jeff Haas
*/
// Allows an Arduino to act as a 3-Stage Timer and control two relays, with optional delay between relays.
// Includes blinking LED for PIR warmup, and easy to change Prop Timing variables.
//
// After uploading sketch, hit CTRL + SHIFT + M to see debug info on Serial Monitor.
// 
/////////////////////////////
//VARIABLES 
int Pir1 = 14; // input pin for PIR 1 sensor
int Pir2 = 15; // input pin for PIR 2 sensor
int Pir3 = 16; // input pin for PIR 3 sensor
int Pir4 = 17; // input pin for PIR 4 sensor
int Rat = 22; // input pin for rat
int M1 = 23; // input for morgue 1
int M2 = 24; // input for morgue 2
int M3 = 25; // input for morgue 3
int M4 = 26; // input for morgue 4
int Cn = 27; // input for coffin
int Cs = 28; // input for clown strobe
int Cp = 29; // input for clown pop up
int Ds = 30; // input for drop panel strobe
int Dd = 31; // input for drop panel door
int Fc = 32 // input for E-firecracker
int pirState = LOW; // we start, assuming no motion detected
int PirVal = 0; // variable for reading the pin status
int TIMER = 0; // For tracking PIR debounce
//Prop Timing variables
int calibrationTime = 60; // Set PIR calibration time. Should be 60 seconds for good warmup. Time in seconds.
int PropWait = 2; // Pause before props go off after motion is detected. Time in seconds.
int Rly1Run = 1; // How long Relay1 runs. Time in seconds.
int PropGap = 2; // Time between first relay going off and second relay going off. Time in seconds.
int Rly2Run = 1; // How long Relay2 runs. Time in seconds.
int ResetTime = 20; // Run time of prop + PIR cool down + desired wait time for next trigger. Time in seconds.
/////////////////////////////
//SETUP 
void setup() {
pinMode(Pir1, INPUT); // declare PIR 1 sensor as input
pinMode(Pir2, INPUT); // declare PIR 2 sensor as input
pinMode(Pir3, INPUT); // declare PIR 3 sensor as input
pinMode(Pir4, INPUT); // declare PIR 4 sensor as input
pinMode(Pir5, INPUT); // declare PIR 5 sensor as input
pinMode(Pir6, INPUT); // declare PIR 6 sensor as input
pinMode(Rat, OUTPUT); // declare Rat as output
pinMode(M1, OUTPUT); // declare Morgue 1 as output
pinMode(M2, OUTPUT); // declare Morgue 2 as output
pinMode(M3, OUTPUT); // declare Morgue 3 as output
pinMode(M4, OUTPUT); // declare Morgue 4 as output
pinMode(Cn, OUTPUT); // declare Coffin as output
pinMode(Cs, OUTPUT); // declare Clown Strobe as output
pinMode(Cp, OUTPUT); // declare Clown pop up as output
pinMode(Ds, OUTPUT); // declare Drop panel strobe as output
pinMode(Dd, OUTPUT); // declare Drop panel door as output
pinMode(FC, OUTPUT); // declare E-firecracker as output

Serial.begin(9600); // Use Serial Monitor to debug

//Give the PIR sensor some time to calibrate
Serial.print("Calibrating sensor"); 
for(int i = 0; i < calibrationTime; i++){
Serial.print(".");
digitalWrite(ledPin, HIGH); // Blink LED while PIR is calibrating
delay (500);
digitalWrite(ledPin, LOW);
delay (500);
}
Serial.println("done.");
Serial.println("SENSOR ACTIVE");
delay(50); 
}
////////////////////////////
//LOOP 
void loop(){
PirVal = digitalRead(pirPin); // Read input value
TIMER = TIMER + 5 * PirVal; // PIR debounce code
// Serial.println(TIMER); // Show value of TIMER for setting sensitivity of debounce
if (TIMER > 100) { // Wait for 0.1 sec input

Serial.println("Motion detected"); 
if (pirState == LOW) { // The PIR has just turned on, but the variable for the PIR's state is LOW...
pirState = HIGH; // ...so change the value to HIGH. Print only on the output change, not state.
}
// Now turn everything on to trigger the props!
for(int j = 0; j < PropWait; j++){ // Delay before the first relay is triggered 
Serial.print(".");
delay(1000);
}
Serial.println("Relay 1!");

digitalWrite(ledPin, HIGH); // Turn LED ON for a visual indicator
digitalWrite(relay1, HIGH); // Turn relay1 ON
for(int j = 0; j < Rly1Run; j++){ // Time Relay1 runs
Serial.print(".");
delay(1000);
}

digitalWrite(relay1, LOW); // Turn relay1 OFF
for(int j = 0; j < PropGap; j++){ // Delay between triggering Relay1 and Relay2
Serial.print(".");
delay(1000);
}
Serial.println("Relay 2!"); 
digitalWrite(relay2, HIGH); // Turn relay2 ON
for(int j = 0; j < Rly2Run; j++){ // Time Relay2 runs
Serial.print(".");
delay(1000);
}
digitalWrite(ledPin, LOW); // Turn LED OFF
digitalWrite(relay2, LOW); // Turn relay2 OFF
TIMER = 0; // Reset TIMER byte

Serial.print("Reset"); // Prop reset time.

for(int j = 0; j < ResetTime; j++){ 
Serial.print(".");
delay(1000);
}
} else {
if (pirState == HIGH){ // We have just turned off, so pirState is HIGH
Serial.println("Ready"); // We only want to print on the output change, not state
pirState = LOW; // Reset variable that tracks the PIR's state.
}
}
delay(5); // Brief pause on the checking loop. Acts as debounce delay.
}


----------



## JeffHaas (Sep 7, 2010)

I would suggest you put my code onto the Uno, hook up a PIR and a relay, and see how it works without changing anything. Then add one PIR and another relay, and get them both going independently. When you can do that then you can add all the others pretty quickly.

I don't have a Mega so I can't test this myself, but once you've got it going on the standard Arduino you can move it to the Mega. Add one piece at a time, and test each one to see that it works with all the other pieces before you add another one.


----------



## Cole&Jacksdad (Jan 20, 2011)

So I wrote some small codes just to check the PIR's. 2 are bad. One of them kept triggering the controller.


----------



## JeffHaas (Sep 7, 2010)

Ah ha! PIRs are pretty cheap, I have one that was fine from last year and then just a couple of weeks ago it stopped working, for no reason that I could see.

Is the rest of it working right? I've got an idea I'm going to try out and see how it works.


----------



## Cole&Jacksdad (Jan 20, 2011)

I ran every PIR and I could hear my relays clicking as I set off the PIR's. The codes I wrote were just for one PIR at a time. That is how I found out what was going on. I have everything wired in a maze, so I have to walk to each one to set it off. I am also going to take one of the good ones and switch it to all the other PIR's to test just to make sure it's not wiring.


----------



## JeffHaas (Sep 7, 2010)

Cool, it sounds like you solved it.


----------



## Cole&Jacksdad (Jan 20, 2011)

I'm still haaving issues. I thought maybe there was a short, so I replaced some wiring. No luck. It must be the code because sometimes it would work and other times it kept triggering different PIR's.


----------



## Cole&Jacksdad (Jan 20, 2011)

I'm starting to lose confidence That I will have anything working this year.


----------



## JeffHaas (Sep 7, 2010)

Here's an idea...try connecting only one PIR at a time with your current code - don't change the code, just have only one PIR at a time connected. Then set it off and see what happens. If you have a short somewhere then one of the PIRs should turn on multiple scares.


----------



## DarkOne (Oct 16, 2012)

How is this going? When it triggers all the props, do they each go through their full routine, or are they very short versions of what they're supposed to do? I don't see why you need the "for" statements when turning on and off the relays, it seems less messy to just use a delay.


----------



## Cole&Jacksdad (Jan 20, 2011)

Here is a code my wife came up with, but I can only get 2 props working. It is from the arduino site so that is why paralax PIR is mentioned.
/* 
* //////////////////////////////////////////////////
* //making sense of the Parallax PIR sensor's output
* //////////////////////////////////////////////////
*
* Switches a LED according to the state of the sensors output pin.
* Determines the beginning and end of continuous motion sequences.
*
* @author: Kristian Gohlke / krigoo (_) gmail (_) com / http://krx.at
* @date: 3. September 2006 
*
* kr1 (cleft) 2006 
* released under a creative commons "Attribution-NonCommercial-ShareAlike 2.0" license
* http://creativecommons.org/licenses/by-nc-sa/2.0/de/
*
*
* The Parallax PIR Sensor is an easy to use digital infrared motion sensor module. 
* (http://www.parallax.com/detail.asp?product_id=555-28027)
*
* The sensor's output pin goes to HIGH if motion is present.
* However, even if motion is present it goes to LOW from time to time, 
* which might give the impression no motion is present. 
* This program deals with this issue by ignoring LOW-phases shorter than a given time, 
* assuming continuous motion is present during these phases.
* 
*/
/////////////////////////////
//VARS
//the time we give the sensor to calibrate (10-60 secs according to the datasheet)
int calibrationTime = 30; 
//the time when the sensor outputs a low impulse
long unsigned int lowIn; 
//the amount of milliseconds the sensor has to be low 
//before we assume all motion has stopped
long unsigned int pause = 5000; 
boolean lockLow = true;
boolean takeLowTime; 
int pir1Pin = 14; //the digital pin connected to the PIR sensor's output
int pir2Pin = 17;
int ratPin = 22;
int cfnPin = 24;

/////////////////////////////
//SETUP
void setup(){
Serial.begin(9600);
pinMode(pir1Pin, INPUT);
pinMode(pir2Pin, INPUT);
pinMode(ratPin, OUTPUT);
pinMode(cfnPin, OUTPUT);
digitalWrite(pir1Pin, LOW);
digitalWrite(pir2Pin, LOW);
//give the sensor some time to calibrate
Serial.print("calibrating sensor ");
for(int i = 0; i < calibrationTime; i++){
Serial.print(".");
delay(1000);
}
Serial.println(" done");
Serial.println("SENSOR ACTIVE");
delay(50);
}
////////////////////////////
//LOOP
void loop(){
if(digitalRead(pir1Pin) == HIGH){
digitalWrite(ratPin, HIGH); //the led visualizes the sensors output pin state
if(lockLow){ 
//makes sure we wait for a transition to LOW before any further output is made:
lockLow = false; 
Serial.println("---");
Serial.print("motion detected at ");
Serial.print(millis()/1000);
Serial.println(" sec"); 
delay(50);
} 
takeLowTime = true;
}
if(digitalRead(pir1Pin) == LOW){ 
digitalWrite(ratPin, LOW); //the led visualizes the sensors output pin state
if(takeLowTime){
lowIn = millis(); //save the time of the transition from high to LOW
takeLowTime = false; //make sure this is only done at the start of a LOW phase
}
//if the sensor is low for more than the given pause, 
//we assume that no more motion is going to happen
if(!lockLow && millis() - lowIn > pause){ 
//makes sure this block of code is only executed again after 
//a new motion sequence has been detected
lockLow = true; 
Serial.print("motion ended at "); //output
Serial.print((millis() - pause)/1000);
Serial.println(" sec");
delay(50);
}
}

////////////////////////////
//LOOP

if(digitalRead(pir2Pin) == HIGH){
digitalWrite(cfnPin, HIGH); //the led visualizes the sensors output pin state
if(lockLow){ 
//makes sure we wait for a transition to LOW before any further output is made:
lockLow = false; 
Serial.println("---");
Serial.print("motion detected at ");
Serial.print(millis()/1000);
Serial.println(" sec"); 
delay(50);
} 
takeLowTime = true;
}
if(digitalRead(pir2Pin) == LOW){ 
digitalWrite(cfnPin, LOW); //the led visualizes the sensors output pin state
if(takeLowTime){
lowIn = millis(); //save the time of the transition from high to LOW
takeLowTime = false; //make sure this is only done at the start of a LOW phase
}
//if the sensor is low for more than the given pause, 
//we assume that no more motion is going to happen
if(!lockLow && millis() - lowIn > pause){ 
//makes sure this block of code is only executed again after 
//a new motion sequence has been detected
lockLow = true; 
Serial.print("motion ended at "); //output
Serial.print((millis() - pause)/1000);
Serial.println(" sec");
delay(50);
}
}
} 
We are having trouble adding more props on and I can't figure out how to run a prop with multiple outputs. One prop I have 4 cylinders and all four cylinders need to move at different times.


----------



## DarkOne (Oct 16, 2012)

Are your outputs all relays and are they staying on the entire time from motion detected until motion ended?


----------



## Cole&Jacksdad (Jan 20, 2011)

Yes and yes.


----------



## DarkOne (Oct 16, 2012)

I don't have a PIR to test, but which model do you have? The Parallax and Adafruit versions have a jumper on the back for H and L which is retriggering and non-retriggering. The ebay ones seem to have no jumper but can be changed, you can see the solder pads in the corner marked H and L. These are apparently sent defaulted to retriggering. This means that the output from the sensor remains high until a body is no longer sensed. Non-retriggering would automatically go back to low after being sensed high after a set amount of time built into the sensor. I would think either way would work. 
Here is the datasheet I found on the ebay ones.
http://elecfreaks.com/store/download/datasheet/sensor/DYP-ME003/Specification.pdf

I've reworked your original code. I added a val for each prop, and reset it to 0 after each check. ( Just in case it's getting messed up because of using the same val.) I also changed all your if, if for each prop to an if, else if, else. This is the part I hope works.

What you might run into is if a prop is triggered, it goes through it's cycle and if nothing else is triggered after, but someone is still there, it may cycle a couple times in a row. If this is the case, you could run something like the "blink without delay" sketch using millis so it would check the last time the prop triggered and wouldn't retrigger within a certain amount of seconds.

Here is the modified code.
/*
* 2012 Haunt code
*/
int rat = 2; //rat strobe light is connected to pin 2
int morgue1 = 3; //morgue1 is connected to pin 3
int morgue2 = 4; //morgue2 is connected to pin 4
int morgue3 = 5; //morgue3 is connected to pin 5
int morgue4 = 6; //morgue4 is connected to pin 6
int coffin = 7; //coffin is connected to pin 7
int clownstrobe = 8; //clown strobe is conected to pin 8
int clownpop = 9; //clown pop is connected to pin 9
int dropstrobe = 10; //drop strobe is connected to pin 10
int dropdoor = 11; //drop door is connected to pin 11
int firecracker = 12; //firecracker is connected to pin 12
int PIR1 = 22; //PIR1 is connected to pin 22
int PIR2 = 23; //PIR2 is connected to pin 23
int PIR3 = 24; //PIR3 is connected to pin 24
int PIR4 = 25; //PIR4 is coneected to pin 25
int PIR5 = 26; //PIR5 is connected to pin 26
int PIR6 = 27; //PIR6 is connected to pin 27
int val1 = 0;// variable for reading the pin status
int val2 = 0;
int val3 = 0;
int val4 = 0;
int val5 = 0;
int val6 = 0;
void setup() {

pinMode(rat, OUTPUT);
pinMode(morgue1, OUTPUT);
pinMode(morgue2, OUTPUT);
pinMode(morgue3, OUTPUT);
pinMode(morgue4, OUTPUT);
pinMode(coffin, OUTPUT);
pinMode(clownstrobe, OUTPUT);
pinMode(clownpop, OUTPUT);
pinMode(dropstrobe, OUTPUT);
pinMode(dropdoor, OUTPUT);
pinMode(firecracker, OUTPUT);
pinMode(PIR1, INPUT);
pinMode(PIR2, INPUT);
pinMode(PIR3, INPUT);
pinMode(PIR4, INPUT);
pinMode(PIR5, INPUT);
pinMode(PIR6, INPUT);
}

void loop(){
val1 = digitalRead(PIR1);
if (val1 == HIGH) {
digitalWrite(rat, HIGH);
delay(500);
digitalWrite(rat, LOW);
delay(2000);//Not sure why a 2 second delay is here
}
else if (val1 == LOW){
digitalWrite(rat, LOW);
}
else {}
val1 = 0;

val2 = digitalRead(PIR2);
if (val2 == HIGH) {
digitalWrite(morgue1, HIGH);
delay(250);
digitalWrite(morgue1, LOW);
delay(750);
digitalWrite(morgue2, HIGH);
delay(1250);
digitalWrite(morgue3, HIGH);
delay(250);
digitalWrite(morgue4, HIGH);
delay(250);
digitalWrite(morgue4, LOW);
delay(500);
digitalWrite(morgue2, HIGH);
delay(250);
digitalWrite(morgue2, LOW);
delay(500);
digitalWrite(morgue4, HIGH);
delay(250);
digitalWrite(morgue4, LOW);
delay(500);
digitalWrite(morgue1, HIGH);
delay(500);
digitalWrite(morgue1, LOW);
delay(500);

}
else if (val2 == LOW) {
digitalWrite(morgue1, LOW);
digitalWrite(morgue2, LOW);
digitalWrite(morgue3, LOW);
digitalWrite(morgue4, LOW);
}
else{}
val2 = 0;

val3 = digitalRead(PIR3);
if (val3 == HIGH) {
digitalWrite(coffin, HIGH);
delay(500);
digitalWrite(coffin, LOW);
delay(2000);
}
else if (val3 == LOW) {
digitalWrite(coffin, LOW);
}
else{}
val3 = 0;

val4 = digitalRead(PIR4);
if (val4 == HIGH) {
digitalWrite(clownstrobe, HIGH);
delay(300);
digitalWrite(clownstrobe, LOW);
delay(2000);
digitalWrite(clownpop, HIGH);
delay(300);
digitalWrite(clownpop, LOW);
delay(2000);
}
else if (val4 == LOW) {
digitalWrite(clownstrobe, LOW);
digitalWrite(clownpop, LOW);
}
else{}
val4 = 0;

val5 = digitalRead(PIR5);
if (val5 == HIGH) {
digitalWrite(dropstrobe, HIGH);
delay(250);
digitalWrite(dropdoor, HIGH);
delay(250);
digitalWrite(dropstrobe, LOW);
delay(2000);
digitalWrite(dropdoor, LOW);
delay(2000);
}
else if (val5== LOW) {
digitalWrite(dropstrobe, LOW);
digitalWrite(dropdoor, LOW);
}
else{}
val5 = 0;

val6 = digitalRead(PIR6);
if (val6 == HIGH) {
digitalWrite(firecracker, HIGH);
delay(250);
digitalWrite(firecracker, LOW);
delay(2000);//shouldn't need this delay
}
else if (val6== LOW) {
digitalWrite(firecracker, LOW);
}
else{}
val6 = 0;
}


----------



## Cole&Jacksdad (Jan 20, 2011)

I have the Parallax PIRs.
Thanks for modifing the code. I will give it a try and let you know.


----------



## Cole&Jacksdad (Jan 20, 2011)

I just went and checked and the morgue relays kept clicking off and on.


----------



## DarkOne (Oct 16, 2012)

Are all the PIRs set to the same jumper H or L? I think you'd want H. What exactly are the relays on the morque hooked up to, do they act as a switch to start something that has it's own controller or something that may need more time to complete whatever it is it's doing? The time the relays are on is very short. I usually try to keep a relay on for 1/2 second if switching something on that can run itself.


----------



## DarkOne (Oct 16, 2012)

I realized the code I posted didn't allow for the PIRs to warm up, forgot about that. This revised code allows a minute of warmup before starting to read the sensors. I also added Serial.prints and delays for debugging. Open the Serial port after starting up the arduino. A few seconds should pass then "warming up" should appear, after a minute "warmed up will appear and it will read the sensors in sequence with 2 seconds inbetween readings, this is so you have time to see what is happening after each reading. The serial port will show which sensor it is reading and give you a 0 for LOW and a 1 for HIGH. If HIGH it should also say "Activating prop".

I've uploaded this to my mega and the serial port reacts as expected. I do not have any PIRs, but hopefully this works better. This should be able to tell us where something is going wrong since we'll know what the arduino is thinking. Once you get it figured out, you can remove the extra delays so it will work faster.

/*
* 2012 Haunt code
*/
int rat = 2; //rat strobe light is connected to pin 2
int morgue1 = 3; //morgue1 is connected to pin 3
int morgue2 = 4; //morgue2 is connected to pin 4
int morgue3 = 5; //morgue3 is connected to pin 5
int morgue4 = 6; //morgue4 is connected to pin 6
int coffin = 7; //coffin is connected to pin 7
int clownstrobe = 8; //clown strobe is conected to pin 8
int clownpop = 9; //clown pop is connected to pin 9
int dropstrobe = 10; //drop strobe is connected to pin 10
int dropdoor = 11; //drop door is connected to pin 11
int firecracker = 12; //firecracker is connected to pin 12
int PIR1 = 22; //PIR1 is connected to pin 22
int PIR2 = 23; //PIR2 is connected to pin 23
int PIR3 = 24; //PIR3 is connected to pin 24
int PIR4 = 25; //PIR4 is coneected to pin 25
int PIR5 = 26; //PIR5 is connected to pin 26
int PIR6 = 27; //PIR6 is connected to pin 27
int val1 = 0;// variable for reading the pin status
int val2 = 0;
int val3 = 0;
int val4 = 0;
int val5 = 0;
int val6 = 0;
int warmup =0;
void setup() {


pinMode(rat, OUTPUT);
pinMode(morgue1, OUTPUT);
pinMode(morgue2, OUTPUT);
pinMode(morgue3, OUTPUT);
pinMode(morgue4, OUTPUT);
pinMode(coffin, OUTPUT);
pinMode(clownstrobe, OUTPUT);
pinMode(clownpop, OUTPUT);
pinMode(dropstrobe, OUTPUT);
pinMode(dropdoor, OUTPUT);
pinMode(firecracker, OUTPUT);
pinMode(PIR1, INPUT);
pinMode(PIR2, INPUT);
pinMode(PIR3, INPUT);
pinMode(PIR4, INPUT);
pinMode(PIR5, INPUT);
pinMode(PIR6, INPUT);
Serial.begin (9600);
}

void loop(){
if (warmup == 0){
Serial.println ("warming up");
delay (60000);
warmup ++;
Serial.println ("warmed up");
}
else {
val1 = digitalRead(PIR1);
Serial.print ("PIR1:");
Serial.println (val1);
if (val1 == HIGH) {
Serial.println ("Activating Prop");
digitalWrite(rat, HIGH);
delay(500);
digitalWrite(rat, LOW);
delay(2000);
}
else if (val1 == LOW){
digitalWrite(rat, LOW);
}
else {}
val1 = 0;
delay (2000);//Debugging Delay
val2 = digitalRead(PIR2);
Serial.print ("PIR2:");
Serial.println (val2);
if (val2 == HIGH) {
Serial.println ("Activating Prop");
digitalWrite(morgue1, HIGH);
delay(250);
digitalWrite(morgue1, LOW);
delay(750);
digitalWrite(morgue2, HIGH);
delay(1250);
digitalWrite(morgue3, HIGH);
delay(250);
digitalWrite(morgue4, HIGH);
delay(250);
digitalWrite(morgue4, LOW);
delay(500);
digitalWrite(morgue2, HIGH);
delay(250);
digitalWrite(morgue2, LOW);
delay(500);
digitalWrite(morgue4, HIGH);
delay(250);
digitalWrite(morgue4, LOW);
delay(500);
digitalWrite(morgue1, HIGH);
delay(500);
digitalWrite(morgue1, LOW);
delay(500);

}
else if (val2 == LOW) {
digitalWrite(morgue1, LOW);
digitalWrite(morgue2, LOW);
digitalWrite(morgue3, LOW);
digitalWrite(morgue4, LOW);
}
else{}
val2 = 0;
delay (2000);//Debugging Delay
val3 = digitalRead(PIR3);
Serial.print ("PIR3:");
Serial.println (val3);
if (val3 == HIGH) {
Serial.println ("Activating Prop");
digitalWrite(coffin, HIGH);
delay(500);
digitalWrite(coffin, LOW);
delay(2000);
}
else if (val3 == LOW) {
digitalWrite(coffin, LOW);
}
else{}
val3 = 0;
delay(2000);//Debugging Delay
val4 = digitalRead(PIR4);
Serial.print ("PIR4:");
Serial.println (val4);
if (val4 == HIGH) {
Serial.println ("Activating Prop");
digitalWrite(clownstrobe, HIGH);
delay(300);
digitalWrite(clownstrobe, LOW);
delay(2000);
digitalWrite(clownpop, HIGH);
delay(300);
digitalWrite(clownpop, LOW);
delay(2000);
}
else if (val4 == LOW) {
digitalWrite(clownstrobe, LOW);
digitalWrite(clownpop, LOW);
}
else{}
val4 = 0;
delay(2000);//Debugging Delay
val5 = digitalRead(PIR5);
Serial.print ("PIR5:");
Serial.println (val5);
if (val5 == HIGH) {
Serial.println ("Activating Prop");
digitalWrite(dropstrobe, HIGH);
delay(250);
digitalWrite(dropdoor, HIGH);
delay(250);
digitalWrite(dropstrobe, LOW);
delay(2000);
digitalWrite(dropdoor, LOW);
delay(2000);
}
else if (val5== LOW) {
digitalWrite(dropstrobe, LOW);
digitalWrite(dropdoor, LOW);
}
else{}
val5 = 0;
delay (2000);//Debugging Delay
val6 = digitalRead(PIR6);
Serial.print ("PIR6:");
Serial.println (val6);
if (val6 == HIGH) {
Serial.println ("Activating Prop");
digitalWrite(firecracker, HIGH);
delay(250);
digitalWrite(firecracker, LOW);
delay(2000);
}
else if (val6== LOW) {
digitalWrite(firecracker, LOW);
}
else{}
val6 = 0;
delay(2000);//Debugging delay
}
}


----------



## Cole&Jacksdad (Jan 20, 2011)

Dispite all of the technical issues with the Arduino, my first run of my haunt went well last night. I switched all the props over to momentary switches and recruited some actors to activate the props. So note to self! Figure code out the summer before Halloween and not the week before Halloween. I want to thank all you guys for all the help and espespecially Jeff Haas and Darkone for giving me some codes to work with. Jeff Haas, when I come out to Ca next summer, maybe we ca get togther(I will bring my mega and relays) and try to work some kind of code out. I'll buy the pizza.


----------

