Replace infinite "While(1)" loop with If statement !

Hello Guys ;

I'm trying to write a code to do the following:
When I press switch 1 , the Loop will ignore switch 2 and Vice Versa. I use for this an infinite loop "while(1)" and It's working great , the problem is ofc I can't call functions from outside the while(1) loop so if I want to display for example I must write Serial.println("switch1 on"); inside the infinite loop !
So how can I replace the while so I can call functions in order to add more actions when the switch is HIGH.

int switch1 = 37;
int switch2 = 38;

int led1 = 34;
int led2 = 35;

enum disVar
{
  serial,
  serial1,
  serial2
};

byte disVar = serial;


void setup()
{
  pinMode(switch1, INPUT);
  pinMode(switch2, INPUT);

  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);

  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);

  Serial.begin(9600);
}


void loop()
{
  DisplayDataLCD();
  checkswitch1();
  checkswitch2();
  delay(250);
}


void checkswitch1()
{
  while (1)
  {
    if (digitalRead(switch1) == HIGH)
    {
      disVar = serial1;
      digitalWrite(led1, HIGH);
    } else
    {
      disVar = serial;
      digitalWrite(led1, LOW);
      break;
    }
  }
}

void checkswitch2()
{
  while (1)
  {
    if (digitalRead(switch2) == HIGH)
    {
      disVar = serial2;
      digitalWrite(led2, HIGH);
    } else
    {
      disVar = serial;
      digitalWrite(led2, LOW);
      break;
    }
  }
}

void DisplayDataLCD()
{
  switch (disVar)
  {
    case  serial1 :
      {
        Serial.println("switch1 on");
        break;
      }
    case  serial2 :
      {
        Serial.println("switch2 on");
        break;
      }
    case serial:
      {
        Serial.println("greetings");
        break;
      }
      break;
  }
}

Thx )))))

enum disVar

{
  serial,
  serial1,
  serial2
};

byte disVar = serial;

You are abusing the compiler's generosity. You should not use a byte for a variable which is intended to contain a disVar. It is also confusing to use the same name for the enum definition as well as the instance.

So don't use the while(1) at all. It appears to be doing nothing for you.

My mistake it's like this :

enum disVarValues
{
  serial,
  serial1,
  serial2
};

byte disVar = serial;

the While(1) loop is making the other Switch ignored , meaning whenswitch1 is HIGH , if I press switch2 nothing happens ! do you get my point ?

Then you should

enum disVarValues disVar = serial;

Then the compiler will alert you if you do something stupid like disVar = 42;

Why do you have the while(1)s at all?

B1ng05:
My mistake it's like this :

enum disVarValues

{
 serial,
 serial1,
 serial2
};

byte disVar = serial;




the While(1) loop is making the other Switch ignored , meaning whenswitch1 is HIGH , if I press switch2 nothing happens ! do you get my point ?
enum disVarValues : byte
{
  serial,
  serial1,
  serial2
};

disVarValues disVar = serial;

I think what you are saying in your first post is that you have 3 states, a no-input state, when both switches are low, and a state for each switch, which if you have entered serial1, with switch 1, you want to stay there until switch 1 goes low. Vice versa, if you have entered serial2, with switch 2, you want to stay there. What's ironic is that you've set up a state machine but have no idea that you are duplicating your work.

byte switch1 = 37;
byte switch2 = 38;

byte led1 = 34;
byte led2 = 35;

enum disVarValues : byte
{
  serial,
  serial1,
  serial2
};

disVarValues disVar = serial;


void setup()
{
  pinMode(switch1, INPUT);
  pinMode(switch2, INPUT);

  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);

  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);

  Serial.begin(9600);
}


void loop()
{
  DisplayDataLCD();
  delay(250);
}


bool checkswitch1() {
  if (digitalRead(switch1) == HIGH) return true;
  else return false;
}

bool checkswitch2() {
  if (digitalRead(switch2) == HIGH) return true;
  else return false;
}

void DisplayDataLCD()
{
  switch (disVar)
  {
    case  serial1 :
      {
        Serial.println("switch1 on");
        if (!checkswitch1()) {
          disVar = serial;
          digitalWrite(led1, LOW);
          break;
        }
        break;
      }
    case  serial2 :
      {
        Serial.println("switch2 on");
        if (!checkswitch2()) {
          disVar = serial;
          digitalWrite(led2, LOW);
          break;
        }
        break;
      }
    case serial:
      {
        Serial.println("greetings");
        if (checkswitch1()) {
          digitalWrite(led1, HIGH);
          disVar = serial1;
          break;
        }
        if (checkswitch2()) {
          digitalWrite(led2, HIGH);
          disVar = serial2;
          break;
        }
        break;
      }
  }
}

I don't Understand what's your problem with enum ?!! I tried all of these and they all worked the same !!! no warning no error !!!!

enum disVar
{
  serial,
  serial1,
  serial2
};

byte disVar = serial;

or

enum DisplayValue
{
  serial,
  serial1,
  serial2
};

DisplayValue disVar  = serial;

