Go Down

Topic: Richiesta chiarimenti sulla logica di un programma menù (Read 700 times) previous topic - next topic

Bertallo

Aug 08, 2013, 11:11 pm Last Edit: Aug 09, 2013, 09:48 am by Bertallo Reason: 1
Buonasera a tutti, sto cercando di creare un menù su un display 128 x 64 utilizzando la libreria u8glib, premetto che son partito dall'esempio che è incluso con la libreria e l'ho modificato secondo le mie esigenze, l'obiettivo è riuscire ad entrare da una voce menù in un altro sotto menù ma non so se sto procedendo nel migliore dei modi, per non dover riscrivere infinite volte il menù in ogni schermata che creo, volevo modificare colamente alcuni parametri e stampare sempre il solito menù (drawMenu) vi allego il codice che ho scritto:

Code: [Select]
#include <U8glib.h>
#include <Keypad.h>

U8GLIB_ST7920_128X64_4X u8g(2, 4, 3);

const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS]={
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

byte rowPins[ROWS]={12, 11, 10, 9};
byte colPins[COLS]={8, 7, 6, 5};

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

int MENU_ITEMS;
char menu_strings;
byte menu_redraw_required = 0;

void utility(void) {
 u8g.drawStr(17, 2, "GIO 8 AGO 2013");
 u8g.drawLine(0, 32, 128, 32);
}

void drawMenu(void) {
  byte i, h;
  byte w, d;

 
  u8g.setFontPosTop();
 h = u8g.getFontAscent()-u8g.getFontDescent();
 w = u8g.getWidth();
 for( i = 4; i<=MENU_ITEMS; i++ ) {
   d = (w-u8g.getStrWidth(menu_strings[i]))/2;    //<-----Qui mi segnala "Invalid types 'char[byte]' for array subscript"
   u8g.setDefaultForegroundColor();
   if ( i == menu_current ) {
     u8g.drawBox(20, i*h-1, w-41, h);
     u8g.setDefaultBackgroundColor();
   }
   u8g.drawStr(d, i*h-1, menu_strings[i]);
  }
}

char key;
void selection(void)
{
  if(key)
  {
     if(key=='A')
     {
           if(menu_current == 4)
       menu_current=MENU_ITEMS;
       menu_current--;
     }
     else if (key=='B')
     {
       menu_current++;
        if(menu_current >=MENU_ITEMS)
          {
            menu_current =4;
          }
     }
     else if(key=='#')
       {
        if(menu_current==4)
          {
             MENU_ITEMS=2
             char *menu_strings[MENU_ITEMS] = {"Zona 1", "Zona 2" };
             byte menu_current = 0;  
            do
            {
               do
               {
                   drawSecond();
               }   while(u8g.nextPage());
           
              key=keypad.getKey();  
            }while(key!='*');
        }
     }
    }
  }  


void setup(void){
  Serial.begin(9600);
  u8g.setFont(u8g_font_6x10);
  u8g.setFontRefHeightText();
}

void loop(void){

  u8g.firstPage();
  key=keypad.getKey();
 
  do{
      MENU_ITEMS =  7;
      menu_strings = new menu_strings[MENU_ITEMS] = {" ", " ", " ", " ", "MANUALE", "AUTOMATICO", "IMPOSTAZIONI" };
      byte menu_current = 4;  
      drawMenu();
      utility();
  } while( u8g.nextPage() );
 selection();

 
}

uwefed

Allora dacci la fonte delle 2 librerie, quale Arduino usi, quale versione IDE, e dacci i messaggi di errore copia e incolla.
Ciao Uwe

leo72

Hai intitolato il thread "errore compilazione", ma da come descrivi la cosa pare più un problema di logica del programma.

Bertallo

Utilizzo Arduino UNO, con il software aggiornato all'IDE 1.0.5, le librerie sono:
-u8glib per il display :
http://code.google.com/p/u8glib/
http://code.google.com/p/u8glib/wiki/userreference
http://code.google.com/p/u8glib/wiki/tmenu

-Keypad.h per gestire la tastiera:
http://playground.arduino.cc/code/Keypad

Messaggi di errore:
Non essendo nemmeno sicuro di star procedendo nel modo corretto non li ho guardati più di tanto, volevo sapere se la mia idea di mantenere un unico "metodo" (drawMenu) andando a modificare il valore delle sue variabili (MENU_ITEMS, menu_current, menu_strings) e far la stessa cosa cosa per quanto riguarda quello che ho chiamato "selection", che legge i tasti premuti dalla tastiera ed esegue le istruzioni in base al tasto premuto, ovvero cambiare solo il valore delle variabili (o aggiungerne se necessario) ma non farne uno per ogni menù diverso che creo..  vi allego comunque gli errori che mi da fino a qui.. probabilmente poi ce ne saranno altri perchè per esempio all'interno di selection alla riga "if(menu_current == 4)" quel 4 si riferisce alla 4a voce del primo menù che per me è la prima, ma in un secondo menù quel 4 dovrà diventare 0, per cui anche qui volevo introdurre una variabile..

prova.ino: In function 'void drawMenu()':
prova:38: error: invalid types 'char[byte]' for array subscript
prova:40: error: 'menu_current' was not declared in this scope
prova:44: error: invalid types 'char[byte]' for array subscript
prova.ino: In function 'void selection()':
prova:74: error: 'menu_current' was not declared in this scope
prova:76: error: 'menu_current' was not declared in this scope
prova:81: error: 'menu_current' was not declared in this scope
prova:90: error: 'menu_current' was not declared in this scope
prova:93: error: expected `;' before 'char'
prova:99: error: 'drawSecond' was not declared in this scope
prova.ino: In function 'void loop()':
prova:125: error: expected type-specifier before 'menu_strings'
prova:125: error: invalid conversion from 'int*' to 'char'
prova:125: error: expected `;' before 'menu_strings'



PaoloP

#4
Aug 09, 2013, 10:14 am Last Edit: Aug 09, 2013, 10:18 am by PaoloP Reason: 1
Tu dichiari
Code: [Select]
char menu_strings;
come variabile e poi lo usi come vettore
Code: [Select]
menu_strings[i]

Lo devi dichiarare
Code: [Select]
char menu_strings[MENU_ITEMS];
ma MENU_ITEMS deve essere definito
Code: [Select]
int MENU_ITEMS = xxx;
dove xxx è il numero di oggetti del menu.

menu_current è dichiarata locale dentro il do while
Code: [Select]
byte menu_current = 4;  
non la puoi usare fuori.  

Quando usi new devi usare anche free altrimenti crei spazzatura (garbage) e dopo un po' ti si inchioda il micro.

Bertallo

Si avevo intuito che il problema stava proprio sull'attribuzione di valori a variabili locali, il fatto è che non mi viene in mente altro modo per modificarle quando cambio menù senza dover riscrivere tutto..

ho provato a modificare:
int MENU_ITEMS=10;
char menu_strings[MENU_ITEMS];

ma mi restituisce questo errore

21: error: array bound is not an integer constant

PaoloP

Non puoi dichiarare una array dinamico senza utilizzare new. (anche con valore assegnato MENU_ITEMS è una variabile)
Oppure metti
Code: [Select]
const int MENU_ITEMS=10;
ma non puoi più modificarne la dimensione.

Go Up