Offline
Newbie
Karma: 0
Posts: 38
|
 |
« on: May 04, 2012, 09:01:17 am » |
A bit of a newbie to arduino but I'm trying. I have a question in regards to "if" statements. Basically I want it to check if any other any other inputs are reading LOW before allowing another input reading low to signal an output. It should "wait in line" so to speak. So here is my code below for starters. 2 switches and 2 outputs to relays. If S1 is low, and S2 drives low, I need it to wait for S1 to be high again before allowing it to drive outputs. How can I achieve this? Thanks! // constants int S1 = 2; // Float Switch 1 int S2 = 3; // Float Switch 2 int K1 = 8; // Relay K1 int K2 = 9; // Relay K2
void setup() { // initialize the pins, define pin usage pinMode(S1, INPUT); pinMode(S2, INPUT); pinMode(K1, OUTPUT); pinMode(K2, OUTPUT); digitalWrite(S1, HIGH); digitalWrite(S2, HIGH); } // begin switch logic void loop() { if (digitalRead(S1)==LOW) { digitalWrite(K1,HIGH); digitalWrite(K2,HIGH); } else if (digitalRead(S2)==LOW) { digitalWrite(K1,HIGH); digitalWrite(K2,HIGH); } else { digitalWrite(K1,LOW); digitalWrite(K2,LOW); } }
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Sr. Member
Karma: 0
Posts: 302
|
 |
« Reply #1 on: May 04, 2012, 09:25:23 am » |
You can always create a function to do the "last input reading low to signal an output", and use it inside the conditional roughly same way you have there, no ?! That way you can call it inside the conditional variable which will or not allow it to proceed...Makes sense ?!?
|
|
|
|
|
Logged
|
10 LET Loop=Infinite 20 GO TO 10
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 38
|
 |
« Reply #2 on: May 04, 2012, 11:03:38 am » |
I am not sure I follow you. This is the only way I think I could write it to work. Is there a more elegant/cleaner way to do this? // digital I/O Pin Constants int S1 = 2; // Float Switch 1 int S2 = 3; // Float Switch 2 int S3 = 4; // Manual Switch 1
int K1 = 8; // Relay K1 - Solenoid for Tank 1 int K2 = 9; // Relay K2 - Solenoid for Tank 2 int K3 = 10; // Relay K3 - Solenoid for Manual Use int K4 = 11; // Relay K4 - Water Pump Relay
void setup() { // Initialize the pins, define digital I/O Pin Use pinMode(S1, INPUT); pinMode(S2, INPUT); pinMode(S3, INPUT); pinMode(K1, OUTPUT); pinMode(K2, OUTPUT); pinMode(K3, OUTPUT); pinMode(K4, OUTPUT); digitalWrite(S1, HIGH); digitalWrite(S2, HIGH); digitalWrite(S3, HIGH); } // Begin Water Tank 1 Logic void loop() { // If Switch 1 is Low, Water Low, First check if no other switches are LOW if (digitalRead(S1) == LOW && digitalRead(S2) == HIGH && digitalRead(S3) == HIGH) { digitalWrite(K1,HIGH); digitalWrite(K4,HIGH); } else { digitalWrite(K1,LOW); digitalWrite(K4,LOW); } // If Switch 2 is Low, Water Low, First check if no other switches are LOW if (digitalRead(S2) == LOW && digitalRead(S1) == HIGH && digitalRead(S3) == HIGH) { digitalWrite(K2,HIGH); digitalWrite(K4,HIGH); } else { digitalWrite(K2,LOW); digitalWrite(K4,LOW); } // If Switch 3 is Low, Water Low, First check if no other switches are LOW if (digitalRead(S3) == LOW && digitalRead(S1) == HIGH && digitalRead(S2) == HIGH) { digitalWrite(K3,HIGH); digitalWrite(K4,HIGH); } else { digitalWrite(K3,LOW); digitalWrite(K4,LOW); } }
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Sr. Member
Karma: 0
Posts: 302
|
 |
« Reply #3 on: May 04, 2012, 11:28:53 am » |
seems good from here(says he while squinting lol). Serious ! Thats how i probably would do it
|
|
|
|
|
Logged
|
10 LET Loop=Infinite 20 GO TO 10
|
|
|
|
Global Moderator
UK
Offline
Brattain Member
Karma: 137
Posts: 19006
I don't think you connected the grounds, Dave.
|
 |
« Reply #4 on: May 04, 2012, 11:34:15 am » |
You could read all the conditions as single bits, and pack them into a variable, then use a switch/case construct to set the outputs.
|
|
|
|
|
Logged
|
Pete, it's a fool looks for logic in the chambers of the human heart.
|
|
|
|
Switzerland
Offline
Faraday Member
Karma: 69
Posts: 3256
|
 |
« Reply #5 on: May 04, 2012, 11:36:04 am » |
Seems like you wanna use a state machine. Define a variable as your state: byte state = 0; Then you can specify for every state what you wanna do in this case. One possibility might be to change to another state. p.e.: switch (state) { case 0: if (digitalRead(4) == LOW) { state = 1; // change to next state } breaik; case 1: // do whatever you think is appropriate here break; default: // show some error because we reached an undefined state } This is much easier to maintain than to have dozens of "if" statements with every possibility.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Sr. Member
Karma: 0
Posts: 302
|
 |
« Reply #6 on: May 04, 2012, 11:45:47 am » |
Definitely a good option if it gets complicated. check here for some simple examples and even a library
|
|
|
|
|
Logged
|
10 LET Loop=Infinite 20 GO TO 10
|
|
|
|
New Jersey
Offline
Edison Member
Karma: 24
Posts: 2345
|
 |
« Reply #7 on: May 04, 2012, 12:13:33 pm » |
I don't think your latest version isn't going to work as intended. Assume that S1 is low and the other two are high. The first if turns on solenoid one and the water pump. Very shortly after, the second if will be false (because S2 is high), so it turns off solenoid two which is ok and then turns off the water pump, which isn't.
One way to do it is once you detect a need for water, set the outputs and then loop waiting for the switch to go high again. A timeout in the loop might help, which would also give the other tanks a turn.
More simply, put a long delay between each if so that say, ten seconds of water can flow.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 38
|
 |
« Reply #8 on: May 04, 2012, 08:25:34 pm » |
A few things and thanks for your suggestions. One, for some reason I can't get the arduino to output correctly. It will only switch relay K1. And even when it was working, as stated above, if you hit switch 1, it turns it on. Then when you press switch 2 at the same time, it turns it off. (both outputs) So perhaps this code is not the way I want to go. I don't quite understand how to apply the switch case to my scenario, knowing my logic says no 2 solenoids can be open at the same time. I've enclosed my latest code below. Thanks again for all your help. /* Water Controller This system controls water flow with 1 pump, 2 water tanks, 2 water level float switches, and 1 manual switch. Conditions are set so that the pump is only feeding one source at any given time, to not choke the water supply or overload the pump. Only the manual switch can activate it's solenoid to bring water in as it is feeding from one of the tanks. If two switches are low at the same time the system will reject the others until the first one is high again. Created May 5, 2012 by Brian Sheldon */
// Digital I/O Pin Constants int S1 = 2; // Float Switch 1 int S2 = 3; // Float Switch 2 int S3 = 4; // Manual Switch 1
int K1 = 8; // Relay K1 - Solenoid for Tank 1 int K2 = 9; // Relay K2 - Solenoid for Tank 2 int K3 = 10; // Relay K3 - Solenoid for Manual Use int K4 = 11; // Relay K4 - Water Pump Relay
void setup() { // Initialize the pins, define digital I/O Pin Use pinMode(S1, INPUT); pinMode(S2, INPUT); pinMode(S3, INPUT); pinMode(K1, OUTPUT); pinMode(K2, OUTPUT); pinMode(K3, OUTPUT); pinMode(K4, OUTPUT); digitalWrite(S1, HIGH); digitalWrite(S2, HIGH); digitalWrite(S3, HIGH); }
void loop() { // Begin Water Tank 1 Logic // If Switch 1 is Low, Water Low, First check if no other switches are LOW if (digitalRead(S1) == LOW && digitalRead(S2) == HIGH && digitalRead(S3) == HIGH) { digitalWrite(K1,HIGH); digitalWrite(K4,HIGH); } else { digitalWrite(K1,LOW); digitalWrite(K4,LOW); } // Begin Water Tank 2 Logic // If Switch 2 is Low, Water Low, First check if no other switches are LOW if (digitalRead(S2) == LOW && digitalRead(S1) == HIGH && digitalRead(S3) == HIGH) { digitalWrite(K1,HIGH); digitalWrite(K4,HIGH); } else { digitalWrite(K1,LOW); digitalWrite(K4,LOW); } // Manual Switch 3 Logic // If Switch 3 is Low, Water Low, First check if no other switches are LOW if (digitalRead(S3) == LOW && digitalRead(S2) == HIGH) { digitalWrite(K3,HIGH); digitalWrite(K4,HIGH); } else { digitalWrite(K3,LOW); digitalWrite(K4,LOW); } }
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #9 on: May 04, 2012, 08:38:38 pm » |
So perhaps this code is not the way I want to go. I don't quite understand how to apply the switch case to my scenario, knowing my logic says no 2 solenoids can be open at the same time. I've enclosed my latest code below. Do you have a hardware problem or a software problem? The only way to know is to add some Serial.print() statements, to output data. Read AND STORE the state of each switch AND PRINT IT! if (digitalRead(S1) == LOW && digitalRead(S2) == HIGH && digitalRead(S3) == HIGH) if (digitalRead(S2) == LOW && digitalRead(S1) == HIGH && digitalRead(S3) == HIGH) if (digitalRead(S3) == LOW && digitalRead(S2) == HIGH)
Why do you need to keep reading the switches? Oh, yeah, it's because you don't save what you read.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 113
|
 |
« Reply #10 on: May 04, 2012, 11:22:57 pm » |
Seems like your rather over complicating it, if I'm understanding your logic you need keep something happening until it no longer needs it then go back and service the next thing. Pop the pin of the variable and keep that state till it's fulfilled. So something like this: if (digitalRead(S1) == LOW && curS == 0) { \\ Do Stuff curS = S1; // Locks us to S1 untill it's high } else if (digitalRead(S1) == HIGH && curS == S1 ) } //Undo S1 Stuff curS = 0; // This releases the lock }
Just repeat that block for as many input you have. Now I would say you should de-bounce the inputs and outputs as you do not want to cycle relays and solenoids at high frequencies you will break them.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 38
|
 |
« Reply #11 on: May 06, 2012, 09:18:49 am » |
Silas,
Do I first define curS in the beginning of the program? Because if i put it where you have it in the scope at the end after "do stuff" I get an error that "curS" wasn't defined in the scope.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 38
|
 |
« Reply #12 on: May 06, 2012, 09:58:29 am » |
My followup question was anything but vague, it's quite specific. I asked him if I need to first define the item at the beginning at the code or not, because as is it doesn't work.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Sr. Member
Karma: 0
Posts: 302
|
 |
« Reply #13 on: May 06, 2012, 10:07:10 am » |
My bad...Confused the post with another i still had open...I do apologise !!! Proves we humans aint good at multitasking !!!
|
|
|
|
|
Logged
|
10 LET Loop=Infinite 20 GO TO 10
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 38
|
 |
« Reply #14 on: May 06, 2012, 11:40:41 am » |
No worries! I just want to make things work!  Silas, in regards to your example, I think I see your point now. So here is my modified code. The loop is limited to 1 switch at the moment for simplicity. (My logic of adding stuff till it breaks or doesn't work!) This works as said, but when I release switch 1, it doesn't turn off the outputs. I can't at the moment figure out why? What am I missing? // Digital Input Pin Constants const int S1 = 2; // Float Switch 1 const int S2 = 3; // Float Switch 2 const int S3 = 4; // Manual Switch 1 // Digital Output Pin Constants const int K1 = 8; // Relay K1 - Solenoid for Tank 1 const int K2 = 9; // Relay K2 - Solenoid for Tank 2 const int K3 = 10; // Relay K3 - Solenoid for Manual Use const int K4 = 11; // Relay K4 - Water Pump Relay // Variables int curS; void setup() { // Initialize the pins, define digital I/O Pin Use pinMode(S1, INPUT); pinMode(S2, INPUT); pinMode(S3, INPUT); pinMode(K1, OUTPUT); pinMode(K2, OUTPUT); pinMode(K3, OUTPUT); pinMode(K4, OUTPUT); digitalWrite(S1, HIGH); digitalWrite(S2, HIGH); digitalWrite(S3, HIGH); Serial.begin(9600); }
void loop() {
if (digitalRead(S1) == LOW && curS == 0) { Serial.print("Filling Tank 1"); digitalWrite(K1, HIGH); delay(3000); digitalWrite(K4, HIGH); curS = S1; } else if (digitalRead(S1) == HIGH && curS == 1) { digitalWrite(K4, LOW); delay(3000); digitalWrite(K1, LOW); curS = 0; } }
|
|
|
|
|
Logged
|
|
|
|
|
|