Skip to Content

Come controllare un display LCD I2C a caratteri con Arduino

Come controllare un display LCD I2C a caratteri con Arduino

Questo articolo include tutto ciò che devi sapere sull’uso di un display a caratteri I2C LCD con Arduino. Ho incluso uno schema di collegamento e molti esempi di codice per aiutarti a iniziare.

La prima parte di questo articolo copre le basi per visualizzare testo e numeri. Nella seconda parte, entrerò più nel dettaglio su come mostrare caratteri personalizzati e come utilizzare le altre funzioni della libreria LiquidCrystal_I2C.

Una volta che sai come visualizzare testo e numeri sul LCD, ti consiglio di dare un’occhiata agli articoli qui sotto. In questi tutorial imparerai come misurare e visualizzare i dati dei sensori sul LCD.

Materiali

Componenti hardware

lcd16×2 character I2C LCD× 1Amazon
lcd20×4 character I2C LCD (alternativa)× 1Amazon
Arduino Uno Rev 3Arduino Uno Rev3× 1Amazon
Jumper wires (maschio a femmina)× 4Amazon
USB cable type A/B× 1Amazon

Strumenti

Small screwdriverAmazon

Software

Arduino IDEArduino IDE

Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.

Nozioni di base sull’I2C LCD

Questa guida fa parte del nostro hub di articoli su Displays. Questo tipo di LCD è ideale per visualizzare testo e numeri, da qui il nome ‘character LCD’.

L’I2C LCD che usiamo in questo tutorial ha un piccolo circuito aggiuntivo montato sul retro del modulo. Questo modulo include un chip PCF8574 (per la comunicazione I2C) e un potenziometro per regolare la retroilluminazione a LED.

Il vantaggio di un LCD I2C è che il cablaggio è molto semplice. Ti servono solo due pin dati per controllare l’LCD. Gli LCD standard richiedono tipicamente circa 12 connessioni, il che può essere un problema se non hai molti pin GPIO disponibili.

Fortunatamente, puoi anche acquistare il circuito aggiuntivo I2C separatamente su Amazon, così puoi facilmente aggiornare anche un LCD standard.

Per un tutorial e uno schema di collegamento per LCD a caratteri standard, consulta il seguente articolo:

Se guardi attentamente l’LCD, puoi vedere i piccoli rettangoli che formano i singoli caratteri. Ogni rettangolo è composto da una griglia di 5×8 pixel. Più avanti in questo tutorial ti mostrerò come controllare i singoli pixel per visualizzare caratteri personalizzati sull’LCD.

LCD Pixels
Pixel LCD

Specifiche

Le specifiche degli LCD 16×2, 20×4 e di altre dimensioni sono per lo più le stesse. Usano tutti lo stesso HD44780 Hitachi LCD controller, quindi puoi facilmente sostituirli. Ti basterà cambiare le specifiche di dimensione nel codice Arduino.

Le specifiche di un tipico display I2C 16×2 sono riportate nella tabella qui sotto.

Specifiche LCD I2C 16×2

Tensione di funzionamento5 V
ControllerController LCD Hitachi HD44780
Indirizzo predefinito0x27
Risoluzione dello schermo2 righe × 16 caratteri
Risoluzione del carattere5 × 8 pixel
Dimensioni del modulo80 × 36 × 12 mm
Dimensioni dell’area visibile64.5 × 16.4 mm
CostoCheck price

Per maggiori informazioni, puoi consultare i datasheet qui sotto.

I datasheet dei modelli 16×2 e 20×4 includono le dimensioni dell’LCD e puoi trovare ulteriori informazioni sul driver LCD Hitachi nel datasheet HD44780.

Il chip PCF8574 è usato nel modulo I2C sul retro dell’LCD.

Come collegare l’I2C LCD ad Arduino UNO

Lo schema di collegamento qui sotto mostra come collegare l’I2C LCD ad Arduino. Collegare un LCD I2C è molto più semplice che collegare un LCD standard. Ti servono solo 4 pin invece di 12.

I2C-LCD-with-Arduino-Wiring-Diagram-Schematic-Pinout
Schema di collegamento I2C LCD con Arduino

Le connessioni sono anche riportate nella tabella qui sotto.

Connessioni I2C LCD

LCD a caratteri I2CArduino
GNDGND
VCC5 V
SDAA4
SCLA5

Se non usi un Arduino Uno, i pin SDA e SCL possono trovarsi in posizioni diverse.

Nota che un Arduino Uno con layout R3 (pinout 1.0) ha anche i pin header SDA (linea dati) e SCL (linea clock) vicino al pin AREF. Consulta la tabella qui sotto per maggiori dettagli.

