I am building a halloween project with my kid. It will trigger on an IR (door minder) circuit, and should turn on two relays which will be connected to an air solonoid valve and a 110v outlet for lights.
Seems simple enough. This is my first project with Arduino, and it is not working....
the relays are triggering simultaneously
on --> 1 second
off --> 10 seconds
they are ignoring the 5VDC input signal on pin 7
Any help you can offer would be greatly appreciated
// application used to trigger on an IR receiver and turn on and off two relays.
// Relays turn on simultaneously, but then turn off in sequence based on delays.
// A final attenuation period may be added to defeat further triggering for additiona time
// define constants
const int inPin = 7; // sense pin, provides 5VDC when high
const int lights = 13; // output to one relay
const int solonoid = 12; // output to second relay
void setup()
{
// Serial.begin(9600);
pinMode(solonoid, OUTPUT);
pinMode(lights, OUTPUT);
pinMode(inPin, INPUT);
}
void loop()
{
// start loop with relays off
digitalWrite(solonoid, LOW);
digitalWrite(lights, LOW);
// read sense pin - hooked to a IR receiver and relay, passes 5V when triggered
int(pinState) = digitalRead(inPin);
// if 5VDC preset on pin 7, then process the loop actions
if(pinState == HIGH){
// turn both relays on
digitalWrite(solonoid, HIGH);
digitalWrite(lights, HIGH);
//wait first delay
delay(1000);
// turn off first relay
digitalWrite(solonoid, LOW);
// wait second delay
delay(10000);
// turn off other relay
digitalWrite(lights, LOW);
} // end if loop
//attenuation delay - prevent triggering
delay(60000);
} // end program loop
Is this really the code that you wanted here? int(pinState) = digitalRead(inPin);It doesn't look right to me, but it compiles, and it even seems to work. Hmph.
When I run your code using the onboard LED instead of relays, I get the expected results. That makes me suspect that your relays are affecting the supply voltage:
Are you driving them directly with the Arduino pins? Are they 5V relays, and is the coil current less than the 40mA limit?
Are you driving the coils from the Arduino's 5V supply? Is the coil current unreasonable for the 5V supply?
Do you have flyback doides on your relay coils? If you don't, you need them.
What are those relays, and how are you driving them?
void loop()
{
// start loop with relays off
digitalWrite(solonoid, LOW);
digitalWrite(lights, LOW);
// read sense pin - hooked to a IR receiver and relay, passes 5V when triggered
int(pinState) = digitalRead(inPin);
// if 5VDC preset on pin 7, then process the loop actions
if(pinState == HIGH){
...
} // end if loop
//attenuation delay - prevent triggering
delay(60000);
} // end program loop
What tmd3 said about that line, change it to:
int pinState = digitalRead(inPin);
As for the 60 seconds delay, you are only testing the button once every 60 seconds, so you may have to wait 60 seconds for anything to happen.
Also what tmd3 said about the relays, the current, the diodes, etc.
The problem seems to be that it is failing to abide by the if logic statement and just parsing through the nested IF arguments, regardless of whether the input pin is high. When there is no trigger voltage, I want it to stay LOW on the two output pins... It is ignoring the input signal and just cycling through the flip/flop cycles based on the delays.
Thanks for the bug checking. I will remove the paren and retest the code.
The relays are add on boards from spark-fun
I built a small power supply with a 12v center tap transformer, bridge rect, 2 x 1000 uF caps, that feed 7805 and 7812 voltage regulators for 12v and 5v outs. The 5v feeds the arduino power, as well as directly feeding the power to the relay 5v terminals. The arduino digital channel outs feed the control terminal on the relay boards.
I will see what happens when I remove the parens. If it still fails, I will post a link to video showing the behavior and the latest code.
Thanks again for your assistance.
zargnut:
The problem seems to be that it is failing to abide by the if logic statement and just parsing through the nested IF arguments, regardless of whether the input pin is high.
What nested "if"? You only have one "if".
How is this input pin wired up, exactly? Have you taken steps to ensure it is low when it is supposed to be? Or is it floating?
I am sorry... I am a newbie and using poor terminology.
It was executing the code which were contained in the single IF statement, even though the IF criteria were not met.
I change a couple of things and it looks like it is working.
I defined pinState in the 'header'
I set pinState = LOW at start of each LOOP
I removed the () around pinState
It looks like it is working. I have attached pics and a scope trace
Revised Code
// application used to trigger on an IR receiver and turn on and off two relays.
// Relays turn on simultaneously, but then turn off in sequence based on delays.
// A final attenuation period may be added to defeat further triggering for additiona time
// define constants
const int inPin = 7; // sense pin, provides 5VDC when high
const int lights = 13; // output to one relay
const int solonoid = 12; // output to second relay
int pinState = 0; // define pinState variable = set to LOW = 0
void setup()
{
pinMode(solonoid, OUTPUT);
pinMode(lights, OUTPUT);
pinMode(inPin, INPUT);
}
void loop()
{
// start loop with relays off
digitalWrite(solonoid, LOW);
digitalWrite(lights, LOW);
// Reset pinState to LOW or 0 for every loop
pinState = 0;
// read sense pin - hooked to a IR receiver and relay, passes 5V when triggered
int pinState = digitalRead(inPin);
// if 5VDC preset on pin 7, then process the loop actions
if(pinState == HIGH){
// turn both relays on
digitalWrite(solonoid, HIGH);
digitalWrite(lights, HIGH);
//wait first delay (blast of air via solonoid valve)
delay(1000);
// turn off first relay
digitalWrite(solonoid, LOW);
//*** Trigger Audio File Play via serial bus***
// wait second delay (theatrical lights on skeleton)
delay(2000);
// turn off other relay
digitalWrite(lights, LOW);
//attenuation delay - prevent triggering
// placed in IF loop, only invoked if recently triggered
delay(4000);
} // end if loop
} // end program loop
int pinState = 0; // define pinState variable = set to LOW = 0
// Reset pinState to LOW or 0 for every loop
pinState = 0;
Set to 0 on every pass through loop.
int pinState = digitalRead(inPin);
// if 5VDC preset on pin 7, then process the loop actions
if(pinState == HIGH){
Then, you create a local variable with the same name as the global variable. Why? For the rest of loop(), the local variable is the only one referenced. Nothing happens to the global variable anymore.
You only need one pinState, and it does not need to be global.
I tried to break out the delays using variables at the beginning and then calling them.
ie:
int solonoidDelay = 1000;
then call it
delay (solonoidDelay);
and the syntax did not work. is there a simple fix for this?
I found another error on my point, which was pointed out. I did not have my input pin pulled down. I am an electronics newbie and never really understood what that meant... The voltage when not "HIGH" was around 1.5v and fluctuating... but enough noise to keep triggering the IF loop. I ran a wire thru a 1 MOhm resistor to ground, and that seemed to fix it.
Here is a link to picasa album with the finished box. We tried it with a little light, and it works pretty well. Will have to see if I can get the audio player shield working. Thanks for all your help.