LCD 16x2 Approccio

Salve
ho fatto pace con le librerie e per la prima volta ne ho installata una “#include <LiquidCrystal.h>” tanto per proseguire la mia comprensione degli Array.

Compresi,modificati e provati i vari esempi che ho trovato in giro ho provato ad allungare il passo e qui il fallimento totale.

Il mio obbiettivo è questo,vorrei fare 2 simboli speciali tipo PACMAN o SMILE, uno nella riga sopra che parte da 0 l’altro in quella sotto che parte da 16,che si dirigono verso il centro ed arrivati si scambiono di riga e proseguono ,per poi riapparire una volta usciti dal display.

Per i simboli inventati ho trovato alcuni esempi,ma non ho capito bene come funzionano.

byte smiley[8]={
                B00000,
                B10001,
                B00000,
                B00000,
                B10001,
                B01110,
                B00000,
               };

Per gli scorrimenti se utilizzo solo una riga riesco Ma non come vorrei.
Se provo ad utilizzarne 2 fa un gran casino.

Mi servirebbe il classico calcio nel sedere per provare a comprendere.

B sta per bit, hai in ogni riga 5 bit e quindi 5 pixel, Se 1=pixel acceso. 8 righe x 5 colonne
Fai una griglia di 5x8 e colora il quadrato dove hai 1, lasci vuoto se 0 e vedrai il disegno

https://www.arduino.cc/en/Reference/LiquidCrystalCreateChar

Puoi dichiarare al massimo 8 caratteri custom, devi passare l'array alla createChar, ogni array ad un numero tra 0-7
lcd.createChar(0, smiley);
lcd.write(byte(0));
lcd.createChar(1, altrocarattere);
lcd.write(byte(1));

Immaginavo qualkosa del genere.
Sù questo faccio un pò di prove poi faccio sapere.

Grazie per il momento

E per la questione auto scorrimenti indipendenti????

ciao Puso,

nel tuo LCD 16x2 hai due righe, numerate come 0 ed 1, ed ogni riga ha 16 caselle, numerate da 0 a 15.

ogni casella è formata da una griglia di puntini ...quindi ogni casella ha x righe ed y colonne....ogni uno di questi puntini può essere acceso o spento.
per semplificarti la vita, come ha detto nid69ita, gestisci la tua griglia come un array di byte dove ogni elemento è "descritto" sotto forma di BIT.
quel tuo:

byte smiley[8]={
                B00000,
                B10001,
                B00000,
                B00000,
                B10001,
                B01110,
                B00000,
               };

potrebbe essere scritto anche come:

byte smiley[8]={
                0,
                17,
                0,
                0,
                17,
                14,
                0,
               };

ma capisci che è più intuitivo il primo metodo che quasi ti mostra come verrà disegnato.

detto questo devi anche considerare che il tuo LCD tende a tenere in memoria, per ogni casella, il proprio stato fino a nuova scrittura...da qui ci sono diversi modi per fare quello che vuoi tu...prova e posta lo sketch

devo ancora fare le prime prove,ma non sarebbe più corretto scrivere

byte smile[][5]={
                   00000,
                   01110,
                   11011,
                   10001,
                   11011,
                   11111,
                   01110,
                   00000
                  };

???????

Puso:
devo ancora fare le prime prove,ma non sarebbe più corretto scrivere

ASSOLUTAMENTE NO !

Allora NON hai capito ... quello è un vettore di 8 elementi ed ogni elemento è un byte ...

Guglielmo

Ricordati che un byte può essere rappresentato in tante forme, ma sempre 8 bit, il cui valore decomale va da 0 a 255, sono.

B01110 significa solo rappresentare, in binario, il valore decimale 14 o, in esadecimale, il valore 0x0E ovvero: 00001110

dato che i bit più significativi sono a 0 ... puoi evitare di scriverli, ma, sarebbe stato la stessa cosa, scrivere appunto B00001110.

Dato che ogni carattere, sul LCD, è composto da 5 puntini luminosi in orizzontale che si ripetono per 8 file ... per indicare quale puntino luminoso di ogni singola fila e acceso e quale spento, bastano otto numeri che rappresentano i 5 puntini.

Guglielmo