SchedaSDASCL
Arduino UnoA4A5
Arduino NanoA4A5
Arduino Micro23
Arduino Mega 25602021
Arduino Leonardo23
Arduino Due2021
Posizioni dei pin SDA e SCL su diverse schede Arduino.

Regolare il contrasto dell’LCD

Dopo aver collegato l’LCD, dovrai regolare il contrasto del display. Sul modulo I2C troverai un potenziometro che puoi ruotare con un piccolo cacciavite.

Collega il connettore USB dell’Arduino per alimentare l’LCD. Dovresti vedere accendersi la retroilluminazione. Ora ruota il potenziometro finché non appaiono una (LCD 16×2) o due righe (LCD 20×4) di rettangoli. Puoi regolare il contrasto anche in seguito se necessario.

Una volta fatto ciò, possiamo iniziare a programmare l’LCD.

Installare la libreria LiquidCrystal_I2C per Arduino

In questo tutorial userò la libreria LiquidCrystal_I2C . Questa libreria ha molte funzioni integrate che rendono la programmazione dell’LCD molto semplice.

L’ultima versione di questa libreria si trova qui:

Assicurati di avere installata questa esatta libreria ed elimina eventuali altre librerie con lo stesso nome (LiquidCrystal_I2C). Altre librerie potrebbero funzionare, ma potrebbero usare nomi leggermente diversi per le varie funzioni.

La libreria LiquidCrystal_I2C funziona in combinazione con la libreria Wire.h che permette di comunicare con dispositivi I2C. Questa libreria è preinstallata nell’IDE Arduino.

Per installare questa libreria, vai su Tools > Manage Libraries (Ctrl + Shift + I su Windows) nell’IDE Arduino.Arduino IDESi aprirà il Library Manager che aggiornerà la lista delle librerie installate.

Installing an Arduino library step 1 open Library Manager
Gestione librerie

Ora cerca ‘liquidcrystal_i2c’ e cerca la libreria di Frank de Brabander. Seleziona l’ultima versione e clicca su Install.

Installare la libreria LiquidCrystal_I2C per Arduino

La libreria include alcuni esempi che puoi usare, ma dovrai modificarli per adattarli al tuo hardware. Ho incluso molti esempi di codice qui sotto che puoi usare con il cablaggio mostrato in precedenza.

Prima ti mostrerò un esempio base di codice e poi spiegherò le funzioni in dettaglio.

Come trovare l’indirizzo I2C del mio LCD?

La maggior parte degli LCD I2C viene fornita con l’indirizzo predefinito ‘0x27’, ma può variare a seconda del lotto o del produttore. In tal caso, dovrai trovare l’indirizzo reale dell’LCD prima di poterlo usare. Sul sito Arduino puoi trovare uno sketch di esempio che scansiona il bus I2C per dispositivi. Se viene trovato un dispositivo, l’indirizzo viene mostrato nel monitor seriale.

/*I2C_scanner
  This sketch tests standard 7-bit addresses.
  Devices with higher bit address might not be seen properly.
*/
  
#include "Wire.h"

void setup() {
  Wire.begin();

  Serial.begin(9600);
  while (!Serial);
  Serial.println("\nI2C Scanner");
}

void loop() {
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for (address = 1; address < 127; address++ ) {
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0) {
      Serial.print("I2C device found at address 0x");
      if (address < 16)
        Serial.print("0");
      Serial.print(address, HEX);
      Serial.println("  !");

      nDevices++;
    }
    else if (error == 4) {
      Serial.print("Unknown error at address 0x");
      if (address < 16)
        Serial.print("0");
      Serial.println(address, HEX);
    }
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");

  delay(5000);
}

Se carichi questo sketch su Arduino e lo esegui, dovresti vedere il seguente output nel Monitor Seriale (Ctrl + Shift + M).

I2C Address finder serial monitor output
Output del monitor seriale dello scanner indirizzi I2C

Annota l’indirizzo che trovi, ti servirà più avanti per programmare l’LCD.

Esempio base di codice Arduino per LCD I2C

Questo sketch di esempio visualizzerà il classico ‘Hello World!’ sulla prima riga dell’LCD e ‘LCD tutorial’ sulla seconda riga.

/* I2C LCD with Arduino example code. More info: https://www.makerguides.com */

#include "Wire.h" // Library for I2C communication
#include "LiquidCrystal_I2C.h" // Library for LCD

// Wiring: SDA pin is connected to A4 and SCL pin to A5.
// Connect to LCD via I2C, default address 0x27 (A0-A2 not jumpered)
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2); // Change to (0x27,20,4) for 20x4 LCD.

