I'm working on a menu system for a project, and for some reason hitting the "back" button which causes a menu screen handler to return a reference to a parent menu causes the Arduino to jump back to the setup function. I'm not sure if it's doing a full reset because when I added an LED that's turned on right before the return statement, that LED stays on until I actually hit the reset button. I've pretty much ruled out a hardware issue with the button, so I must be missing something in software.
Any insight is appreciated.
The problem occurs at the indicated line at the end of DataScreen.maintain()
/*******************************************************************************************************
/ CLASS MenuItem
/ base class for all of the various menu screens so that the currentItem pointer may point to any
/ of the sketch's menus.
/
/******************************************************************************************************/
class MenuItem {
public:
char descript[16];
MenuItem* parent;
virtual void display(){};
virtual MenuItem* handleButton( int button ){};
virtual MenuItem* maintain(){}; //do any required maintenance, ie-poll sensors to update screen data
};
/*******************************************************************************************************
/ CLASS DataScreen
/ for displaying sensor data
/
/******************************************************************************************************/
class SensorScreen : public MenuItem {
protected:
unsigned int currentDatum; //current datum that should be displayed
unsigned long lastPoll; //time of last sensor data update
boolean refresh; // flag indicates if screen needs to be refreshed
public:
SensorScreen(char desc[], MenuItem *par ) {
parent = par;
strcpy(descript, desc);
currentDatum=0;
lastPoll=0;
refresh=true;
}
void display() {
Serial.println("display");
lcd.clear();
lcd.home();
lcd.print(valueNames[currentDatum]);
lcd.setCursor(0,1);
lcd.print(currentDatum);
lcd.print(":");
lcd.print(sensorData[currentDatum]);
}
MenuItem* maintain() {
//Serial.println("maintain");
if( millis() - lastPoll > pollInterval ) {
//poll sensors again;
}
if( up.changed && up.pressed ) {
currentDatum = ( currentDatum < 66 ? currentDatum + 1 : 0 );
refresh=true;
}
if( dn.changed && dn.pressed ) {
currentDatum = ( currentDatum > 0 ? currentDatum - 1 : 66 );
refresh=true;
}
if( back.changed && back.pressed ) {
digitalWrite(12, HIGH); //troubleshooting LED
return parent; //this is where things go bad
}
else {
if(refresh){
display();
refresh=false;
}
return this;
}
}
};
/*******************************************************************************************************
/ CLASS SelectScreen
/ base class for all of the various menu screens so that the currentItem pointer may point to any
/ of the sketch's menus.
/
/******************************************************************************************************/
class SelectScreen : public MenuItem {
protected:
int currentSelection;
boolean refresh;
public:
MenuItem *options[1];
SelectScreen( char desc[] ) {
strcpy(descript, desc);
currentSelection=0;
refresh=true;
parent = this;
}
void display() {
lcd.clear();
lcd.print(options[currentSelection]->descript);
}
MenuItem * maintain() {
if( enter.changed && enter.pressed ) {
return options[currentSelection];
}
else return this;
}
};
MenuItem *currentItem;
SelectScreen mainMenu("Main Menu");
SensorScreen sensorScreen("View sensor data", &mainMenu);
void setup() {
mainMenu.options[0] = &sensorScreen ;
Serial.begin(9600);
lcd.clear();
lcd.print("hello!");
currentItem = &mainMenu;
delay(1000);
currentItem->display();
pinMode(12, OUTPUT);
}
void loop(){
up.refresh();
dn.refresh();
back.refresh();
enter.refresh();
currentItem = currentItem->maintain();
}