göra en meny med en lcd keypad shield och arduino?!?

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
kallman
Inlägg: 47
Blev medlem: 10 november 2010, 17:57:08

göra en meny med en lcd keypad shield och arduino?!?

Inlägg av kallman »

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!!
Användarvisningsbild
psynoise
EF Sponsor
Inlägg: 7226
Blev medlem: 26 juni 2003, 19:23:36
Ort: Landvetter

Re: göra en meny med en lcd keypad shield och arduino?!?

Inlägg av psynoise »

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 :).
Användarvisningsbild
psynoise
EF Sponsor
Inlägg: 7226
Blev medlem: 26 juni 2003, 19:23:36
Ort: Landvetter

Re: göra en meny med en lcd keypad shield och arduino?!?

Inlägg av psynoise »

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.
nifelheim
Den första
Inlägg: 2489
Blev medlem: 27 mars 2008, 22:31:16
Ort: stockholm

Re: göra en meny med en lcd keypad shield och arduino?!?

Inlägg av nifelheim »

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:

Kod: Markera allt

I am looking to make my menu like so:

Option1 --->  Option2 ---> Option3 ---> Option4    
  |                    |
Sub1              Sub1
  |                    |
Sub2              Sub2                 
  |
Sub3
  |
Sub4

Lycka till
B1n4ry
EF Sponsor
Inlägg: 1327
Blev medlem: 30 november 2005, 20:02:50
Ort: Borås
Kontakt:

Re: göra en meny med en lcd keypad shield och arduino?!?

Inlägg av B1n4ry »

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
victor_passe
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?!?

Inlägg av victor_passe »

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:

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) &parameters.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 

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.
Användarvisningsbild
baron3d
EF Sponsor
Inlägg: 1353
Blev medlem: 1 oktober 2005, 23:58:43
Ort: Torestorp

Re: göra en meny med en lcd keypad shield och arduino?!?

Inlägg av baron3d »

Någon har knappat lite i Borland....
http://elektronikforumet.com/forum/view ... 19&t=51494
kallman
Inlägg: 47
Blev medlem: 10 november 2010, 17:57:08

Re: göra en meny med en lcd keypad shield och arduino?!?

Inlägg av kallman »

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! :)
Skriv svar