Vediamo graficamente quanto detto ... prendi la lettera R ... è composta da 8 righe di 5 puntini luminosi:

R.jpg

Che corrispondono ai seguenti BYTES espressi in binario:

unit8_t letteraR[8] = {
B11110,
B10001,
B10001,
B11110,
B10100,
B10010,
B10001,
B00000
}

Guglielmo

P.S.: uint8_t è il modo più universale di identificare un "byte", come uint32_t è un "unsigned long" a 32 bit o un unit16_t e un "unsigned int" a 16 bit.

R.jpg

Magari lo studio del datasheet del più diffuso “controller” per LCD (… che poi è quello con cui il SW parla, mica vedi direttamente l’elettronica degli LCD) ti può essere utile … te lo allego :wink:

Guglielmo

HD44780.pdf (322 KB)

gpb01:
ASSOLUTAMENTE NO !
Allora NON hai capito ... quello è un vettore di 8 elementi ed ogni elemento è un byte ...
Guglielmo

Forse l'ho fuorviato il dicendogli di fare un disegno in tabella 5x8
8 righe = otto elementi vettore, 5 colonne ma in unico byte (ogni bit=colonna)

ok...primo tentativo fallito miseramente compila ma non funziona

byte smile[8]={
               B00000,
               B01110,
               B11011,
               B10001,
               B11011,
               B11111,
               B01110,
               B00000
              };

void setup() 
{  
  lcd.begin(16,2);  
  Serial.begin(9600);
}

void SMILE() 
{
lcd.setCursor(0,0);
lcd.createChar(0,smile);
lcd.write(byte(0));  
lcd.print(char(0));  
  
}
void loop()
{
 SMILE();
}

Guarda che hai l'esempio bello che fatto nel reference !

Guglielmo

ok grazie a tutti anche per il forviamento..ho guardato alcuni video ...è impressionante quello che si può fare con un semplice LCD( ed alcune cose credo mi abbia fatto bene impararle senza librerie)....mi piace ci studio sopra.

Nei prossimi giorni faccio altre prove e vi faccio sapere...e faccio arrabbiare Guglielmo.

OK
caoito come fare i simboli, ora l’idea e questa in Alto a SX appare la clessidra ed il tempo in secondi.

Dopo 2 secondi in Basso a SX appare la bottiglia ed a DX il bicchiere fin qui tutto ok.

Ora vorrei che bottiglia e bicchiere si avvicinassero al centro,poi la bottiglia sale in Alto si piega e versa il contenuto nel bicchiere,ma non riesco neppure a farli avvicinare al centro.

potrei usare i FOR ma vorrei evitarlo ho fatto alcune prove,compila ma non si muove nulla.

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

byte clessidra[8]={31,17,17,10,10,17,17,31};
byte bottiglia[8]={14,10,17,17,17,17,17,31};
byte bicchiere[8]={31,17,17,14,4,4,4,31};
byte culoBott[8]={0,0,15,8,8,8,15,0};
byte colloBott[8]={0,0,16,14,2,14,16,0};

unsigned long tempo=0;

void setup() 
{ 
 lcd.createChar(0,clessidra); 
 lcd.createChar(1,bottiglia);
 lcd.createChar(2,bicchiere); 
 lcd.createChar(3,culoBott); 
 lcd.createChar(4,colloBott);  
  
 lcd.begin(16,2);  
 Serial.begin(9600);
  
}

void CLESSIDRA() 
{
lcd.setCursor(0,0);
lcd.write(byte(0));
lcd.print(" ");
lcd.print(millis()/1000);  
}

void BICCHIERE() 
{
 lcd.setCursor(15,1);
 lcd.write(byte(2));
  
 byte(2)<<7;//COMPILA MA NON SI MUOVE
}
  
void BOTTIGLIA() 
{
 lcd.setCursor(0,1);
 lcd.write(byte(1));
  
 byte(2)<<6;//COMPILA MA NON SI MUOVE
}
void loop()
{
 tempo=millis()/1000; 
 CLESSIDRA();
 if(tempo>=2)
   {
    BICCHIERE();
    BOTTIGLIA();
   }
 
}

E cosa pretenderesti che facesse questa riga … :o :o :o

