Some users are required to navigate multiple functions within their arduino program. The following is a basic/rudimentary navigation system in which users can select their functions they want to execute using push buttons or keyboard. The input (buttons or keyboard) should be setup up separate to do debouncing and should be interrupt driven to respond on an event. This will not be explained in this post. This system is basic and should not be used to execute mission critical functions.
Assume interrupt and input is set up and the user has minimum of a "A", "B', "C" and "back" button.
The system is layers of while and if loops.
Assuming a system hierarchy is built to dictate the navigation. This basic system is limited to each layer having 3 options. But is simple to implement.
The following code is written in c and is not directly for arduino. function calls may be need to changed to match libraries. The system layers while and if loops. The If loop is used navigate deeper into the hierarchy. On entry the button memory bit needs to be reset. This is to avoid the arduino popping straight into every sub tree of the same button input. The while loop is used to keep the arduino within a layer, and allow it to pop back out to the layer before it. The back button needs to be reset on exit of while loop to avoid it popping all the way to the first hierarchical tree. Functions deep within the layer should be executed in short periods of time otherwise there will be a delay before the system can back out of a navigation layer. This system is no way a replacement of using a scheduler, OS or more advanced navigation techniques. Simpler techniques exist such as the two button "select" and "cycle" but the code is a little less easy to implement and the user has a little more problems navigating and miss clicking. Use this code responsibly, since it may contain errors.
//Basic system navigation of functions on arduino
//Designed by : Varoun Hanooman
//Date: 02/01/2016
int keyboard_A_clicked = 0;
int keyboard_B_clicked = 0;
int keyboard_C_clicked = 0;
int keyboard_back_clicked = 0;
int LCD_display_layer1 = 0; //to ensure lcd only displays once
void loop(){
//code that normally is executed
random_function();
//code to print to lcd should run once unless live updating
if(LCD_display_layer1 == 0){
print("Info");
LCD_display_layer1 = 1; // stops display from rewriting
}
if(keyboard_A_clicked == 1){ //go into monitor
keyboard_A_clicked = 0; // reset memory for button
while(keyboard_back_clicked == 0){
print("User should input X or Y to monitor");
if(keyboard_A_clicked == 1){
keyboard_A_clicked = 0;
while(keyboard_back_clicked == 0){
monitorX();
}
keyboard_back_clicked = 0;// reset back button
LCD_display_layer1 = 0; //allow first lcd display to display
}
if(keyboard_B_clicked == 1){
keyboard_B_clicked = 0;
while(keyboard_back_clicked == 0){
monitorY();
}
keyboard_back_clicked = 0;// reset back button
LCD_display_layer1 = 0; //allow first lcd display to display
}
}
keyboard_back_clicked = 0;// reset back button
}
if(keyboard_B_clicked == 1){ //go into monitor
keyboard_B_clicked = 0; // reset memory for button
while(keyboard_back_clicked == 0){
print("Settings");
if(keyboard_A_clicked == 1){
keyboard_A_clicked = 0;
while(keyboard_back_clicked == 0){
//Timing
if(keyboard_A_clicked == 1){
keyboard_A_clicked = 0;
setTimingFast();
}
//Speaker
if(keyboard_B_clicked == 1){
keyboard_B_clicked = 0;
resetTimingSlow();
}
}
keyboard_back_clicked = 0;// reset back button
}
if(keyboard_B_clicked == 1){
keyboard_B_clicked = 0;
while(keyboard_back_clicked == 0){
//Speaker On
if(keyboard_A_clicked == 1){
keyboard_A_clicked = 0;
setSpeakerOn();
}
//Speaker Off
if(keyboard_A_clicked == 1){
keyboard_A_clicked = 0;
setSpeakerOff();
}
}
keyboard_back_clicked = 0;// reset back button
}
}
keyboard_back_clicked = 0;// reset back button
LCD_display_layer1 = 0; //allow first lcd display to display
}
}
jremington:
Actually, it won't on Arduino, for several reasons.
This does not look at all useful and certainly does not serve as a good example for beginners.
Ok basically, I'm not an arduino enthusiasts. I work alot with Microchip microcontrollers and Spartan FPGA boards. My friend, who is a beginner to arduino, asked for an easy way to allow him to do navigation on his arduino. I wrote this algorithm in a similar fashion for him. It works flawlessly and he's really happy with the implementation. I just thought I'd share this info for other users that wants a similar navigation. If you don't like it and can't see its use, it's ok.
VarounHanooman:
Ok basically, I'm not an arduino enthusiasts. I work alot with Microchip microcontrollers and Spartan FPGA boards. My friend, who is a beginner to arduino, asked for an easy way to allow him to do navigation on his arduino. I wrote this algorithm in a similar fashion for him. It works flawlessly and he's really happy with the implementation. I just thought I'd share this info for other users that wants a similar navigation. If you don't like it and can't see its use, it's ok.
It's not a matter of like or dislike. It will shut down about half the hardware that works with the Arduino. It's not that the internal logic is flawed or not useful, it's just that an inline implementation like this will block. To be compatible with the status quo operating environment of the Arduino, you would have to implement this logic as a state machine.
I'm sure you have worked with different OS's as a programmer and learned that there are things you are allowed to do, that will still get you in trouble. This is one of them.
aarg:
It's not a matter of like or dislike. It will shut down about half the hardware that works with the Arduino. It's not that the internal logic is flawed or not useful, it's just that an inline implementation like this will block. To be compatible with the status quo operating environment of the Arduino, you would have to implement this logic as a state machine.
I'm sure you have worked with different OS's as a programmer and learned that there are things you are allowed to do, that will still get you in trouble. This is one of them.
You are correct about needing a state machine. I should have stated that. The logic flows for a finite state machine. Thanks for indicating that.
Hi everyone, this is my first forum post as I just made an account. I am the friend in question who used the nested while-if loops. I consider myself a complete noob when it comes to arduino and definitely not a strong programmer and just wanted to support that it did work. The project I used it for was a Home security system. Had a short time (About 2 months) in which to build the system (Will upload and link my project when I get some time). Just to briefly describe the system, it consists of an Alarm Control Panel, with components used such as a keypad, 4x40 LCD, FONA gsm breakout, DS3231 RTC and an Xbee S2 to receive information wirelessly from sensors.
The sensors I built were wireless door contact, wireless PIR and wireless vibration using the atmega 328p standalone, with Xbee S2's as the communication devices. Considered different options such as running a free OS on the Mega to perform tasks such as writing to LCD and performing different alarm functions, however I did not yet fully understand OS operation enough to implement it within the short timeframe. Ultimately, the use of while-if statements seemed the most logical to me. Aarg is right, I designed the control panel as a state machine, and the sensors are interrupt driven. I know this was by far not the best way to implement such a system, but just wanted to share that as a beginner, I felt proud of what I was able to accomplish within the space of 2 months. I am also looking forward to enhancing my coding capabilities and learning more about this platform. Hope this helped put Varoun's post in a clearer context!
brokensilence51:
Hi everyone, this is my first forum post as I just made an account. I am the friend in question who used the nested while-if loops. I consider myself a complete noob when it comes to arduino and definitely not a strong programmer and just wanted to support that it did work. The project I used it for was a Home security system. Had a short time (About 2 months) in which to build the system (Will upload and link my project when I get some time). Just to briefly describe the system, it consists of an Alarm Control Panel, with components used such as a keypad, 4x40 LCD, FONA gsm breakout, DS3231 RTC and an Xbee S2 to receive information wirelessly from sensors.
The sensors I built were wireless door contact, wireless PIR and wireless vibration using the atmega 328p standalone, with Xbee S2's as the communication devices. Considered different options such as running a free OS on the Mega to perform tasks such as writing to LCD and performing different alarm functions, however I did not yet fully understand OS operation enough to implement it within the short timeframe. Ultimately, the use of while-if statements seemed the most logical to me. Aarg is right, I designed the control panel as a state machine, and the sensors are interrupt driven. I know this was by far not the best way to implement such a system, but just wanted to share that as a beginner, I felt proud of what I was able to accomplish within the space of 2 months. I am also looking forward to enhancing my coding capabilities and learning more about this platform. Hope this helped put Varoun's post in a clearer context!
brokensilence51:
Aarg is right, I designed the control panel as a state machine, and the sensors are interrupt driven. I know this was by far not the best way to implement such a system, but just wanted to share that as a beginner
Actually, there is nothing wrong with that, as stated. The only problem is that the states are not handled in a non-blocking manner. You can handle some asynchronous events using interrupts, but you can not tie them together into a main app that runs concurrent functions that way. That will prevent you from combining many common kinds of user input/output and hardware functions.
holmes4:
Some days (it some times seems) that every other post is asking how to get out of this [blocking] situation.
I've thought that lately too. That, and the notion of switches becoming pressed (as opposed to being pressed), and the idea of a flag to check if something has been done yet, seem to me to be the three main concepts required to code anything other than really trivial stuff.
Take the blink without delay example. Hive off the blink code in to a function and call it from loop.
Add this kind of blocking code to it.
Now how do you keep the LED blinking? Add calls to the blink function from here there and every where?.
Now take it a step further, try adding user (via a pot) input to control the rate of blinking - the program must of course respond, at once, how do you do that without checks on the pot all over the place?
holmes4:
Take the blink without delay example. Hive off the blink code in to a function and call it from loop.
Add this kind of blocking code to it.
Now how do you keep the LED blinking? Add calls to the blink function from here there and every where?.
Now take it a step further, try adding user (via a pot) input to control the rate of blinking - the program must of course respond, at once, how do you do that without checks on the pot all over the place?
Mark
I agree with you. This code is not to rival the benefits of a scheduler or OS, its for simple code functions. By this i mean navigating to a function that may set an output high/low, or printing the value received on the adc. I would not use this code for anything other than simple navigation to meet small project requirements. As stated before, this system work if u design a state machine.
I reiterate and agree with the community this is not best practice and cannot scale well to a bigger project.