ST7920 Serial u8glib

Hai un display 128×64 con controller ST7920 Serial u8glib ?

ST7920 Serial u8glib

Ecco l’articolo che stavi aspettando … come controlalre un display basato sull’ST7920 attraveso un protocollo seriale e con la libreria u8glib.

Perché ST7920 Serial u8glib

Motivi per utilizzare questa combinazione potrei scriverne tanti e di certo altrettanti potresti aggiungerli tu, i principali sono:

  • i display grafici 128×64 con controller ST7920 sono molto diffusi;
  • il controllo seriale del ST7920 ti permette di controllare un display con soli 3 cavi + alimentazione;
  • la libreria u8glib è largamente usata per il controllo dei display grafici e molto completa
  • più di un anno fa avevo dedicato a questo tipo di display un articolo controllandolo con una altra libreria, dedicata, e mediante bus parallelo a 8bit: il panorama è cambiato da allora

Ho quindi ho deciso di riprendere il discorso per mostrarti come usare un display grafico con controller ST7920 Serial u8glib.

Collegamenti Serial u8glib

Nell’articolo dedicato al display grafico 128×64 avrai letto che tale display puoi utilizzarlo sia in modalità parallela, ossia con un collegamento a 8 bit e 11 pin + alimentazione + restroilluminazione, sia in modalità seriale con soli 3 collegamenti .. ecco come collegare il display:

ST7920 Serial u8glib schema

come vedi il pin PSB è quello che definisce la modalità di connessione del display: se connesso a +5v l’ST7920 lavora in parallelo, se connesso al Gnd l’ST7920 lavora in parallelo.

I 3 collegamenti verso arduino o genuino, nella modalità seriale sono:

ST7920 Serial u8glib connection arduino

che ho collegato ai pin analogici A2,A3 ed A4 perché usati già dalla libreria u8glib come vedrai in seguito.

Lato display i collegamenti sono verso i pin E, R/W ed RS

ST7920 Serial u8glib connection display

oltre, chiaramente, all’alimentazione +5v, il Gnd, la restoilluminazione e PSB connesso al Gnd.

Lo sketch

Lo sketch del progetto ST7920 Serial u8glib scrive i numeri “123” con il carattere massimo possibile sul display 49punti:

ST7920 Serial u8glib 123

puoi cambiare la grandezza del carattere ed il font per scrivere più informazioni sul display.

Ecco lo sketch che ho realizzato partendo dal classico “Hello World”:

#include "U8glib.h"

U8GLIB_ST7920_128X64_1X u8g(18, 16, 17); // SPI Com: en=18,rw=16,di=17

void draw(void) {
  u8g.setFont(u8g_font_fub49n);
  u8g.drawStr( 0, 56, "123");
}

void setup(void) {
  if ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
    u8g.setColorIndex(255);     // white
  }
  else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
    u8g.setColorIndex(3);         // max intensity
  }
  else if ( u8g.getMode() == U8G_MODE_BW ) {
    u8g.setColorIndex(1);         // pixel on
  }
  else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
    u8g.setHiColorByRGB(255,255,255);
  }
}

void loop(void) {
  u8g.firstPage();  
  do {
    draw();
  } while( u8g.nextPage() );
  
  delay(50);
}

procedendo linea per linea dalla linea 01: includi la libreria u8glib.h;

linea 03: definisci i collegamenti tra display e arduino / genuino;

linea 05: crea la funzione draw() il cui scopo è disegnare, nel nostro caso scrivere, sul display quando richiamata;

linea 06: imposta il font come fub49n, puoi utilizzare uno dei font disponibili nella font wiki della libreria u8glib, il font scelto da me è il Free Universal Bold da 49 punti;

linea 07: imposta la posizione del testo alla colonna 0 e riga 56, per centrarlo rispetto al display dalla formula: (64 – ((64-49)/2)) = 56,5 arrotondata per difetto;

linee 10-23: in funzione del valore restituito dalla funzione u8g.getMode() imposti il colore del testo, nel mio caso è unmonocromatico;

linea 26: all’interno della funzione loop() pulisci il display con il metodo u8g.firstPage();