byte(2)<<7;//COMPILA MA NON SI MUOVE

… perché non ha molto senso … stai facendo un byte shift e, per di più, non assegni il valore a nulla!

Guglielmo

P.S.: T’ho già detto che DEVI prendere un buon libro di ‘C’ e STUDIARE … non andare a tentoni scrivendo cose come questa !!!

ciao...non si muove perchè nella varie funzioni hai impostati lcd.setCursor() con delle costanti numeriche tipo "0,0" o "15,1"...sempre li verranno disegnati i tuoi caratteri...devi utilizzare delle variabili per impostare la posizione...e queste variabili le devi gestire, incrementare, decrementare, verificare...per far fare all'LCD quello che vuoi.

EDIT:

P.S.: T'ho già detto che DEVI prendere un buon libro di 'C' e STUDIARE ... non andare a tentoni scrivendo cose come questa !!!

questo è il miglior consiglio...per tutto.

ok ok non sono un gran studente convenzionale
comunque mi sono appena ricordato che ho fatto funzionare un display 7 segmenti senza librerie.

e caschi il mondo riuscirò a versare li contenuto della bottiglia dentro il bicchiere.

:confused: :confused: :confused:

dunque avevo spostato il mio bicchiere ed ero tutto contento perchè faceva quello che volevo

void BICCHIERE() 
{
 if(spostaBicc==0)
   {
    c=15;
    lcd.write(byte(0));
    spostaBicc=1;
   }      
 if(spostaBicc==1)
   {
    lcd.write(byte(0));
    lcd.setCursor(c,1);
    lcd.write(byte(3));
    if(millis()-velBicc>=500)
      {
       lcd.write(byte(0));
       c--;
       lcd.setCursor(c,1); 
       lcd.write(byte(3));
       velBicc=millis();
      }
    if(c==9)
      {
       lcd.write(byte(0));
       spostaBicc=3;     
      }    
    }
}

Poi un bel copia incolla per la bottiglia con le modifiche di rito e qui il disastro :sob: :sob: :sob: :sob:

void BOTTIGLIA() 
{
 if(spostaBott==0)
   {
    c=0;
    lcd.write(byte(0));
    spostaBott=1;
   }      
 if(spostaBott==1)
   {
    lcd.write(byte(0));
    lcd.setCursor(c,1);
    lcd.write(byte(2));
    if(millis()-velBott>=500)
      {
       lcd.write(byte(0));
       c++;
       lcd.setCursor(c,1); 
       lcd.write(byte(2));
       velBott=millis();
      }
    if(c==7)
      {
       lcd.write(byte(0));
       spostaBott=3;     
      }    
    
   }
}

mi viene da pensare riguardando i vari consigli che sto sbagliando dove mettere il puntatore :drooling_face: :drooling_face: mi sto arenando.

ciao…non ho provato le due funzioni, che per me risultano un po’ contorte, però ti dico una cosa che vale come "discorso in generale e non solo per questo specifico caso; tu hai due “oggetti” che vuoi disegnare nel tuo LCD; questi due “oggetti” li gestisci individualmente con una funzione ciascuno; tra queste due funzioni non c’è alcuna possibilità di dialogo…cioè una non sa cosa sta facendo l’altra…o meglio…dove ha piazzato il proprio “oggetto”…e se ragioni individualmente, per singola funzione/oggetto, facile che se uno funziona (da solo) appena inserisci il secondo succeda il “disastro”.
Dovresti cercare di immaginare l’iterazione complessiva dei due “oggetti” e farli lavorare assieme…posso garantirti che quello che vuoi fare, bottiglia e bicchiere che si avvicinano e bottiglia che riempie il bicchiere, lo ottieni con un for() e un paio di if().

Grazie Orso per il consiglio

comunque sia il primo problema l'ho risolto,mi è bastato invertire il senso della scrittura "lcd.leftToRight();-lcd.rightToLeft();".

Per l'altro problema mi sembra di aver capito che di "lcd.setCursor()" ne ho solo 1 .......o posso avere più cursori indipendenti tra loro?????? :fearful: :fearful:

Comunque ipotizzando di averne solo 1, millis() non mi serve quindi uso il delay().