Go Down

### Topic: Conditional statement help (Read 3259 times)previous topic - next topic

#### cncb

##### May 04, 2012, 04:01 pm
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!

Code: [Select]
`// constantsint S1 = 2;    // Float Switch 1int S2 = 3;    // Float Switch 2int K1 = 8;    // Relay K1int K2 = 9;    // Relay K2void 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 logicvoid 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);  }}`

#### iyahdub

#1
##### May 04, 2012, 04:25 pm
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 ?!?
10 LET Loop=Infinite
20 GO TO 10

#### cncb

#2
##### May 04, 2012, 06:03 pm
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?

Code: [Select]
`// digital I/O Pin Constants int S1 = 2;    // Float Switch 1int S2 = 3;    // Float Switch 2int S3 = 4;    // Manual Switch 1int K1 = 8;    // Relay K1 - Solenoid for Tank 1int K2 = 9;    // Relay K2 - Solenoid for Tank 2int K3 = 10;   // Relay K3 - Solenoid for Manual Useint K4 = 11;   // Relay K4 - Water Pump Relayvoid 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 Logicvoid 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);  }}`

#### iyahdub

#3
##### May 04, 2012, 06:28 pm
seems good from here(says he while squinting lol).
Serious !
Thats how i probably would do it
10 LET Loop=Infinite
20 GO TO 10

#### AWOL

#4
##### May 04, 2012, 06:34 pm
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.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

#### pylon

#5
##### May 04, 2012, 06:36 pm
Seems like you wanna use a state machine. Define a variable as your state:

Code: [Select]
`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.:

Code: [Select]
`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.

#### iyahdub

#6
##### May 04, 2012, 06:45 pm
Definitely a good option if it gets complicated. check here for some simple examples and even a library
10 LET Loop=Infinite
20 GO TO 10

#### wildbill

#7
##### May 04, 2012, 07:13 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.

#### cncb

#8
##### May 05, 2012, 03:25 am
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.

Code: [Select]
`/*  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 Constantsint S1 = 2;    // Float Switch 1int S2 = 3;    // Float Switch 2int S3 = 4;    // Manual Switch 1int K1 = 8;    // Relay K1 - Solenoid for Tank 1int K2 = 9;    // Relay K2 - Solenoid for Tank 2int K3 = 10;   // Relay K3 - Solenoid for Manual Useint K4 = 11;   // Relay K4 - Water Pump Relayvoid 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);  }}`

#### PaulS

#9
##### May 05, 2012, 03:38 am
Quote
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!

Code: [Select]
`  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.

#### silasmoeckel

#10
##### May 05, 2012, 06:22 am
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:
Code: [Select]
`if (digitalRead(S1) == LOW && curS == 0) {\\ Do StuffcurS = S1; // Locks us to S1 untill it's high}else if (digitalRead(S1) == HIGH && curS == S1 ) }//Undo S1 StuffcurS = 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.

#### cncb

#11
##### May 06, 2012, 04:18 pm
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.

#### cncb

#12
##### May 06, 2012, 04:58 pm
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.

#### iyahdub

#13
##### May 06, 2012, 05:07 pm
My bad...Confused the post with another i still had open...I do apologise !!! Proves we humans aint good at multitasking !!!
10 LET Loop=Infinite
20 GO TO 10

#### cncb

#14
##### May 06, 2012, 06:40 pm
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?

Code: [Select]
`// Digital Input Pin Constantsconst int S1 = 2;    // Float Switch 1const int S2 = 3;    // Float Switch 2const int S3 = 4;    // Manual Switch 1// Digital Output Pin Constantsconst int K1 = 8;    // Relay K1 - Solenoid for Tank 1const int K2 = 9;    // Relay K2 - Solenoid for Tank 2const int K3 = 10;   // Relay K3 - Solenoid for Manual Useconst int K4 = 11;   // Relay K4 - Water Pump Relay// Variablesint 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;  }}`

Go Up

Please enter a valid email to subscribe