Scelta iniziale LCD 16x2 i2c

Ciao a tutti.
Mi presento: mi chiamo Leonardo ed ho 18 anni, utilizzo arduino a livello hobbystico da circa 1 anno e mezzo 2. Sto frequentando un Istituto Tecnico Industriale e sto preparando il progetto per la maturità. Vi spiego un po’ il tutto. Sto realizzando una serra automatizzata. Come sensori ho il DHT22(Temperatura e umidità), un sensore di umidità del terreno, un sensore TMP36 per la temperatura esterna e un sensore di luce(fotoresistenza). Con i sensori di temperatura/umidità aziono una ventolina ed un servo per aprire le finestre. Con il sensore di umidità del terreno aziono un led per simulare l’irrigazione. Ora arriva il problema. Con il sensore di luce devo creare un programma che implementa le ore mancanti di luce giornaliere. Esempio : x pianta ha bisogno di 10 ore di luce al giorno, ce ne sono state solo 8 quindi le restanti due ore vengono implementate da una lampada a U.V.(anche qui un led). Ho acquistato anche un modulo RTC basato su DS1307 ma non so comunque come andare avanti.
Secondo problema: ho un display, per la precisione questo Adafruit I2C Controlled + Keypad Shield Kit for 16x2 LCD : ID 715 : $14.95 : Adafruit Industries, Unique & fun DIY electronics and kits.
Visualizzo tutti i parametri della serra, ma all’avvio sul display dovrebbe esserci la possibilità di fare una scelta. Quest’ultima deve poi andare a cambiare le soglie di temperatura e umidità. Esempio: posso scegliere tra Lattuga, Pomodori e Melanzane. Ogni pianta ha delle diverse temperature di crescita. Se seleziono Lattuga si vanno a modificare i parametri con i quali aziono ventola/servo.
Spero di essermi spiegato.

Allego la parte di programma che sono riuscito a fare

dht22_lcd.ino (3.41 KB)