or

enum disVarValues : byte
{
  serial,
  serial1,
  serial2
};

disVarValues disVar = serial;

or I can even replace enum with just simple const int variables like this

const int  serial = 0;
const int serial1 = 1;
const int serial2 = 2;

int disVar  = serial;

My question is not about enum , I want to replace while(1) with "if" statement.

Here's the code without while(1) loop , it's working without any problem, when i turn on switch1 ,led1 goes on and "switch1 on" displayed , if i turn on switch2 led2 goes on and "switch2 on" displayed , but what I want switch2 to be ignored while switch1 is on , or switch1 ignored while switch2 is on !!

int switch1 = 37;
int switch2 = 38;

int led1 = 34;
int led2 = 35;

bool  anyButtonPressed = false;


const int  serial = 0;
const int serial1 = 1;
const int serial2 = 2;

int disVar  = serial;


void setup()
{
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(switch1, INPUT);
  pinMode(switch2, INPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  Serial.begin(9600);
}


void loop()
{
  DisplayDataLCD();
  checkswitch1();
  checkswitch2();
  delay(250);
}


void checkswitch1()
{
  if (digitalRead(switch1) == HIGH)
  {
    disVar = serial1;
    digitalWrite(led1, HIGH);
  } else
  {
    disVar = serial;
    digitalWrite(led1, LOW);

  }
}

void checkswitch2()
{

  if (digitalRead(switch2) == HIGH)
  {
    disVar = serial2;
    digitalWrite(led2, HIGH);
  } else
  {
    //disVar = serial;
    digitalWrite(led2, LOW);

  }
}

void DisplayDataLCD()
{
  switch (disVar)
  {
    case serial:
      {
        Serial.println("greetings");
        break;
      }
    case  serial1 :
      {
        Serial.println("switch1 on");
        break;
      }
    case  serial2 :
      {
        Serial.println("switch2 on");
        break;
      }
      break;
  }
}

Remove all the while(1)'s.

The enum won't give errors if you use it correctly. The reason for using the more-restrictive declaration is so that the compiler can find errors such as assigning an invalid value to disVar.

B1ng05:
Here's the code without while(1) loop , it's working without any problem, when i turn on switch1 ,led1 goes on and "switch1 on" displayed , if i turn on switch2 led2 goes on and "switch2 on" displayed , but what I want switch2 to be ignored while switch1 is on , or switch1 ignored while switch2 is on !!

Did you look at the code I presented in my last post? I use the state machine you set up to eliminate the use of while(1). Do you understand my approach? Does it work for you? Does it accomplish your objective?

Perehama:
Did you look at the code I presented in my last post? I use the state machine you set up to eliminate the use of while(1). Do you understand my approach? Does it work for you? Does it accomplish your objective?

Oh I'm sorry I replied but something wierd happenned !! ,anyways Thank you so much I tried your code and that's part of what I want , I even gave you a karma :stuck_out_tongue: , so you're right i have 3 states, a no-input state, when both switches are low, and a state for each switch (y) .

Now I tried to simplify my original code that's why it doesn't show all the functions , what I want is for the checkswitch1() and checkswitch2() functions to stay in loop and in the same time to get the 3 states !

B1ng05:
what I want is for the checkswitch1() and checkswitch2() functions to stay in loop

Now, since this contradicts, "I want to ignore checkswitch2() while checkswitch1() is HIGH" you have to explain with more information. What exactly are you trying to do and why do you want them to remain in the loop? You might be interested to know that the void loop() is nothing more than a while(1) in for (,,) form. See arduino/main.cpp.

Thx , I know tht void loop() == while(1) , so I'll try to explain more :state one is when both switches are low,so I get the greetings display , state two for switch1 and state three for switch2 : lets say with switch1 I can turn a fan and with switch2 I can turn a Uv lamp , If I turn on the Fan (=>switch1==HIGH) , the Uv lamp can't be on, meaning (=>switch2==LOW) , and if the Uv lamp is on than the fan can't be turned on !

The DisplayDataLCD function is just for priting and dislaying. here's the code :

byte switch1 = 37;
byte switch2 = 38;

byte led1 = 34;
byte led2 = 35;

byte FanRelay = 22;
byte UvRelay = 23 ;

enum disVarValues : byte
{
  serial,
  serial1,
  serial2
};

disVarValues disVar = serial;


void setup()
{
  pinMode(switch1, INPUT);
  pinMode(switch2, INPUT);

  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);

  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);

  digitalWrite(FanRelay , HIGH);
  digitalWrite(UvRelay , HIGH);

  pinMode(FanRelay, OUTPUT);
  pinMode(UvRelay, OUTPUT);

  Serial.begin(9600);
}


