Helt klart så är det bästa att du börjar med att skriva ut statisk text på displayen.
Steg två är att börja läsa av knapparna kanske byta text när man trycker på en knapp.
Sedan läster du på om "statemachine"
Jag brukar lägga upp det så att jag har en variabel som innehåller aktuell position i menyträdet.
Pseudokod kan då se ut såhär:
Kod: Markera allt
while ...
if state=1 then skriv ut "Huvudmenyval 1"
if state=2 then skriv ut "Huvudmenyval 2"
if state=3 then skriv ut "Huvudmenyval 3"
if state=11 then skriv ut "Undermeny 1:1"
if state=12 then skriv ut "Undermeny 1:2"
if state=13 then skriv ut "Undermeny 1:3"
if state=21 then skriv ut "Undermeny 2:1"
if state=22 then skriv ut "Undermeny 2:2"
if state=31 then skriv ut "Undermeny 3:1"
om högerknapp then state = state + 1
om state = 4 then state = 3
om state = 14 then state = 13
om state = 23 then state = 22
om state = 32 then state = 31
om vänsterknapp then state = state - 1
om state = 0 then state = 1
om state = 10 then state = 11
om state = 20 then state = 21
om state = 30 then state = 31
om selectknapp and (state < 10) then state = state + 10
om selectknapp and (state > 10) then state = 1
.. repeat while
Sedan kan man snygga till det där genom att lagra texter, möjliga menyval, "ändlägen" m.m. i variabler...
Kanske inte alls så snyggt men hyfsat enkelt att jobba med och i min mening ganska flexibelt...
Här är ett exempel från ett av mina pågående projekt:
Kod: Markera allt
// Functions for Menu Handling
void getmenuitem(int _nr) {
byte _n;
switch ( _nr ) {
case 0: menu.txt = "<< TALLYRadio >>";
menu.u = 0;
menu.d = 1;
menu.l = -1;
menu.r = 10;
if (cfgmode) { menu.txt = "TALLYRadio CFG"; }
break;
case 1: menu.txt = "STATUS:";
menu.u = 0;
menu.d = 9;
menu.l = -1;
menu.r = 10;
break;
case 9: menu.txt = "RESET!";
menu.u = 1;
menu.d = 9;
menu.l = -1;
menu.r = -99;
if (menustate== 0) { menuedit[0]=0; menueditmin=0; menueditmax=1; menustatemax=1; }
break;
// SETTINGS
case 10: menu.txt = "IP-ADDRESS";
menu.u = 10;
menu.d = 11;
menu.l = -1;
menu.r = -2;
if (menustate==0) { menuedit[0]=ip[0]; menuedit[1]=ip[1]; menuedit[2]=ip[2]; menuedit[3]=ip[3]; menueditmin=0; menueditmax=255; menustatemax=4;}
break;
case 11: menu.txt = "SUBNET MASK";
menu.u = 10;
menu.d = 12;
menu.l = -1;
menu.r = -2;
if (menustate==0) { menuedit[0]=netmask[0]; menuedit[1]=netmask[1]; menuedit[2]=netmask[2]; menuedit[3]=netmask[3]; menueditmin=0; menueditmax=255; menustatemax=4; }
break;
case 12: menu.txt = "DEFAULT GATEWAY";
menu.u = 11;
menu.d = 13;
menu.l = -1;
menu.r = -2;
if (menustate==0) { menuedit[0]=gateway[0]; menuedit[1]=gateway[1]; menuedit[2]=gateway[2]; menuedit[3]=gateway[3]; menueditmin=0; menueditmax=255; menustatemax=4; }
break;
case 13: menu.txt = "ATEM IP";
menu.u = 12;
menu.d = 14;
menu.l = -1;
menu.r = -2;
if (menustate==0) { menuedit[0]=atem_ip[0]; menuedit[1]=atem_ip[1]; menuedit[2]=atem_ip[2]; menuedit[3]=atem_ip[3]; menueditmin=0; menueditmax=255; menustatemax=4; }
break;
case 14: menu.txt = "LCD BACKLIGHT";
menu.u = 13;
menu.d = 15;
menu.l = -1;
menu.r = -3;
if (menustate==0) { menuedit[0]=EEPROM.read(46); menueditmin=0; menueditmax=10; menustatemax=1; }
if (menustate==1) { lcd.setBacklight( map(menuedit[0], menueditmin, menueditmax, 0, 0xFF ), true); }
break;
case 15: menu.txt = "GPIO MAPPING";
menu.u = 14;
menu.d = 16;
menu.l = -1;
menu.r = -8;
if (menustate== 0) { menuedit[0]=1; menueditmin=1; menueditmax=16; menustatemax=2; menuedit[1]=GPIOmap[menuedit[0]]; }
if (menustate== 1) { menuedit[1]=GPIOmap[menuedit[0]]; }
if (menustate > 1) { menueditmin=0; if (menuedit[0]<=8) { menueditmax= 23; } else { menueditmax= 25; } }
break;
case 16: menu.txt = "<-- RETURN";
menu.u = 15;
menu.d = 16;
menu.l = 0;
menu.r = -1;
break;
} // switch case
} // getmenuitem
void handleMenu() {
int encValue = Encoder.encoder_state(1000);
if (encValue) {
if (encValue == 1) { ++encDelta; }
if (encValue == -1) { --encDelta; }
lcd.setCursor(0, 0);
getmenuitem(menupos);
if (encDelta >= 3) { // Vridning Medurs
encDelta = 0;
if (menustate==0) {
if (menu.d != -1) { menupos = menu.d; } // Navigera
} else {
if (menuedit[menustate-1]<menueditmax) { ++menuedit[menustate-1]; } // Editera
}
} else if (encDelta <= -3) { // Vridning Moturs
encDelta = 0;
if (menustate==0) {
if (menu.u != -1) { menupos = menu.u; } // Navigera
} else {
if (menuedit[menustate-1]>menueditmin) { --menuedit[menustate-1]; } // Editera
}
} else if (encValue == 2) { // Knapptryckning
if (menu.l >= 0) {
menupos = menu.l;
} else if (menu.r >= 0) {
menupos = menu.r;
} else if (menu.r <= -2) {
++menustate;
if (menustate > menustatemax) {
menustate = 0;
// Reset / Restart
if (menupos == 9) {
if (menuedit[0] == 1) {
Serial << F("Restarting....\n\n\n");
lcd.clear();
lcd << "RESTARTING...";
delay(1000);
resetFunc(); //call reset
}
}
// Save IP Adress
if (menupos == 10) {
EEPROM.write( 9, menuedit[0]); ip[0] = menuedit[0];
EEPROM.write(10, menuedit[1]); ip[1] = menuedit[1];
EEPROM.write(11, menuedit[2]); ip[2] = menuedit[2];
EEPROM.write(12, menuedit[3]); ip[3] = menuedit[3];
Serial << F("Save IP Adress to EEPROM\n");
}
// Save Netmask
if (menupos == 11) {
EEPROM.write(13, menuedit[0]); netmask[0] = menuedit[0];
EEPROM.write(14, menuedit[1]); netmask[1] = menuedit[1];
EEPROM.write(15, menuedit[2]); netmask[2] = menuedit[2];
EEPROM.write(16, menuedit[3]); netmask[3] = menuedit[3];
Serial << F("Save Netmask to EEPROM\n");
}
// Save Gateway
if (menupos == 12) {
EEPROM.write(17, menuedit[0]); gateway[0] = menuedit[0];
EEPROM.write(18, menuedit[1]); gateway[1] = menuedit[1];
EEPROM.write(19, menuedit[2]); gateway[2] = menuedit[2];
EEPROM.write(20, menuedit[3]); gateway[3] = menuedit[3];
Serial << F("Save Gateway to EEPROM\n");
}
// Save ATEM IP
if (menupos == 13) {
EEPROM.write(21, menuedit[0]); atem_ip[0] = menuedit[0];
EEPROM.write(22, menuedit[1]); atem_ip[1] = menuedit[1];
EEPROM.write(23, menuedit[2]); atem_ip[2] = menuedit[2];
EEPROM.write(24, menuedit[3]); atem_ip[3] = menuedit[3];
Serial << F("Save IP Adress to EEPROM\n");
}
// Save LCD Brigthness
if (menupos == 14) {
EEPROM.write(46, menuedit[0] );
delay(250);
Serial << F("Save LCD Brightness ") << String(menuedit[0],DEC) << F(" to EEPROM\n");
}
// Save GPIO MAP
if (menupos == 15) {
GPIOmap[menuedit[0]] = menuedit[1];
EEPROM.write(48-1+menuedit[0], menuedit[1] );
Serial << F("Save GPIO-MAP to EEPROM\n");
}
}
}
} else if (encValue > 999) {
menupos = 0;
menustate = 0;
}
getmenuitem(menupos);
lcd.clear();
lcd << menu.txt;
for (int n=0; n<(16-menu.txt.length()); ++n ) { lcd << F(" "); }
if (menu.r == -2) { // -2 = Edit IP
lcd.setCursor(0, 1);
lcd << F(" ");
if ( menuedit[0]<100 ) { lcd << " "; }
if ( menuedit[0]<10 ) { lcd << " "; }
lcd << String(menuedit[0]) << ".";
if ( menuedit[1]<100 ) { lcd << " "; }
if ( menuedit[1]<10 ) { lcd << " "; }
lcd << String(menuedit[1]) << ".";
if ( menuedit[2]<100 ) { lcd << " "; }
if ( menuedit[2]<10 ) { lcd << " "; }
lcd << String(menuedit[2]) << ".";
if ( menuedit[3]<100 ) { lcd << " "; }
if ( menuedit[3]<10 ) { lcd << " "; }
lcd << String(menuedit[3]);
if (menustate>0) { lcd.setCursor( 0, 1); lcd << F(">"); }
switch ( menustate ) {
case 1: lcd.setCursor( 3, 1); lcd.blink(); break;
case 2: lcd.setCursor( 7, 1); lcd.blink(); break;
case 3: lcd.setCursor(11, 1); lcd.blink(); break;
case 4: lcd.setCursor(15, 1); lcd.blink(); break;
default: lcd.noBlink(); break;
}
} else if (menu.r == -3) { // -3 = Edit % value in 10 steps
lcd.setCursor(0, 1);
lcd << F(" ");
if ( menuedit[0]<100 ) { lcd << " "; }
if ( menuedit[0]<10 ) { lcd << " "; }
lcd << String( map(menuedit[0], menueditmin, menueditmax, 0, 100 ) ) << F("% ");
if (menustate==1) { lcd.setCursor( 0, 1); lcd << F(">"); lcd.blink(); } else { lcd.noBlink(); }
} else if (menu.r == -8) { // -8 = GPIO mapping
lcd.setCursor(0, 1);
if (menustate>0) { lcd << F(">"); lcd.blink(); } else { lcd << F(" "); lcd.noBlink();}
// OUTPUTS
if ( (menuedit[0]>=1) && (menuedit[0]<= 8) ) {
lcd << F("GPO") << String(menuedit[0] ) << F("=");
if (menuedit[1]== 0) { lcd << F("OFF"); }
if ( (menuedit[1]>= 1) && (menuedit[1]<= 8) ) { lcd << F("TALLY ") << String(menuedit[1]); }
if ( (menuedit[1]>= 9) && (menuedit[1]<=16) ) { lcd << F("PREVIEW ") << String(menuedit[1]-8); }
if (menuedit[1]==17) { lcd << F("FTB ACTIVE"); }
if ( (menuedit[1]>=18) && (menuedit[1]<=21) ) { lcd << F("KEY ") << String(menuedit[1]-17); }
if ( (menuedit[1]>=22) && (menuedit[1]<=23) ) { lcd << F("DSK ") << String(menuedit[1]-21); }
}
// INPUTS
if ( (menuedit[0]>=9) && (menuedit[0]<=16) ) {
lcd << F("GPI") << String(menuedit[0]-8) << F("=");
if (menuedit[1]== 0) { lcd << F("OFF"); }
if ( (menuedit[1]>= 1) && (menuedit[1]<= 8) ) { lcd << F("SELECT ") << String(menuedit[1]); }
if ( (menuedit[1]>= 9) && (menuedit[1]<=16) ) { lcd << F("PREVIEW ") << String(menuedit[1]-8); }
if (menuedit[1]==17) { lcd << F("FTB"); }
if (menuedit[1]==18) { lcd << F("CUT"); }
if (menuedit[1]==19) { lcd << F("AUTO"); }
if ( (menuedit[1]>=20) && (menuedit[1]<=23) ) { lcd << F("KEY ") << String(menuedit[1]-19); }
if ( (menuedit[1]>=24) && (menuedit[1]<=25) ) { lcd << F("DSK ") << String(menuedit[1]-23); }
}
if (menustate==1) { lcd.setCursor(4, 1); }
if (menustate==2) { lcd.setCursor(6, 1); }
} else if (menu.r == -99) { // -99 = Soft Reset
lcd.setCursor(0, 1);
lcd << F(" ");
if ( menuedit[0]==0 ) { lcd << " NO"; }
if ( menuedit[0]>=1 ) { lcd << " YES!"; }
if (menustate==1) { lcd.setCursor( 0, 1); lcd << F(">"); lcd.blink(); } else { lcd.noBlink(); }
} else if ( (menu.r > -2) && (menu.r <= 0) ) { // -2 < menu.r <= 0 = Ingen edit = blanka ut nedre raden
lcd.setCursor(0, 1);
lcd << F(" ");
lcd.noBlink();
} else if ( (menupos >= 10) && (menu.r > 0) ) { // > 0 = Submenu available
lcd.setCursor(0, 1);
lcd << F(" --> SUBMENU ");
}
}
} // handleMenu
//B1N4RY