I saw a serious lack of info about state machines..
A state machine for those who don't know is like the buttons on your digital watch.. when you press them in certain combination, you can change time, date, run a stopwatch, etc..
Here, I offer some sample code I was writing that seems to work well for me.
It's beta but should give you something good to start from. Any ideas where it can be improved, I would greatly appreciate your input!
This code uses about 5k of code space but some of that is wasted with sample serial output to see changes made.
/* 4-button state machine
*
* This code is pre-set to allow sharing the button pins with a 4-byte LCD
* It has an example for how to modify different settings
* buttons are labeled as 'Main', 'Next', 'Prev', and 'Enter'
* Main toggles between different options
* Next and Prev increases or decreases the value of an option
* and Enter allows you to switch between different levels of that option
* IE minutes/hours or date/month/year
*/
int mainbutton = 4; // button connected to digital pin 4]
boolean mainbuttonstate = false;//Indicate whether button is just pressed or was already pressed
long mainbuttonMillis = 0; //last time button pressed
int mainstate=0;//indicate the current state in the main menu
int nextbutton=5;//button connected to digital pin 5
boolean nextbuttonstate=false;//incidate whether button is just pressed or was already pressed
long nextbuttonMillis=0;//last time button pressed
int prevbutton=6;//button connected to digital pin 6
boolean prevbuttonstate=false;//indicate whether button is just pressed or was already pressed
long prevbuttonMillis=0;
int entbutton = 7; // button connected to digital pin 2]
boolean entbuttonstate = false;//indicate whether button is just pressed or was already pressed
long entbuttonMillis = 0; //last time button pressed
int entstate=0;//state of particular option (Ie minutes or hours,etc..)
long restoreMillis=0;//last time any button pressed - used to return to a normal operation when no buttons pressed after 5 seconds
int ontemp=10;//store some values that we can change
int offtemp=7;
int hour=12;
int minutes=24;
int date=8;
int month=8;
int year=8;
int debounce =50;//how many ms to consider a button as 'pressed'
void setup()
{
pinMode(mainbutton,INPUT);//set our buttons as inputs
pinMode(nextbutton,INPUT);
pinMode(prevbutton,INPUT);
pinMode(entbutton,INPUT);
Serial.begin(9600);//open serial port to allow us to monitor changes
}
void loop()
{
// here is where you'd put code that needs to be running all the time.
if(digitalRead(mainbutton)==LOW)//check if main button is pressed
{
restoreMillis=millis();//set the restore counter
if (mainbuttonMillis==0 )//see if button was just pressed
{
mainbuttonMillis=millis();//if so, record the start of button press to measure debounce
}
else
{
if((mainbuttonMillis+debounce)>millis())//if button already pressed, check if debounce is good
{
if (mainbuttonstate==false)//if debounce is good..
{
mainbuttonstate=true;//set state to good
entstate=0;//reset the Enter button state, so you know what value you are editing
mainstate++;//increment the main menu
if(mainstate>5)//sets how many levels the main menu has
{
mainstate=0;//if max level exceeded, revert to main level
}
switch (mainstate)//do some action based on what state main level is.
{
case 0:
Serial.println("Main");
break;
case 1:
Serial.println("On Temp");
break;
case 2:
Serial.println("Off Temp");
break;
case 3:
Serial.println("Sensor Select");
break;
case 4:
Serial.println("Time Set");
break;
case 5:
Serial.println("Date Set");
break;
}
}
}
}
}
else
{
if(mainbuttonMillis!=0)//if button debounce occured and button is now released
{
mainbuttonMillis=0;//reset counter to wait for another button press
mainbuttonstate=false;//and set the button state to false
}
}
//*************************************************
if(digitalRead(nextbutton)==LOW)//see if next button is pressed
{
restoreMillis=millis();//set the restore counter
if (nextbuttonMillis==0 )//see if button was just pressed
{
nextbuttonMillis=millis();//if so, record the start of button press to measure debounce
}
else
{
if((nextbuttonMillis+debounce)>millis())
{
if (nextbuttonstate==false)
{
nextbuttonstate=true;
switch (mainstate)//do something based on which option we are editing
{
case 0:
Serial.println("Main");
break;
case 1:
ontemp++;
Serial.print("On Temp=");
Serial.println(ontemp);
break;
case 2:
offtemp++;
if (offtemp>=ontemp)
{
ontemp=offtemp+1;
}
Serial.print("Off Temp=");
Serial.println(offtemp);
break;
case 3:
Serial.println("Sensor Select");
break;
continued below.....