linee 27-29: crei un ciclo do..while ossia un ciclo in cui prima esegui le istruzioni specificate all’interno delle parentesi graffe e solo successivamente controlli la validità della condizione nel while, che in questo caso è il risultato dell metodo: u8g.nextPage();

linea 31: attendi 50 millisecondi prima di eseguire nuovamente la funzione di loop()

Il risultato finale che otterrai è simile alla schermata seguente:

ST7920 Serial u8glib 123

  • Questo sito ed i suoi contenuti è fornito "così com'è" e Mauro Alfieri non rilascia alcuna dichiarazione o garanzia di alcun tipo, esplicita o implicita, riguardo alla completezza, accuratezza, affidabilità, idoneità o disponibilità del sito o delle informazioni, prodotti, servizi o grafiche correlate contenute sul sito per qualsiasi scopo.
  • Ti chiedo di leggere e rispettare il regolamento del sito prima di utilizzarlo
  • Ti chiedo di leggere i Termini e Condizioni d'uso del sito prima di utilizzarlo
  • In qualità di Affiliato Amazon io ricevo un guadagno dagli acquisti idonei qualora siano presenti link al suddetto sito.

Permalink link a questo articolo: https://www.mauroalfieri.it/elettronica/st7920-serial-u8glib.html

36 commenti

1 ping

