Conditional statement help

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);
  }
}

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 ?!?

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);
  }
}

seems good from here(says he while squinting lol).
Serious !
Thats how i probably would do it

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.

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.

Definitely a good option if it gets complicated. check here for some simple examples and even a library

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.

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);
  }
}

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.

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.

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.

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.

My bad...Confused the post with another i still had open...I do apologise !!! Proves we humans aint good at multitasking !!!

No worries! I just want to make things work! :slight_smile:

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;
  }
}
curS = S1;

Why are you assigning the variable the pin number of the sensor?

Nevermind I had the code wrong. It works now! Thanks so much. Now to add the rest of the inputs and work out the serial posts, as well as the debounce. I could imagine the way the float switches work that could be an issue.