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.
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.
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?
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();
}
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()?
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);
}
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.