//#include <SPI.h>
#include "Ucglib.h"
//Ucglib_ST7735_18x128x160_SWSPI ucg(/*SCK=*/ 52, /*SDA=*/ 51, /*A0=*/ 11, /*cs=*/ 10, /*reset=*/ 12); // Crea l'oggetto necessario per il display
Ucglib_ST7735_18x128x160_HWSPI ucg(/*cd=*/ 11, /*cs=*/ 10, /*reset=*/ 12);
// Definisco i pin per l'encoder e il pulsante
#define pulenc 14 // Pin 14 per pulsante encoder
#define Clk 15 // Pin 15 per Clk encoder
#define Dt 16 // Pin 16 per Dt encoder
int num_menu=1; // Indica in quale menù ci troviamo
int inc=0;
// Conserva stato ultima posizione encoder
int prevClk;
int prevDt;
int currClk;
int currDt;
bool tasto_premuto=0; // Variabile flag per il tasto premuto
bool tasto=1;
int ele=3;
// Definisco le variabili per il menù
int riga=0; // Indica la riga del display e la fase che si deve modificare// indice dell'elemento selezionato nel menù principale
const char* menu1[3] = {"Menu1_a", "Menu1_b", "Esci dal menu"}; // nomi degli elementi del menù principale
const char* menu2[5] = {"Menu2_a", "Menu2_b", "Menu2_c", "Menu2_d", "Esci dal menu"}; // nomi degli elementi sottomenù del Menua_1
const char* menu3[9] = {"Menu3_a", "Menu3_b", "Menu3_c", "Menu3_d","Menu3_e", "Menu3_f", "Menu3_g", "Menu3_h", "Esci dal menu"};
void setup() {
// Inizializzo il display con la rotazione e il colore di sfondo desiderati
delay(1000);
ucg.begin(UCG_FONT_MODE_SOLID); // stampa i caratteri con lo sfondo
ucg.setFont(ucg_font_ncenR10_hr);
ucg.clearScreen();
ucg.setColor(0,255, 255, 255); // Bianco
ucg.setColor(1,0, 0, 0); // sfondo nero
ucg.setPrintDir(1); //Direzione orizzontale
// Inizializzo il pulsante come input con la resistenza di pull-up interna
pinMode(pulenc, INPUT_PULLUP);
Serial.begin(9600); // Inizializza la seriale alla velocità di 9600
}
void loop(){
tasto = digitalRead(pulenc);
if ( tasto==0 ) menu_principale(); // Se viene premuto un tasto viene richiamata la routine menu_principale()
}
void menu_principale(){
riga=0;
num_menu=1;
draw_menu(menu1, 3);
delay(500);
while (num_menu!=0) {
controlla_encoder();
riga = constrain(riga, 0, ele-1); // riga può assumere un valore tra 0 e numero max degli elementi del menù
if (tasto_premuto==1){
if (riga==0 && num_menu==1) {num_menu=2; }
if (riga==1 && num_menu==1) {num_menu=3; }
if (riga==ele-1 && num_menu==1) num_menu=0; // Se si preme su esci si trona al menù precedente
if (riga==ele-1 && (num_menu==2 || num_menu==3)) num_menu=1;
riga=0;
ucg.clearScreen();
} // se viene premuto il tasto e si trova su exit, ritorna al loop principale
switch(num_menu) {
case 1:
draw_menu(menu1, 3);
break;
case 2:
draw_menu(menu2, 5);
break;
case 3:
draw_menu(menu3, 9);
break;
}
}
ucg.clearScreen();
}
void controlla_encoder() {
int esci=0;
tasto_premuto=0;
while (esci==0) {
tasto = digitalRead(pulenc);
if (tasto==0) { // Se si preme il tasto si esce dal controllo encoder
esci=1;
tasto_premuto=1;
}
int currClk = digitalRead(Clk);
int currDt = digitalRead(Dt);
// Questo IF controlla l'encoder
if (currClk != prevClk) {
if (0 == currClk) {
inc = 1 - ((currDt == currClk) << 1);
riga=riga+inc;
esci=1; // Se la rotella gira si esce dal controllo encoder
}
prevClk = currClk;
prevDt = currDt;
}
}
}
void draw_menu(const char* disegna_menu[], int num_ele) {
ele=num_ele;
if (riga<6) {
if (riga==5) ucg.clearScreen();
for (int i = 0; i < num_ele; i++) { // per ogni elemento del menù
if (i == riga) { // se è l'elemento selezionato
ucg.setColor(1,0, 0, 255); // sfondo blu
} else ucg.setColor(1,0, 0, 0); // sfondo nero
ucg.setPrintPos(115 -i*20, 10); // posiziono il cursore sul display
ucg.print(disegna_menu[i]); // stampo il nome dell'elemento
}
}
if (riga>5){
if (riga==6) ucg.clearScreen();
for (int i = 6; i < ele; i++) { // per ogni elemento del menù
if (ele-i == ele-riga) { // se è l'elemento selezionato
ucg.setColor(1,0, 0, 255); // sfondo blu
} else ucg.setColor(1,0, 0, 0); // sfondo nero
ucg.setPrintPos(115 -(i-6)*20, 10); // posiziono il cursore sul display
ucg.print(disegna_menu[i]); // stampo il nome dell'elemento
}
}
}
Fin'ora questo è il codice per il menu composto da un menu principale con 3 elementi (menu1), se clicco sul primo elemento si visualizza il menu2 formato da 5 elementi, se si clicca sul secondo elemento esce il menu3 formato da 9 elementi. L'ultimo elemento di ogni menu serve per uscire dal menu.
Ho difficoltà a gestire il menu3 quello da 9 elementi. Il display può visualizzare solo 6 righe, da 0 a 5, ho risolto come da codice ma non mi piace. Ho messo la cancellazione dello schermo quando la riga visualizzata è la 5 e la 6, la 5 quando dalla 6 torna indietro, la 6 quando dalla 5 va alla 6, in entrambi i casi vengono visualizzate le nuove pagine. Però se partendo dalla riga 0 scendo fino ad arrivare alla 5, lo schermo viene cancellato, invece dovrebbe essere cancellato solo se dalla 6 si passa alla 5. Lo stesso problema ce l'ho quando navigo nella seconda parte del menu. Come posso modificare il codice per evitare questo problema?
Ho anche un altro problema. Per scorrere di un posto i menu, a volte lo fa girando di uno scatto e a volte lo fa girando di due scatti l'encoder, non ho capito perchè.