void loop()
{
  DisplayDataLCD();

  //Check switch1 turns a FAN through FanRelay
  if (digitalRead(switch1) == HIGH)
  {
    digitalWrite(FanRelay , LOW);
    digitalWrite(led1, HIGH);
    disVar = serial1;

  } else
  {
    digitalWrite(FanRelay , HIGH);
    digitalWrite(led1, LOW);
    disVar = serial;
  }

  //Check switch2 turns a UV Lamp through UvRelay
  if (digitalRead(switch2) == HIGH)
  {
    digitalWrite(UvRelay , LOW);
    digitalWrite(led2, HIGH);
    disVar = serial2;

  } else
  {
    digitalWrite(UvRelay , HIGH);
    digitalWrite(led2, LOW);
  }

  delay(250);
}


/*bool checkstate1() {
  if (digitalRead(switch1) == HIGH) return true;
  else return false;
  }

  bool checkstate2() {
  if (digitalRead(switch2) == HIGH) return true;
  else return false;
  }
*/
void DisplayDataLCD()
{
  switch (disVar)
  {
    case  serial :
      {
        Serial.println("greetings");
      }
    case  serial1 :
      {
        Serial.println("switch1 on");
      }
      break;

    case serial2:
      {
        Serial.println("switch2 on");
      }
      break;
  }
}

Danke.

B1ng05:
Thx , I know tht void loop() == while(1) , so I'll try to explain more :state one is when both switches are low,so I get the greetings display , state two for switch1 and state three for switch2 : lets say with switch1 I can turn a fan and with switch2 I can turn a Uv lamp , If I turn on the Fan (=>switch1==HIGH) , the Uv lamp can't be on, meaning (=>switch2==LOW) , and if the Uv lamp is on than the fan can't be turned on !

The DisplayDataLCD function is just for priting and dislaying. here's the code :

byte switch1 = 37;

byte switch2 = 38;

byte led1 = 34;
byte led2 = 35;

byte FanRelay = 22;
byte UvRelay = 23 ;

enum disVarValues : byte
{
 serial,
 serial1,
 serial2
};

disVarValues disVar = serial;

void setup()
{
 pinMode(switch1, INPUT);
 pinMode(switch2, INPUT);

pinMode(led1, OUTPUT);
 pinMode(led2, OUTPUT);

digitalWrite(led1, LOW);
 digitalWrite(led2, LOW);

digitalWrite(FanRelay , HIGH);
 digitalWrite(UvRelay , HIGH);

pinMode(FanRelay, OUTPUT);
 pinMode(UvRelay, OUTPUT);

Serial.begin(9600);
}

void loop()
{
 DisplayDataLCD();

//Check switch1 turns a FAN through FanRelay
 if (digitalRead(switch1) == HIGH)
 {
   digitalWrite(FanRelay , LOW);
   digitalWrite(led1, HIGH);
   disVar = serial1;

} else
 {
   digitalWrite(FanRelay , HIGH);
   digitalWrite(led1, LOW);
   disVar = serial;
 }

//Check switch2 turns a UV Lamp through UvRelay
 if (digitalRead(switch2) == HIGH)
 {
   digitalWrite(UvRelay , LOW);
   digitalWrite(led2, HIGH);
   disVar = serial2;

} else
 {
   digitalWrite(UvRelay , HIGH);
   digitalWrite(led2, LOW);
 }

delay(250);
}

/*bool checkstate1() {
 if (digitalRead(switch1) == HIGH) return true;
 else return false;
 }

bool checkstate2() {
 if (digitalRead(switch2) == HIGH) return true;
 else return false;
 }
*/
void DisplayDataLCD()
{
 switch (disVar)
 {
   case  serial :
     {
       Serial.println("greetings");
     }
   case  serial1 :
     {
       Serial.println("switch1 on");
     }
     break;

case serial2:
     {
       Serial.println("switch2 on");
     }
     break;
 }
}




Danke.

What you want to do is rename your display function or copy paste it into the main loop, and then call a display function from within each state. The state machine is essential to what you wish to achieve.

B1ng05:
Thx , I know tht void loop() == while(1) , so I'll try to explain more :state one is when both switches are low,so I get the greetings display , state two for switch1 and state three for switch2 : lets say with switch1 I can turn a fan and with switch2 I can turn a Uv lamp , If I turn on the Fan (=>switch1==HIGH) , the Uv lamp can't be on, meaning (=>switch2==LOW) , and if the Uv lamp is on than the fan can't be turned on !

OK, so now we are getting close to the problem. Your code looks pretty good - especially the part with the display function. That looks at the current state and displays the correct thing.

Your main loop which is reading the switches isn't quite so smart. It doesn't look at the state. It just reads the switches. So if you were in the serial1 (fan) state and you press the UV button then it should turn off the fan. It could only do that if it looked at the state before setting it to serial2.

One further refinement for the display: if the state hasn't changed then you don't need to write anything new to the display. This will stop it flickering and save a lot of processor time dealing with the display. So the display should have an internal static variable which remembers what the state was, that was last written to the display. Only update the display if it changes.

void DisplayDataLCD()
{
  static disVarValues disVarLast = serial1;  //start it at a value which disVar DOESN'T start at.
  if(disVar == disVarLast) return; //no need to update the display
  disVarLast = disVar;  //record that this is the last state displayed

  switch (disVar)
     .... continue as normal