Can I have Two While statements in succession??

Hello, I am attempting to write a function that will enable me to do some testing and tuning to my project. I want to be able to run the motor up or down depending on a couple of momentary switches being pressed (one for up and one for down). my question is, is it ok to use two while statements in succession, or do i need to break up my code into multiple functions.

void testmode() 
{
  digitalWrite(TestLed, HIGH);
  TestUpState = digitalRead(TestUp);
  TestDwnState = digitalRead(TestDwn);
  while (TestUpState == HIGH) 
     {
      analogWrite(PWM, 255);
      digitalWrite(DIR, HIGH);
     }
      analogWrite(PWM, 0);
  while (TestDwnState == HIGH);
     {
      analogWrite(PWM, 255);
      digitalWrite(DIR, LOW);
     }
      analogWrite(PWM, 0);    
}

Sure, go for it.

-jim lee

  while (TestUpState == HIGH)
     {
      analogWrite(PWM, 255);
      digitalWrite(DIR, HIGH);
     }

Once TestUpState is HIGH and the while loop is entered how will TestUpState change to exit the loop ?

while the answer to your question is yes, there's no need for either while loop.

since loop() is repeatedly called, the button state can determine PWM and DIR value used to unconditionally call digitalwrite() and analogWrite() each iteration of loop(). PWM should be set to zero if neither button is pressed.

Your code will not work as you expect, the first while loop will run forever and do nothing. This is probably more like what you want:

void testmode()
{
  digitalWrite(TestLed, HIGH);
  if (digitalRead(TestUp) == HIGH)
  {
      analogWrite(PWM, 255);
      digitalWrite(DIR, HIGH);
      while (digitalRead(TestUp) == HIGH) {}; //Wait for TestUp to go LOW
      analogWrite(PWM, 0);
  }
  if (digitalRead(TestDwn) == HIGH)
  {
      analogWrite(PWM, 255);
      digitalWrite(DIR, LOW);
      while (digitalRead(TestDwn) == HIGH) {}; //Wait for TestDwn to go LOW
      analogWrite(PWM, 0);   
  }
  //digitalWrite(TestLed, LOW); //Maybe?
}

But it is still not a good approach.

UKHeliBob:

  while (TestUpState == HIGH)

{
      analogWrite(PWM, 255);
      digitalWrite(DIR, HIGH);
    }



Once TestUpState is HIGH and the while loop is entered how will TestUpState change to exit the loop ?

If I am using a momentary switch, wont the while statement exit once the button is released thus changing the TestUpState to LOW ?
what if I add these lines to the while code?

  while (TestUpState == HIGH) 
     {
      analogWrite(PWM, 255);
      digitalWrite(DIR, HIGH);
      TestUpState = digitalRead(TestUp);      
     }
      analogWrite(PWM, 0);

If I am using a momentary switch, wont the while statement exit once the button is released thus changing the TestUpState to LOW ?

No. You are not reading the button pin in the while loop so TestUpState will not change state once the code is in the while loop

sorry i think i was editing my post while you were answering. I added the line

TestUpState = digitalRead(TestUp);

to my while statement loop will that fix it?

Do a bit of reading on while loops. You will learn how to use one and also why you shouldn’t.

Basically a while loop traps your code until the statement becomes false. As you have found, once you enter one you need something in it to update the statement otherwise it will never be false. Since the main loop already loops (as the name implies) you generally don’t need one and you will have far more responsive and dynamic code if you avoid it

And to answer your question, yes, you can have as many while loops as you want or your memory allows but you should always question why you need 1 let alone 2

Ps serial.print is a great way to reveal if you are stuck in a while loop or successfully escaping one

strebor71:
sorry i think i was editing my post while you were answering. I added the line

TestUpState = digitalRead(TestUp);

to my while statement loop will that fix it?

Reading the state of the pin into TestUpState inside the while loop will allow it loop to end. Depending on what you want to do that may or may not be the best way to achieve it

