Maker Pro
Maker Pro

Creating a user interface for arduino.

Hello friends,
I was working on my car when i came across a few YouTube videos of DIY fuel injector cleaning methods. Since i was looking for a new project to study i decided to build my own arduino based fuel injector cleaner. I know how to handle my analog/digital inputs/outputs to execute the cleaning cycles but what I do not know is how to create a user interface for it.
I am going to use 3 buttons to control the device. Up arrow button, down arrow button and enter button. The display will be a 20x4 liquid crystal LCD with i2c bus. Printing on the LCD is pretty easy so I should be ok with it.
I am thinking that the interface should look like this:
First it will display a greeting message then it will display two options: Automatic cleaning mode and manual cleaning mode. In auto mode things are simple; the device will execute the cleaning for a specific time period and display a message when finished. In manual mode the user will be asked to enter the amount of time he desires for the cleaning cycle to last.
That’s about it.
 

Harald Kapp

Moderator
Moderator
Check this, it may give you a good start.

Before you think about how to implement the user interface, think about what the user interface shall look like and what are the user interactions (input, output) you require. This is called the "use cases" of your software.
For example: you have only 3 buttons. It is comparatively easy to use these buttons for navigation through a menu where you only have to make a selection from e.g. a list of menu entries.
It is more of an effort if you need the user to enter numbers because you then have to select the numbers from a list of choices.
What you want to do pretty much defines how you can do it effectively.
 
Last edited:
Yes, i have already considered all these and i am actually pretty close to finish the code and run the first test :)
The LCD will look like this :
----------------------------------------------------------
PLEASE SELECT CLEANING METHOD
1.AUTOMATIC CLEANING <---
2.MANUAL CLEANING
----------------------------------------------------------
In the loop function i check for changes in the state of the buttons so if for example i detect the down arrow button changing state, i have a variable named (option = 1) that will become (option = 2) and the printing on the LCD will look like this :

----------------------------------------------------------
PLEASE SELECT CLEANING METHOD
1.AUTOMATIC CLEANING
2.MANUAL CLEANING <---
----------------------------------------------------------
Then if a press on the (enter) button is sensed, the code will read the value of (option) and will divert control to the corresponding function.
In Auto mode things are pretty straight forward, meaning pre defined times etc. While in Manual mode the user enters the ammount of time required (from 1 to 30 minutes) by incrementing a variable up to 30 each time up key is pressed or decrementing it down to 0 each time down key is pressed. The variable's value is printed on the LCD and when enter key is pressed the manual cleaning cycle begins.

Does it make sense to you ?
 
Last edited:

Harald Kapp

Moderator
Moderator
Looks good, Constantine.

An idea for manual mode: Worst case you have to press the up/down key 30 times. A common method to avoid this is to provide an auto increment/decrement mode. When you press the button for a certain timespan (e.g. longer than 3 sec) a counter will automatically increment or decrement the displayed number of remaining minutes while you press the button and stop when you release the button.
If you were to have more than 30 steps you can even advance this method by accelerating the counter if the button has been pressed for much longer. The problem here is often to release the button in time to avoid overshoot. Often you have to correct the final value with one or two presses of the button to achieve the desired final value.

Don't forget to debounce your keys :)
 
the code has this for example:

if (digitalRead (UpKey) == LOW) // I use the internal pullup resistors
{
Do things an in the end...
delay (50);
}
This is how i debounce the keys. Untested so far...
 

hevans1944

Hop - AC8NS
Explicit and immediate de-bouncing of a switch contact is sometimes unnecessary if all you are looking for is a change of state before initiating some further action. This often occurs while the program is in a "wait loop" that periodically examines a port bit for a change of state.

For example, a normally-open SPST switch with one terminal connected to a digital input with a pull-up resistor and the other terminal connected to ground will read as logic "1" until the switch is actuated. After the switch is actuated, the input will immediately change to logic "0" but may alternate between "0" and "1" as the switch contacts bounce, until finally settling down to logic "0" again. The input will remain at logic "0" until the switch is de-actuated. Any one of the logic "0" states will be detected by software that periodically examines the input port, or detected by means of a hardware interrupt if this capability is enabled, so the change of state that the software was "looking" for is reliably detected without de-bouncing the switch (yet) and the program can continue.

The problem with this approach is when the program must determine that the switch is subsequently de-actuated, creating a logic "1" on the input port, after some period of time following a switch actuation event. If this period of time is too short, the switch contacts may still be bouncing from the actuation event. This bouncing can cause a "false positive" that the switch is de-actuated when in fact it is still actuated. So, there has to be a de-bounce delay to ensure that the switch was actually de-actuated when the software is "looking" for a switch change of state from actuated to de-actuated.

If the programmer wants to include a de-bounce delay after every change of switch state, as described in the Arduino tutorial that @Harald Kapp linked to in post #6, that is the safest and most general approach. The additional few dozen milliseconds of delay it introduces into program execution time will not be noticed by human beings whose reaction time to switch events is measured in hundreds of milliseconds. OTOH, if the switch is controlling machinery, a fixed de-bounce delay may lead to unacceptable results. That, among other reasons, is why mechanical limit switches should always be of the "over-run" type that remain actuated (or de-actuated) after initiating a "stop motion" event.
 

Fish4Fun

So long, and Thanks for all the Fish!
@ HellasTechn ...

You should seriously consider incorporating some means of switch de-bouncing as suggested by Harold & Heavens ... Slowing micro-controller interfaces down to "realistic human speeds" is extremely important for reliable functionality. Watching a typical "tactile switch" output on a DSO can fundamentally change the way you think about "on/off switches", LoL. Using your main loop to "detect" a switch event is fine, but the handling routine should sample the switch state several times over a 1mS to 20ms period and abort if all readings are not the same ... even if the handling routine is called a half dozen times before it actually executes, worst case this implies a 120mS "delay" .... even the extreme case of 120mS is not noticeable in most circumstances.

Good Luck!

Fish
 
Thanks. For the time being i have put this project into the freezer. I will read carefully about debouncing and how to properly implement it after i get back to it :)
 

hevans1944

Hop - AC8NS
There is also the harware debounce.
Yeah, back in the day, I always used a hardware debounce circuit based on SPDT switch contacts, connected to cross-coupled inverters. Unfortunately, tactile switches are more common nowadays and these are mainly only available as SPST, although I suppose other arrangements are possible. Anyhoo, other generally more complicated circuits need to be used to debounce those puppies in hardware. Might as well do it in software then, IMHO.
 
Top