void setup() {
  // Initiate the LCD:
  lcd.init();
  lcd.backlight();
}

void loop() {
  // Print 'Hello World!' on the first line of the LCD:
  lcd.setCursor(2, 0); // Set the cursor on the third column and first row.
  lcd.print("Hello World!"); // Print the string "Hello World!"
  lcd.setCursor(2, 1); //Set the cursor on the third column and the second row (counting starts at 0!).
  lcd.print("LCD tutorial");
}

Dovresti vedere il seguente output sul display LCD:

i2c lcd with arduino hello world
Output sul display LCD

Ora spiegherò come funziona il codice.

Come funziona il codice

Per prima cosa vengono incluse le librerie necessarie. Come detto prima, servono sia Wire.h che LiquidCrystal_I2C. Nel resto di questo tutorial coprirò altre funzioni integrate di questa libreria.

#include "Wire.h" // Library for I2C communication
#include "LiquidCrystal_I2C.h" // Library for LCD

Il passo successivo è creare un oggetto LCD con la classe LiquidCrystal_I2C e specificare l’indirizzo e le dimensioni. Per questo usiamo la funzione LiquidCrystal_I2C(address, columns, rows).

Qui dovrai cambiare l’indirizzo predefinito con quello che hai trovato prima, se è diverso. Se usi un LCD 20×4, cambia questa riga in LiquidCrystal_I2C(0x27,20,4);

Nota che abbiamo chiamato il display ‘lcd’. Puoi dargli un nome diverso, come ‘menu_display’. Dovrai sostituire ‘lcd’ con il nuovo nome nel resto dello sketch.

// Connect to LCD via I2C, default address 0x27 (A0-A2 not jumpered)
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2); // Change to (0x27,20,4) for 20x4 LCD.

Setup

Nel setup, l’LCD viene inizializzato con lcd.init() e la retroilluminazione viene accesa con lcd.backlight().

void setup() {
  // Initiate the LCD:
  lcd.init();
  lcd.backlight();
}

Loop

Nella sezione loop del codice, il cursore viene posizionato sulla terza colonna e prima riga dell’LCD con lcd.setCursor(2,0).

Ricorda che il conteggio parte da 0 e il primo argomento specifica la colonna. Quindi lcd.setCursor(2,1) posiziona il cursore sulla terza colonna e seconda riga.

Poi la stringa ‘Hello World!’ viene stampata con lcd.print("Hello World!"). Nota che devi mettere le virgolette (” “) intorno al testo perché stiamo stampando una text string.

Quando vuoi stampare numeri, non servono virgolette. Per esempio lcd.print(12345).

void loop() {
  lcd.setCursor(2, 0); // Set the cursor on the third column and first row.
  lcd.print("Hello World!"); // Print the string "Hello World!".
  lcd.setCursor(2, 1); //Set the cursor on the third column and the second row.
  lcd.print("LCD tutorial"); // Print the string "LCD tutorial".
}

Se vuoi vedere un esempio per visualizzare (modificare) variabili sull’LCD, dai un’occhiata al mio tutorial sul sensore di distanza a ultrasuoni HC-SR04:

Altre funzioni utili della libreria LiquidCrystal_I2C

Lo sketch di esempio sopra mostra le basi per visualizzare testo sull’LCD. Ora vedremo le altre funzioni della libreria LiquidCrystal_I2C.

clear()

Pulisce lo schermo LCD e posiziona il cursore nell’angolo in alto a sinistra (prima riga e prima colonna) del display. Puoi usare questa funzione per mostrare parole diverse in un ciclo.

#include "LiquidCrystal_I2C.h"

LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup() {
  lcd.init();
  lcd.backlight();
}

void loop() {
  lcd.clear();
  lcd.print("Monday");
  delay(2000);
  lcd.clear();
  lcd.print("13:45");
  delay(2000);
}

home()

Posiziona il cursore nell’angolo in alto a sinistra dell’LCD. Usa clear() se vuoi anche cancellare il display.

cursor()

Mostra il cursore LCD: un underscore (linea) nella posizione del prossimo carattere da stampare.

noCursor()

Nasconde il cursore LCD. L’esempio seguente crea un cursore lampeggiante alla fine di “Hello World!”.

#include "LiquidCrystal_I2C.h"

LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup() {
  lcd.init();
  lcd.backlight();
  lcd.print("Hello World!");
}

void loop() {
  lcd.cursor();
  delay(500);
  lcd.noCursor();
  delay(500);
}

blink()