ok, so a little more background. I currently have a working project for a chicken coop door that opens and closes when a certain light level has been reached. the code works, the door works, the motor works. What I am wanting to do is add the ability to "break" into the existing code (with a toggle switch TestBtn) to give me the ability to run the motor up or down manually by pressing a few momentary switches (TestUp & TestDwn). as the code now exists the only way to run the motor up or down is by covering or uncovering the photoresistor. That is a pain in the butt when an issue comes up where i need to do maintenance to the mechanism or what have you. having the ability to put the system into a "test" mode is what i want to accomplish. I was planning on doing that with a while statement at the top of my main code and a function "testmode".

while (digitalRead(TestBtn) == HIGH) {
testmode();
}

the function testmode:

void testmode() 
{
  digitalWrite(TestLed, HIGH);
  TestUpState = digitalRead(TestUp);
  TestDwnState = digitalRead(TestDwn);
  while (TestUpState == HIGH) 
     {
      analogWrite(PWM, 255);
      digitalWrite(DIR, HIGH);
      TestUpState = digitalRead(TestUp);      
     }
      analogWrite(PWM, 0);
  while (TestDwnState == HIGH);
     {
      analogWrite(PWM, 255);
      digitalWrite(DIR, LOW);
      TestDwnState = digitalRead(TestDwn);     
     }
      analogWrite(PWM, 0);  
  digitalWrite(TestLed, LOW); // thanks for the suggestion 
}

will this make that happen?

You need an up function and a down function. You need a light sensor states and a buttons press states

If lightSensor state is 1 (daylight) and buttonDownstate is 0 Then up
If 1 and 1 down

If light sensor state is 0 and button up state is 0 then Down
If 0 and 1 up

Just my quick thoughts without code syntax

Nested ifs may be better
If LSS 1{
If BDS 1 {
Down();}
Else up
}

Only idea on phone so not coding

pmagowan:
You need an up function and a down function. You need a light sensor states and a buttons press states

If lightSensor state is 1 (daylight) and buttonDownstate is 0 Then up
If 1 and 1 down

If light sensor state is 0 and button up state is 0 then Down
If 0 and 1 up

Just my quick thoughts without code syntax

no, sorry. dont need to do anything with light states or daylight. I just want to add manual control over the motor when i need it. that is why i did not want to include the rest of the code in this convo. I just need help with this function. the rest of the code is fine.

strebor71:
that is why i did not want to include the rest of the code in this convo. I just need help with this function. the rest of the code is fine.

Giving information piecemeal wastes everyone's time.

What does PWM mean in your code? How about DIR?
What exactly is this testmode() function intended to accomplish? Is this really the sort of thing that should be done in its own function, rather than in loop()?

It would help if we could see your entire sketch.

I think if this was my project I would trigger the override when either momentary is pushed down without needing the toggle switch.

Once one of the buttons is pressed the program stays in testmode() until it is released. If you pass the pin of the pressed button and the value to write it simplifies the function a bit, since you only need to read the pin of the button that is already pressed.

void loop()
{
  // override up
  if ( digitalRead(TestUp) == HIGH ) testmode(TestUp, HIGH);

  // override down
  if ( digitalRead(TestDwn) == HIGH ) testmode(TestDwn, LOW);

}

void testmode(byte btnPin, byte val)
{
  digitalWrite(TestLed, HIGH);

  // while button is pressed
  while ( digitalRead(btnPin) == HIGH )
  {
    analogWrite(PWM, 255);
    digitalWrite(DIR, val);
  }
  analogWrite(PWM, 0);

  digitalWrite(TestLed, LOW);

}

Why complicate things ?

You say that you have a working program that controls the door based on the light level and it appears that you are willing to introduce more hardware, including a test mode switch and up and down buttons to control the door manually. So, why not simply keep the program as it is and use switches to change the state of the input from the light sensor to the program to fake the light level ?

If the code is not operated as a state machine, introducing manual override is tricky as by definition an override gives an order that the automatic system would not perform.

Unless you have some peoper state management, The microsecond after you release the manual override button, the automatic system will kick back in, see that the state is incorrect (like it’s dark and the door is open) and issue an opposite order to what you just did.

So you need to look at your system as a whole, and code what needs to happen if you have overridden a system’s decision.