I've programmed a TFT with a main menu with two choices. After you've made the first choice, you'll enter a new page with new new alternatives. From there, I want to have a button that is "back to menu", apart from the other buttons. As my code is structured, I want to restart the loop.
else if(p1.x<40 && p1.y<40){
loop();
}
Is this solution fine, or is it "bad code"? It obviously re-enters the loop and works fine, but it seems like an easy way out.
Definitely "bad code". Every time that call happens a little more stack space is used up. Eventually, the stack will overflow and your sketch will crash.
Thanks for fast replies. I tried to work around it with breaks and return statements but the code got messy even though it worked. But I'll try again and see if I can figure something out!
Not sure what for you "messy" is.
calling loop() from inside functions is the most messiest thing you can code.
it should be very easy to exit / terminate any functions
If you post your complete sketch by using this method that adds the code-tags
There is an automatic function for doing this in the Arduino-IDE
just three steps
press Ctrl-T for autoformatting your code
do a rightclick with the mouse and choose "copy for forum"
In this case, I called a "helpfunction" within the actual function making the choice. So I will have to return two times, with some conditions set for what and when to return. And back in the loop, I'll need to write some condition that makes the loop skip functions afterwards and restarting. Eventhough it might be more "messy" to calling loop() inside another function: having code like
post your complete sketch
by using this method that adds the code-tags
There is an automatic function for doing this in the Arduino-IDE
just three steps
press Ctrl-T for autoformatting your code
do a rightclick with the mouse and choose "copy for forum"
Thanks for your will to help. I've been doing this as a work project, and even though it is pretty basic I don't feel good about posting the whole sketch online as it belongs to the company I'm working for. But I can explained a bit more detailed.
The whole project is about driving a motor at a certain RPM or Power.
I have a method called setValue(). In this method, you firstly choose between RPM and Power - as displayed in a menu. After that choice I call a method within the method, called chooseNumber(), that chooses one digit of the wanted value. This because RPM needs 4 digits, but Power only 3.
So the problem is that if I return something like -1 from chooseNumber() if "Stop button" is pressed, I need to check if any of the numbers read is -1, and if that is the case return -1 from setValue() (which normally returns the set value), and then only execute the rest of the methods in the loop if setValue!=-1.
As said, even if it works it seems a bit off to solve it that way. I though about writing chooseNumber to set the whole value and that would solve some problems, but not all anyways.
However I'm happy for any input. Thanks in advance!
A State Machine is definitely what you want.
In a state machine you set a variable to track what state you are in.
You can use that variable to move from one state to any other state you wish.
You could have a "Choose RPM" state
a "Chose Number" state, a "Stop" state etc.
Very clean way to do what you describe.
Thanks for all response. I can't really however wrap my head around the code structure of a State Machine. If a certain button is pressed, the state will change. But how? Should I write one method that loops with if statements?
int set_value(){
while(true){
if(state = 1) {
if(choose_number(1)){
state = 2;
}
}
else if (state == 2){
if(choose_number(2)){
state = 3; ¨
}
}
...
}
}
Getting your head around the concept is more important than the coding.
You need to understand and think “loop”! Don’t think linear abc. Think loop abcabcabcabc. The microcontroller appears to do multiple things at once because it loops so fast and each time through loop it updates according to what the code says. You need to make your code fast, so no delays or blocking code, so that it appears instantaneous to human timescales.
When you understand that concept then you will realise you can’t just tell the code to do x because it will do x over and over again very fast. You need to remember the state of something from one loop to the next so that you can manipulate it at the appropriate time or condition.
The common example is blink without delay. To blink an LED without blocking code you need to first turn on the LED, simple digitalwrite code. Next time through loop it would just do the same again and again so you need some way to know that you are in a new state and start a timer. So you set a variable eg LEDState to 1. Now you implement your basic timing code using millis ie you check the clock each time through the loop and see if x time has past. A simple if statement can then be used to toggle the LED, ie if the time now minus the startTime is greater than the delayTime I want to change the LEDState. In this way you are able to toggle between two states when a condition is met.
You can do this with any number of states. You just define the states you need, the condition that sets the state and the function you wish to run in each state. Each time through loop the microcontroller checks your state variable, implements the code related to that state and then changes state depending on if the changing state conditions are met.