Crea un cursore LCD a blocco lampeggiante: un rettangolo lampeggiante nella posizione del prossimo carattere da stampare.

noBlink()

Disabilita il cursore a blocco lampeggiante. L’esempio seguente mostra il cursore lampeggiante per 5 secondi e poi lo disabilita per 2 secondi.

#include "LiquidCrystal_I2C.h"

LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);

void setup() {
  lcd.init();
  lcd.backlight();
  lcd.print("blink() example");
}

void loop() {
  lcd.blink();
  delay(5000);
  lcd.noBlink();
  delay(2000);
}

display()

Questa funzione accende lo schermo LCD e mostra qualsiasi testo o cursore stampato sul display.

noDisplay()

Questa funzione spegne qualsiasi testo o cursore stampato sull’LCD. Il testo/dati non vengono cancellati dalla memoria dell’LCD.

Questo significa che verranno mostrati di nuovo quando la funzione display() viene richiamata.

L’esempio seguente crea un effetto di testo lampeggiante.

#include "LiquidCrystal_I2C.h"

LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);

void setup() {
  lcd.init();
  lcd.backlight();
  lcd.print("Blinking text");
}

void loop() {
  lcd.display();
  delay(2000);
  lcd.noDisplay();
  delay(2000);
}

write()

Questa funzione può essere usata per scrivere un carattere sull’LCD. Vedi la sezione su come creare e visualizzare caratteri personalizzati qui sotto per maggiori informazioni.

scrollDisplayLeft()

Scorre il contenuto del display (testo e cursore) di uno spazio a sinistra.

Puoi usare questa funzione nella sezione loop del codice in combinazione con delay(500), per creare un’animazione di testo scorrevole.

#include "LiquidCrystal_I2C.h"

LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);

void setup() {
  lcd.init();
  lcd.backlight();
  lcd.print("Hello World!");
}

void loop() {
  lcd.scrollDisplayLeft();
  delay(500);
}

scrollDisplayRight()

Scorre il contenuto del display (testo e cursore) di uno spazio a destra.

autoscroll()

Questa funzione attiva lo scorrimento automatico dell’LCD. Questo fa sì che ogni carattere inviato al display spinga i caratteri precedenti di uno spazio.

Se la direzione del testo è da sinistra a destra (default), il display scorre verso sinistra; se la direzione è da destra a sinistra, il display scorre verso destra.

Questo ha l’effetto di stampare ogni nuovo carattere nella stessa posizione sull’LCD.

Lo sketch di esempio seguente abilita lo scorrimento automatico e stampa i caratteri da 0 a 9 nella posizione (16,0) dell’LCD. Cambia in (20,0) per un LCD 20×4.

#include "LiquidCrystal_I2C.h"

LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);

void setup() {
  lcd.init();
  lcd.backlight();
}

void loop() {
  lcd.autoscroll();
  lcd.setCursor(16, 0);
  for (int x = 0; x < 10; x++) {
    lcd.print(x);
    delay(500);
  }
  lcd.clear();
}

noAutoscroll()

Disabilita lo scorrimento automatico dell’LCD.

leftToRight()

Questa funzione fa scorrere il testo verso destra dal cursore, come se il display fosse allineato a sinistra (default).

rightToLeft()

Questa funzione fa scorrere il testo verso sinistra dal cursore, come se il display fosse allineato a destra.

Come creare e visualizzare caratteri personalizzati?

Con la funzione createChar() è possibile creare e visualizzare caratteri personalizzati sull’LCD. Questo è particolarmente utile se vuoi mostrare un carattere che non fa parte del ASCII character set.

CGROM e CGRAM

Gli LCD basati sul controller Hitachi HD44780 hanno due tipi di memoria: CGROM e CGRAM (Character Generator ROM e RAM).

CGROM genera tutti i pattern di caratteri 5 x 8 punti dai codici carattere standard a 8 bit. CGRAM può generare pattern di caratteri definiti dall’utente.

Per display 5 x 8 punti, CGRAM può scrivere fino a 8 caratteri personalizzati e per display 5 x 10 punti 4. Per maggiori informazioni consulta il datasheet.

Esempio di codice per caratteri personalizzati

Lo sketch di esempio seguente crea e visualizza otto caratteri personalizzati (numerati da 0 a 7). Puoi copiare il codice cliccando sul pulsante in alto a destra nel campo del codice.

/* Arduino example code to display custom characters on I2C character LCD. More info: www.www.makerguides.com */

// Include the library:
#include "LiquidCrystal_I2C.h"

// Create lcd object of class LiquidCrystal_I2C:
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2); // Change to (0x27,20,4) for 20x4 LCD.