Ciao,
essendo il tuo primo post, ti chiederei cortesemente di presentarti QUI (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con attenzione il REGOLAMENTO ... Grazie.

Guglielmo

Lelo:
....
Visualizzo tutti i parametri della serra, ma all'avvio sul display dovrebbe esserci la possibilità di fare una scelta. Quest'ultima deve poi andare a cambiare le soglie di temperatura e umidità. Esempio: posso scegliere tra Lattuga, Pomodori e Melanzane. ....

Intanto ti rispondo a questo quesito ...
... se guardi in "Megatopic" c'è una bellissima libreria fatta apposta per gestire i "Menu" e "SottoMenu" su LCD. E' molto affidabile e ben manutenuta ... prova a guardarla.

Guglielmo

Ciao Gugliemo,
ho provveduto a presentarmi dove mi hai indicato.
Per quanto riguarda la libreria MENWIZ, l'avevo già adocchiata ma non trovo nessuna pagina in cui è spiegata.
Ora la provo.

Lelo:
Per quanto riguarda la libreria MENWIZ, l'avevo già adocchiata ma non trovo nessuna pagina in cui è spiegata.

Se hai dei dubbi, puoi chiedere nel thread indicato ...
... l'autore è un assiduo frequentatore del forum e ti risponde in tempi bervi :wink:

Guglielmo

Lelo:
l'avevo già adocchiata ma non trovo nessuna pagina in cui è spiegata.

Nel download è incluso un pdf che spiega come usarla.

Grazie mille.
Avete però idea di come risolvere il mio problema?
Cioè,appena accendi il displau ti chiede: "Che tipo di pianta vuoi piantare?"
E tu puoi scegliere fra 3 diverse opzioni: "Lattuga, pomodori o melanzane".
In base alla scelta che effettui vengono modificate le varie soglie.
Sono bloccatissimo, non so come andare avanti e mercoledi prossimo deve essere tutto finito.
Help me PLEASE

Fai questa parte nel setup() dopo aver inizializzato display e i vari pin.
Poni la domanda su display e attendi la risposta.
La risposta è il problema, attraverso cosa ? Il display è solo un mezzo per visualizzare quali scelte e quale stai per fare ma l'input o arriva da seriale (da pc) oppure da dei bottoni.
Per i bottoni, o 3 bottoni numerati (metodo più semplice) oppure 2 bottoni che ti permettono di fare la scelta e confermare.

Ciao nid,
Se guardi il link che ho postato all'inizio del display puoi vedere che è una shield che usa la comunicazione i2c e che sono presenti anche 6 pulsanti. Su, giù, destra, sinistra, seleziona e reset. In più il potenziometro per la retro. La scelta verrebbe effettuata da quei pulsanti. Ma non so comunque come farla. Potresti postarmi un esempio di programma?
Grazie

La libreria di supporto per quello shield la trovi qua: GitHub - adafruit/Adafruit-RGB-LCD-Shield-Library. Mostra anche come leggere i pulsanti.

Qua c'è un tutorial: Overview | RGB LCD Shield | Adafruit Learning System.

Tutto ciò però vale solo se hai esattamente quello shield di Adafruit. Ce ne sono in giro molti cinesi simili ma che non usano i2c. Su tali shield i pulsanti sono solitamente collegati tutti ad A0 tramite resistori, il che implica che la tecnica per leggerli cambia.

Ho esattamente quello e che comunica con i2c. Quei programmi li ho già provati, il display riesco a farlo funzionare bene, ma proprio non riesco a capire come effettuare una scelta dal display. Cioè quando premo seleziona, come fa Arduino a capire che deve andare a variare le soglie?
Sul fatto delle soglie mi hanno consigliato di usare gli array, in cui mi scrivo tutti i valori in delle stringhe e poi se li vanno a prender da lì. Ma non ho idea di come fare, le mie conoscenze di programmazione sono abbastanza scarse. Se qualcuno può farmi un esempio gli sarei grato.

Con dei semplici if e delle variabili globali che contengono la soglia.
Solo come esempio a macro-schema:

int soglia=0;      variabile globale, da usare nel programma in generale.
const int soglia1=10;
const int soglia2=20;
const int soglia3=30;
....
da button fanno scelta, esempio hai in   variabile scelta valore da 1 a 3:
if(scelta==1)
{ soglia=soglia1;
}else if(scelta==2)
{ soglia=soglia2;
}else if(scelta==3)
{ soglia=soglia3;
}
.... da qui soglia è quella "selezionata"

Non conosco la shield e quella lib. Devi vedere quando selezioni come la lib ti ritorna l'informazione.

La lettura dei pulsanti è banale:

  uint8_t buttons = lcd.readButtons();

  if (buttons) {
    if (buttons & BUTTON_UP) {
      lcd.print("UP ");
    }
    if (buttons & BUTTON_DOWN) {
      lcd.print("DOWN ");
    }
    if (buttons & BUTTON_LEFT) {
      lcd.print("LEFT ");
    }
    if (buttons & BUTTON_RIGHT) {
      lcd.print("RIGHT ");
    }
    if (buttons & BUTTON_SELECT) {
      lcd.print("SELECT ");
    }
  }

Ovviamente quello che vuoi fare alla pressione di ogni tasto devi deciderlo tu e scrivere il codice nella parte di relativa al tasto di interesse. Il codice che ti ha fornito nid sopra può fare al caso tuo, si tratta di unirlo a questo.

Beh, dipende COME vuoi selezionare. Se ti accontenti che 1 pulsante=1 soglia e quindi con 3 pulsanti hai fatto, è semplice.
Se invece con le frecce vuoi poter “selezionare” a display qualcosa quindi dare un feedback a display ogni volta che premi le frecce fino a quando non premi “seleziona” allora si complica un pò.
In questo ultimo caso poi NON è il valore dei button a darti la info di quale soglia hai scelto ma una tua variabile che può essere 1,2 o 3 e che tiene traccia di quale voce di menu hai selezionato.
In caso di selezione “carina”:
Di base puoi stampare su riga 0 “Scegliere soglia:”. Poi su riga 1 una frase tra “Lattuga”, “Pomodori” e “Melanzane”
Parti con “Lattuga” perchè la variabile scelta==1. Quando premi bottone avanti fai scelta++ e bottone indietro scelta-- Devi essere in un ciclo while continuo fino a quando il bottone premuto non è quello di selezione.
In questo while stampi su riga 1 la frase tra le tre a seconda del valore di scelta. Con 3 semplici if.
Devi controllare scelta non vada fuori range, ovvero scelta++ ma poi se scelta>3 allora scelta=0 e quando scelta-- controlli se scelta<1 allora scelta=3.
Poi, siccome la frase la stampi sempre in riga 1 colonna 0 e si sovrappongono, devi stampare sempre con spazi fino a coprire la frase più lunga, mi pare 9 caratteri
"Lattuga "
"Pomodori "
“Melanzane”
123456789

P.S. crea delle funzioni void che permettono di spezzare il programma.

  1. ad esempio questo lo stampi almeno 2 volte:
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("T.int: ");
    lcd.print(dht.readTemperature());
    lcd.write(4);
    lcd.print("C");
    lcd.setCursor(0,1);
    lcd.print("Umid: ");
    lcd.print(dht.readHumidity());
    lcd.print(" %");

Se tutto questo pezzo lo metti dentro a una funzione void, puoi averlo 1 sola volta e dove serve lo scrivi solo chiamando la funzione. Esempio:

void StampaTempInterna()
{ lcd.clear();
...
}
... nella loop
if (buttons & BUTTON_UP) {
  StampaTempInterna();   // molto più semplice da leggere
}

Anche nel setup() puoi chiamare la StampaTempInterna() e togliere il doppione del codice.

Usando le funzioni void il discorso della selezione, usa questo metodo.
nella tua setup() quindi richiamerai una funzione che chiamerai esempio SceltaSoglia();

void setup() 
{ pinMode(4, OUTPUT); //led irrigazione
  pinMode(7, OUTPUT); //led riscaldamento
  myservo.attach(11);  //servomtore
  ...
  SceltaSoglia();
  StampaTempInterna();
}
void SceltaSoglia()
{ uint8_t buttons=0;
  byte scelta=1;
  lcd.clear();
  lcd.setCursor(0,0); lcd.print("Scelta soglia:");
  while( ! buttons & BUTTON_SELECT)
  { lcd.setCursor(0,1); 
     // stampare la frase con 3 if in base a scelta
     buttons = lcd.readButtons();
     // analizzare quale pulsante premuto se up o down ++ o -- su scelta
    ...
  }
}

Grandissimi.
Credo di aver capito quasi tutto. Mi sfugge solo una cosa. Nell'esempio di Sukko, come faccio a far capire ad arduino quale scelta ho fatto dal display?

nid69ita:
Beh, dipende COME vuoi selezionare. Se ti accontenti che 1 pulsante=1 soglia e quindi con 3 pulsanti hai fatto, è semplice.
Se invece con le frecce vuoi poter “selezionare” a display qualcosa quindi dare un feedback a display ogni volta che premi le frecce fino a quando non premi “seleziona” allora si complica un pò.
In questo ultimo caso poi NON è il valore dei button a darti la info di quale soglia hai scelto ma una tua variabile che può essere 1,2 o 3 e che tiene traccia di quale voce di menu hai selezionato.
In caso di selezione “carina”:
Di base puoi stampare su riga 0 “Scegliere soglia:”. Poi su riga 1 una frase tra “Lattuga”, “Pomodori” e “Melanzane”
Parti con “Lattuga” perchè la variabile scelta==1. Quando premi bottone avanti fai scelta++ e bottone indietro scelta-- Devi essere in un ciclo while continuo fino a quando il bottone premuto non è quello di selezione.
In questo while stampi su riga 1 la frase tra le tre a seconda del valore di scelta. Con 3 semplici if.
Devi controllare scelta non vada fuori range, ovvero scelta++ ma poi se scelta>3 allora scelta=0 e quando scelta-- controlli se scelta<1 allora scelta=3.
Poi, siccome la frase la stampi sempre in riga 1 colonna 0 e si sovrappongono, devi stampare sempre con spazi fino a coprire la frase più lunga, mi pare 9 caratteri
"Lattuga "
"Pomodori "
“Melanzane”
123456789

mi quoto. rileggiti questo

Siete grandissimi. State riportando a galla il mio progetto.
Tempo di pranzare e provo il tutto. Sia che riesco sia che non, vi posto il programma così da potermi dare ulteriori consigli.
Gentilissimi, grazie mille.

nid69ita:
Usando le funzioni void il discorso della selezione, usa questo metodo.
nella tua setup() quindi richiamerai una funzione che chiamerai esempio SceltaSoglia();

void setup() 

{ pinMode(4, OUTPUT); //led irrigazione
  pinMode(7, OUTPUT); //led riscaldamento
  myservo.attach(11);  //servomtore
  ...
  SceltaSoglia();
  StampaTempInterna();
}
void SceltaSoglia()
{ uint8_t buttons=0;
  byte scelta=1;
  lcd.clear();
  lcd.setCursor(0,0); lcd.print("Scelta soglia:");
  while( ! buttons & BUTTON_SELECT)
  { lcd.setCursor(0,1);
    // stampare la frase con 3 if in base a scelta
    buttons = lcd.readButtons();
    // analizzare quale pulsante premuto se up o down ++ o -- su scelta
    ...
  }
}

Ora: Dal while si esce quando viene premuto il pulsante SELECT.
Quindi nel while dove hai scritto "//stampare la frase con 3 if in base a scelta" che devo scrivere?
e sotto come faccio ad analizzare quale pulsante è premuto?
Ho provato ma dal while esce con qualsiasi pulsante...
In più, io per cambiare tipo di pianta farei premere il pulsante DOWN 1 volta per passare da lattuga a pomodori e una seconda volta per passare da pomodori a melanzane. Però così passa diretto da lattuga a melanzane.
Se riesci fammi un esempio :smiley: