Basic system navigation of functions on arduino

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.

Example hierarchy:

[Monitor]
[x values]
[y values]
[Settings]
[Timing]
[Fast]
[Slow]
[Speaker]
[On]
[Off]

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

	}


}

navigation.c (1.82 KB)

And your point is ?

ieee488:
And your point is ?

Don't use meaningless variable names?

Use this code responsibly, since it may contain errors.

Will do!

used "A", "B" and "C" since it corresponds to A, B, C in some keyboards. can be changed to
"keyboard_A_clicked"

NEVER NEVER use this code it is blocking! You can't do anything else while waiting for user input.

Some days (it some times seems) that every other post is asking how to get out of this situation.

It's however a very good example of what not to do, from some one who does not know what he is doing.

Mark

If you read my post, you may note that I state that this system would only work with interrupts

I state that this system would only work with interrupts

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.

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! :slight_smile:

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! :slight_smile:

Learning best practices will take you further.

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?

Mark

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.