Vai al modulo dei commenti

    • noro igor il 27 Aprile 2016 alle 15:15
    • Rispondi

    Salve,
    i pin indicati 18,16 e 17 sarebbero quindi A4,A2 e A3 rispettivamente ?
    Grazie e complimenti per i tutorial.

    1. Si Igor,
      i pin da A0 ad A5 corrispondo no anche ai numeri da 14 a 19 rispettivamente.

    • Bruno il 21 Novembre 2016 alle 00:30
    • Rispondi

    Con questa tipologia di display sono riuscito anche se alle prime armi a utilizzare un rtc ma non riesco a usare la ds18b20 che invece andava sul display precedente che era a 4 linee premetto che al posto del 18 ho collegato il 15 in arduino mi riuscirebbe ad aiutare
    Grazie

    1. Ciao Bruno,
      non ho capito il problema.
      Se la sonda la riesci a leggere non cambia nulla se hai un display a 4 linee o un display grafico.

    • Domenico il 4 Dicembre 2016 alle 19:11
    • Rispondi

    Salve, controllo uno stepper con Arduino Mega, keypad e display Nokia 5110. Quest’ultimo risulta troppo piccolo e volevo sostituirlo con questo dell’articolo. Volevo sapere se è possibile senza stravolgere lo sketck.

    1. Ciao Domenico,
      probabilmente dovrai sostituire la libreria in quanto non ricordo se la stessa libreria possa gestire entrambi i display.

    • Guido il 4 Dicembre 2016 alle 20:47
    • Rispondi

    Ciao, guardando il disegno ti chiedo se i pin 1, 6 e 20 del display grafico vanno collegati assieme al pin GND di Arduino, come i pin 2 e 19 del display grafico al pin 5V di Arduino?
    Per cortesia mi puoi anche dire se questo display va bene su Arduino per lavorare con il tuo codice?

    [[ link rimosso in automatico ]]

    Grzie Guido

    1. Ciao Guido,
      in primo luogo ti chiedo di evitare i link a siti generalisti, e-commerce e aste on-line nei commenti, come indicato nelle regole del blog.
      In merito al link, non sono in grado di valutare un prodotto senza la dovuta documentazione tecnica, e se posso permettermi un consiglio, io acquisto solo da rivenditori che rilasciano la documentazione del prodotto prima dell’acquisto per evitare di ritrovarmi con oggetti inusabili

        • Guido il 6 Dicembre 2016 alle 12:55
        • Rispondi

        Ti ringrazio della tua risposta, puo darmi per cortesia delle indicazioni sui pin che ti ho indicato?
        (Ciao, guardando il disegno ti chiedo se i pin 1, 6 e 20 del display grafico vanno collegati assieme al pin GND di Arduino, come i pin 2 e 19 del display grafico al pin 5V di Arduino?)
        Grazie Guido

        1. Ciao Guido,
          i collegamenti dei pin sono riportati anche nello schema che trovi nell’articolo.
          Da come li descrivi mi sembra siano corretti, fai attenzione che il pin 1 del tuo display sia effettivamente come in figura/schema

    • Antonio il 14 Dicembre 2016 alle 10:46
    • Rispondi

    Ciao Mauro,

    io non ho esattamente idea di come tu sia riuscito a fare funzionare il display con questi collegamenti, per almeno 2 fondamentali motivi:
    1. Nella prima immagine schematica dei collegamenti si vede come i pin vadano da sinistra a destra 1-20, mentre nella realtà è tutto il contrario, come si nota dalle imamgini reali.
    2. la libreria u8glib non usa assolutamente gli analogici come SPI, usa invece quelli di default, ovvero i pin digitali 10-11-12-13, atti proprio a quella funzione.
    L’unico modo in cui sono riuscito a farlo funzionare è quello da me descritto, e dubito che si possa fare altrimenti, probabilmente avevi un display diverso.
    Ciao e grazie.

    1. Ciao Antonio,
      comprendo la tua confusione in merito al punto 1 in effetti lo schema in fritzing ha una differente indicazione della numerazione dei pin, purtroppo non sempre riesco a trovare il componente identico nelle librerie del programma ed in questo caso, hai ragione, lo schema ha i numeri dei pin invertiti. Lo schema dei collegamenti è disegnato come vanno realmente eseguiti. (cercherò di correggere l’immagine per non creare dubbi ad altri ).
      In merito al punto 2 potresti avere ua libreria differente da quella che ho utilizzato io, la versione che ho descritto in questo articolo ti permette di definire i pin da utilizzare (vedi linea 03 )

      Grazie per la segnalazione

    • Giacomo Bruschi il 20 Gennaio 2017 alle 09:12
    • Rispondi

    Buon giorno complimenti per i tutorial sempre molto precisi e completi…ho un problema con il mio display 12864 ..ho seguito passo passo le sue istruzioni …inserendo anche un potenziometro 10k x gestire l’illuminazione però mi si accende diventando tutto blue ..ma non mi compaiono le scritte…se ha qualche suggerimento …la ringrazio

    1. Ciao Giacomo,
      il tuo display che controller/driver usa ? il display in questo l’ST7920 ?

    • Giacomo Bruschi il 20 Gennaio 2017 alle 10:27
    • Rispondi

    Sig.Mauro ho un display 12864B 2.0v della philMat

    1. Ciao Giacomo,
      così non mi dici nulla di utile.

    • Guido il 19 Febbraio 2017 alle 22:51
    • Rispondi

    Salve Mauro, come scheda uso Arduino Mega 2560 e per far funzionare il display GLCD ho dovuto impostare i pin in questo modo:

    GLCD Arduino Mega

    E 13
    RW 11
    RS 10

    Questo è il tipo di disply che uso con le impostazioni dei pin:
    [link rimosso in automatico]

    di conseguenza ho modificato lo sketch:

    U8GLIB_ST7920_128X64_1X u8g(13, 11, 10); // SPI Com: e=13,rw=11,rs=10 //pin su Arduino Mega per il mio dislay.

    Mi può per cortesia spiegare perche il display in modalità seriale funziona proprio con questi pin e non con A2, A3 e A4?
    Ho fatto diverse prove con altri pin ma sul display non compaiono scritte, rimane solo illuminato.
    Grazie Guido

    1. Ciao Guido,
      in primo luogo ti chiedo di leggere e rispettare le due semplici regole del blog, avrai letto che non è consentito inserire link esterni nei commenti.
      In merito alla tua richiesta, se ho compreso cosa intendi penso si sia trattato solo di un errore legato alla poca conoscenza della scheda che stai utilizzando in quanto A2,A3,A4 nell’Arduino Mega sono 56,57,58.
      Senza la variazione del numero di pin su cui indirizzare il segnale hai ottenuto di controllare dei pin a cui non era connesso nulla, almeno spero.

    • Guido il 20 Febbraio 2017 alle 23:55
    • Rispondi

    Salve, per fare in modo che le scritte scorrino, quali istruzioni devo mettere nel codice?
    Grazie Guido

    1. Ciao Guido,
      non ricordo se questa libreria gestisca già le scritte scorrevoli, puoi verificare sul sito dell’autore se esistono metodi per farlo.

    • Guido il 21 Febbraio 2017 alle 22:41
    • Rispondi

    Salve a tutti, chiedo se mi sapete indicare un programma dove disegno un immagine e poi la posso trasformare in codice binario da visualizzare sul display GLCD?

    const uint8_t rook_bitmap[] PROGMEM = {
    0x00, // 00000000
    0x55, // 01010101
    0x7f, // 01111111
    0x3e, // 00111110
    0x3e, // 00111110
    0x3e, // 00111110
    0x3e, // 00111110
    0x7f // 01111111
    };

    In questo caso visualizzo una torre.

    Grazie Guido

    1. Ciao Guido,
      a vedere ciò che hai postato potrebbe esserti sufficiente un foglio a quadretti, ho visto usare e provato io stesso questa tecnica molte volte:
      1. disegni un rettangolo, sul foglio a quadretti, di 8 x 8
      2. ci disegni dentro quello che desideri visualizzare
      3. colori i quadratini neri della figura
      4. i quadratini neri sono 1 e i bianchi 0

      hai ottenuto la matrice; usa la calcolatrice scientifica del computer per convertire il binario in hex.

    • Guido il 26 Febbraio 2017 alle 09:36
    • Rispondi

    Salve, con questo codice, vorrei poter visualizzare un messaggio ogni volta che premo il pulsante oltre all’ accensione del led.
    Adopero un pulsante ed ad ogni pressione accendo il led sucessivo.
    Al momento ottengo accensione e spegnimemto dei led quando premo il pulsante, ma non visualizzo la scritta sul display GLCD. Per cortesia mi dite dove sbaglio?
    per non pasticciare troppo il codice la parola lo inserita solo nel primo case.
    Grazie Guido.
    [[ codice rimosso in automatico ]]

    1. Ciao Guido,
      come sai è vietato incollare codice nei commenti, ti chiedo il rispetto delle regole sul blog, sono solo due.
      In merito al problema ipotizzo che il problema possa dipendere o dalla posizione errata di scrittura sul display rispetto all’accensione del led o da un tempo troppo breve perché il display riesca a visualizzarti un testo prima di cancellarlo a causa di clear o simile.

    • Guido il 26 Febbraio 2017 alle 12:24
    • Rispondi

    Non è molto chiaro il codice che ho postato prima.

    [[ codice rimosso in automatico ]]

    1. Ciao Guido,
      vedi commento precedente.

    • Crfel11 il 12 Aprile 2017 alle 18:18
    • Rispondi

    Salve, mi scuso per il codice ma è lo stesso di questa pagina con qualche modifica.
    Il codice funziona egregiamente, non capisco perchè, inserendo dei ritardi con dalay o millis(), non viene riconosciuta la pressione del tasto, non si accende il led , si comporta come se fosse in blocco .
    Non capisco dove sta l’errore .
    Complimenti e saluti
    Cirfel11

    [[ codice rimosso in automatico ]]

    1. Ciao Crfel11,
      spero tu abbia un nome diverso dal tuo Codice Fiscale.
      In merito al codice, esso viene rimosso in automatico per i motivi descritti nel blog.
      In merito al problema che descrivi io proverei a mettere dei Serial.print per capire dove di blocca e come mai non si comporta come atteso.

    • Domenico il 8 Maggio 2017 alle 12:14
    • Rispondi

    Salve Mauro complimenti per la guida, funziona a meraviglia.
    La mia domanda è:
    siccome vorrei adeguare un vecchio progetto fatto con un display 20×4, il cui sketch, come ben sai non ha bisogno di un “loop” per scrivere qualcosa su di esso… basta una semplice istruzione del tipo lcd.print ().
    come potrei sostituire questa istruzione con la libreria u8glib? devo per forse creare un loop ogni volta che devo scrivere qualcosa sul display grafico?
    Spero di essere stato chiaro. Grazie mille

    1. Ciao Domenico,
      il loop serve per la gestione delle pagine, dovrai mettercelo.
      La scrittura la esegue la funzione draw(), come hai letto nella descrizione, ed in particolare le line 6 e 7 dello script.

    • Andrea il 12 Ottobre 2017 alle 15:01
    • Rispondi

    Salve Mauro e complimenti per il blog! Sono da poco appassionato di Arduino ma già la seguo assiduamente! Non mi è chiaro il ciclo DO-WHILE all’interno del loop(). Mi sono documentato ed ho capito che il ciclo DO WHILE o meglio quello che è richiamato al suo interno permette il disegno della pagina in modo tale da non sovraccaricare troppo la RAM di Arduino mediante la gestione di una cache del display. Le spiego molto velocemente il mio progetto: un controllo di temperatura (DS18B20) e diversi menu di settings per le operazioni da svolgere…io pensavo di disegnare 4 videate diverse in funzione appunto del fatto che l’esecuzione sia in misurazione o impostazione di parametri. Lo scorrere delle pagine e dei vari settings sarà gestito da encoder rotativo gestito mediante interrupt (per cui il display avrà un collegamento diverso da quello da lei proposto). Il mio dubbio è se nella videata cambia solo la lettura della temperatura è comunque richiamare il ciclo DO-WHILE e ridisegnare comunque tutto? Quando poi sarò nelle pagine di menu io volevo evidenziare (non so ancora se si può) le varie icone/valori con un blink in reverse image, quindi ad ogni “click” dell’encoder devo ancora una volta ridisegnare tutta la pagina? Soprattutto in fase di visualizzazione delle misurazioni io volevo fare una pagina bella “cicciotta” con diversa grafica, non è che così “inginocchio” l’UNO R3?
    La ringrazio dell’eventuale risposta e le chiedo scusa della lungaggine
    Andrea

    1. Ciao Andrea,
      in merito al ridisegnare le pagine, devi farlo come previsto dalla libreria.
      Per risolvere il tuo dubbio sulla memoria ti consiglio di gestire al meglio le variabili che contengono le pagine riutilizzando il codice di creazione e ottimizzando le funzioni.

    • cosimo il 1 Gennaio 2019 alle 12:22
    • Rispondi

    ciao Mauro,auguri di buon anno.
    e la prima volta che scrivo,ho un problema con un tuo tutorial.
    ti spiego,nello sketch ho aggiunto due draw: di cui draw2 fa un logo di loading,il secondo la visualizzazione della temperatura.
    solo che vanno in sequenza, poi ricomincia con draw2 e poi draw1.
    un possibile tuo aiuto…

    distinti saluti

    [ sketch rimosso automaticamente come da regolamento ]

    1. Ciao Cosimo,
      gli sketch non si possono pubblicare, come hai certamente letto nel regolamento, e vengono cancellati dal sistema sopratutto se sono copie dei miei sketch.
      Se vuoi avere due fasi, la prima con il logo e la seconda con la temperatura, devi innanzitutto gestire tutto nella stessa draw, poi puoi definire una variabile booleana che setti a true di default e dopo la prima eseguzione del bloggo che visualizza il logo la metti a false, testando prima di tale blocco che la variabile sia true avrai che il logo resta attivo solo la prima volta.

      Se riesco pubblico un articolo in cui spiego il concetto con due led su un tutorial video .. spero di riuscire a realizzarlo presto.

    • Michele il 9 Marzo 2019 alle 18:29
    • Rispondi

    Ciao Mauro,
    inanzi tutto ti faccio i complimenti per i tuoi tutorial che mi hanno aiutato con altri progetti.
    Vorrei porti la seguente domanda, in che modo posso pilotare il display grafico se ho collegato ad esso un I2C Adapter per display 128×64? Avresti un codice da mostrarmi, in teoria devo includere la libreria Wire.h,
    ma poi come dovrei procedere? Il codice è lo stessosopra riportato?
    Grazie e ancora complimenti

    1. Ciao Michele,
      la configurazione con I2C dipende sia dal driver del display sia da quello montato sull’adapter, inoltre ti serve uno schea delle connessioni tra i due per comprendere come sono connessi tra loro.
      Raccolte queste informazioni puoi procedere a cercare delle librerie che possano consentirti di controllarlo.
      Solitamente la strada meno complessa è quella di chiedere al produttore o al rivenditore di procurarti le info e le librerie necessarie.

  1. […] la modalità di funzionamento del display è di tipo Seriale, già descritta in un mio precedente articolo, ed i pin interessati […]

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.