göra en meny med en lcd keypad shield och arduino?!?
göra en meny med en lcd keypad shield och arduino?!?
tjena!!
sitter och försöker att skapa en meny till den här http://www.hobbytronics.co.uk/arduino-lcd-keypad-shield
tanken är att det ska se ut något så här:
välkomstskärm
|
meny------meny-----meny----meny
| | | |
| | | |
subb meny subb meny subb meny subb meny
själva navigationen mellan menyerna kommer att göras med höger och vänster knapparn och för att ta sig till subb menyerna så trycker man på select.
hade tänkt att använda detta och testa på min pellets panna för att ha koll på förbruknig, temperaturer Etc.
är inte direkt någon hejare på att programmera arduino men har testat lite små grejer med blinkande ledar, motorer och dylikt så om det är någon som redan har en liknande kod eller lite tips på hur man enklast kodar en "meny" så är det bara att hojta till!!
trevlig fredag!!
sitter och försöker att skapa en meny till den här http://www.hobbytronics.co.uk/arduino-lcd-keypad-shield
tanken är att det ska se ut något så här:
välkomstskärm
|
meny------meny-----meny----meny
| | | |
| | | |
subb meny subb meny subb meny subb meny
själva navigationen mellan menyerna kommer att göras med höger och vänster knapparn och för att ta sig till subb menyerna så trycker man på select.
hade tänkt att använda detta och testa på min pellets panna för att ha koll på förbruknig, temperaturer Etc.
är inte direkt någon hejare på att programmera arduino men har testat lite små grejer med blinkande ledar, motorer och dylikt så om det är någon som redan har en liknande kod eller lite tips på hur man enklast kodar en "meny" så är det bara att hojta till!!
trevlig fredag!!
Re: göra en meny med en lcd keypad shield och arduino?!?
Hej.
Har själv ingen erfarenhet av arduino men gjort liknande till andra mikrokontrollers. Det jag gjort då är en enkel initialrutin för konfiguration av skärmens kontroller (HD4478-klon). Sedan skapat en drivrutin som känner igen tecken som exempel nyrad "/n" och annat som önskas. För Atmels ATmega har jag använt AVR-libc och konfigurerat enklare strömmar till drivrutinen. Därefter använt olika implementationer av printf och då fått något som påminner om Unixs/C:s standardströmmar
.
Har själv ingen erfarenhet av arduino men gjort liknande till andra mikrokontrollers. Det jag gjort då är en enkel initialrutin för konfiguration av skärmens kontroller (HD4478-klon). Sedan skapat en drivrutin som känner igen tecken som exempel nyrad "/n" och annat som önskas. För Atmels ATmega har jag använt AVR-libc och konfigurerat enklare strömmar till drivrutinen. Därefter använt olika implementationer av printf och då fått något som påminner om Unixs/C:s standardströmmar

Re: göra en meny med en lcd keypad shield och arduino?!?
Glömde att säga att flera är säkerligen rädda för printf som kan ta upp en massa programminne. Men idag finns tom 8-bitars AVR med en del kBytes så problemet går att köpa bort.
Re: göra en meny med en lcd keypad shield och arduino?!?
Har du försökt med google?
Den stora fördelen med att använda Arduino, är att nästan allt har någon annan redan gjort och lagt ut på nätet
Om du till exempel skulle googla "Arduino LCD Keypad Shield menu"
blir första träffen http://forum.arduino.cc/index.php/topic,44144.0.html
som behandlar:
Lycka till

Den stora fördelen med att använda Arduino, är att nästan allt har någon annan redan gjort och lagt ut på nätet

Om du till exempel skulle googla "Arduino LCD Keypad Shield menu"
blir första träffen http://forum.arduino.cc/index.php/topic,44144.0.html
som behandlar:
Kod: Markera allt
I am looking to make my menu like so:
Option1 ---> Option2 ---> Option3 ---> Option4
| |
Sub1 Sub1
| |
Sub2 Sub2
|
Sub3
|
Sub4
Lycka till
Re: göra en meny med en lcd keypad shield och arduino?!?
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:
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:
//B1N4RY
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
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
-
- Inlägg: 2436
- Blev medlem: 28 januari 2007, 18:45:40
- Ort: Kungsbacka
Re: göra en meny med en lcd keypad shield och arduino?!?
Ska man göra meny system på ett enkelt och automatiserat vis så får jag föreslå X makron om man skriver i C, du kan du nå dina parameter namn på enkla vis och parameter värden utan att behöva definiera namnen på flera ställen. Givet att du vill ha samma namn i koden som på menyn såklart.
Det går till typ såhär:
Kan nog finnas något fel i koden, blir lätt fel. Men så är metoden iaf.
Då kan man nå:
parameters.timme, parameters.minut och parameters.sekund i sin kod där man använder parametrar/inställningar.
Och när man renderar meny kan man nå:
namnen ("timme", "minut", "sekund") via PARAMETERS_NAMES där 0<=i<=2
datan i structen via *PARAMETERS_PTR där 0<=i<=2
och man och min via
PARAMETERS_MAX där 0<=i<=2
PARAMETERS_MIN där 0<=i<=2
Fördelen är att man bara behöver skriva namnen på ett ställe men ändå kan nå allt både via struct vilket är bra när man kodar för man får auto komplimentering(givet vettigt ide) och man kan nå allt via vektorer vilket är bra för att skriva menyer som inte är hårdkodade.
Alla glada förutom han som ska läsa koden nästa gång.
Det går till typ såhär:
Kod: Markera allt
//Parameter namn, min värde och max värde
#define params \
X(timme,0,24)\
X(minut,0,60)\
X(sekund,0,60)
//Skapa struct med parametrar
struct PARAMETERS_STRUCT{
#define X(name,x,y) unsigned char name;
params
#undef X
}parameters;
//Skapa vektor med pekare till structen
#define X(name,x,y) ¶meters.name,
unsigned char* PARAMETERS_PTR[]={params};
#undef X
//Skapa vektor med max
#define X(name,max,min) max,
unsigned char PARAMETERS_MAX[]={params};
#undef X
//Skapa vektor med min
#define X(name,max,min) min,
unsigned char PARAMETERS_MIN[]={params};
#undef X
//Skapa vektor med namn
#define X(name,x,y) #name,
char PARAMETERS_NAMES[][32]={params};
#undef X
Då kan man nå:
parameters.timme, parameters.minut och parameters.sekund i sin kod där man använder parametrar/inställningar.
Och när man renderar meny kan man nå:
namnen ("timme", "minut", "sekund") via PARAMETERS_NAMES där 0<=i<=2
datan i structen via *PARAMETERS_PTR där 0<=i<=2
och man och min via
PARAMETERS_MAX där 0<=i<=2
PARAMETERS_MIN där 0<=i<=2
Fördelen är att man bara behöver skriva namnen på ett ställe men ändå kan nå allt både via struct vilket är bra när man kodar för man får auto komplimentering(givet vettigt ide) och man kan nå allt via vektorer vilket är bra för att skriva menyer som inte är hårdkodade.
Alla glada förutom han som ska läsa koden nästa gång.
Re: göra en meny med en lcd keypad shield och arduino?!?
Någon har knappat lite i Borland....
http://elektronikforumet.com/forum/view ... 19&t=51494
http://elektronikforumet.com/forum/view ... 19&t=51494
Re: göra en meny med en lcd keypad shield och arduino?!?
tackar för alla svaren!! ska försöka gå igenom alla tips å länkar så snart som möjligt så får vi se om de dyker upp nån tråd senare i projekt tråden! 