// Make custom characters:
byte Heart[] = {
  B00000,
  B01010,
  B11111,
  B11111,
  B01110,
  B00100,
  B00000,
  B00000
};

byte Bell[] = {
  B00100,
  B01110,
  B01110,
  B01110,
  B11111,
  B00000,
  B00100,
  B00000
};

byte Alien[] = {
  B11111,
  B10101,
  B11111,
  B11111,
  B01110,
  B01010,
  B11011,
  B00000
};

byte Check[] = {
  B00000,
  B00001,
  B00011,
  B10110,
  B11100,
  B01000,
  B00000,
  B00000
};

byte Speaker[] = {
  B00001,
  B00011,
  B01111,
  B01111,
  B01111,
  B00011,
  B00001,
  B00000
};

byte Sound[] = {
  B00001,
  B00011,
  B00101,
  B01001,
  B01001,
  B01011,
  B11011,
  B11000
};

byte Skull[] = {
  B00000,
  B01110,
  B10101,
  B11011,
  B01110,
  B01110,
  B00000,
  B00000
};

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

void setup() {
  // Initialize LCD and turn on the backlight:
  lcd.init();
  lcd.backlight();

  // Create new characters:
  lcd.createChar(0, Heart);
  lcd.createChar(1, Bell);
  lcd.createChar(2, Alien);
  lcd.createChar(3, Check);
  lcd.createChar(4, Speaker);
  lcd.createChar(5, Sound);
  lcd.createChar(6, Skull);
  lcd.createChar(7, Lock);

  // Clear the LCD screen:
  lcd.clear();

  // Print a message to the lcd:
  lcd.print("Custom Character");
}

// Print all the custom characters:
void loop() {
  lcd.setCursor(0, 1);
  lcd.write(0);

  lcd.setCursor(2, 1);
  lcd.write(1);

  lcd.setCursor(4, 1);
  lcd.write(2);

  lcd.setCursor(6, 1);
  lcd.write(3);

  lcd.setCursor(8, 1);
  lcd.write(4);

  lcd.setCursor(10, 1);
  lcd.write(5);

  lcd.setCursor(12, 1);
  lcd.write(6);

  lcd.setCursor(14, 1);
  lcd.write(7);
}

Dovresti vedere il seguente output sull’LCD:

i2c lcd with arduino custom characters
Visualizzazione di caratteri personalizzati

Come funziona il codice

Dopo aver incluso la libreria e creato l’oggetto LCD, vengono definiti gli array dei caratteri personalizzati. Ogni array è composto da 8 byte (considerando solo 5 bit). C’è 1 byte per ogni riga della matrice LED 5 x 8. In questo esempio vengono creati 8 caratteri personalizzati.

// Make custom characters:
byte Heart[] = {
  B00000,
  B01010,
  B11111,
  B11111,
  B01110,
  B00100,
  B00000,
  B00000
};

Guardando attentamente l’array, vedrai quanto segue. Ogni riga è composta da 5 numeri corrispondenti ai 5 pixel di un carattere 5 x 8 punti. Uno 0 significa pixel spento e 1 pixel acceso. Il prefisso ‘B’ è il formato binario specifico di Arduino.

È possibile modificare ogni riga a mano, ma consiglio di usare questa applicazione online LCD Custom Character Generator. Questa applicazione crea automaticamente l’array del carattere e puoi cliccare sui pixel per accenderli o spegnerli.

Nel setup, i caratteri personalizzati vengono creati con lcd.createChar(num, data). Il primo argomento di questa funzione è il numero del carattere personalizzato (0-7) e il secondo è l’array del carattere che abbiamo creato.

  // Create new characters:
  lcd.createChar(0, Heart);
  lcd.createChar(1, Bell);
  lcd.createChar(2, Alien);
  lcd.createChar(3, Check);
  lcd.createChar(4, Speaker);
  lcd.createChar(5, Sound);
  lcd.createChar(6, Skull);
  lcd.createChar(7, Lock);

Nella loop, tutti i caratteri vengono visualizzati con lcd.write(). Come argomento usiamo il numero del carattere personalizzato che vogliamo mostrare.

  lcd.setCursor(0, 1);
  lcd.write(0);

Conclusione

In questo articolo ti ho mostrato come usare un LCD a caratteri I2C con Arduino. Abbiamo anche un articolo su How To Control A Character I2C LCD with ESP32, se vuoi lavorare con un microcontrollore ESP32 invece.

Se hai domande, suggerimenti o pensi che manchi qualcosa in questo tutorial, lascia pure un commento qui sotto.