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
| 16×2 character I2C LCD | × 1 | Amazon | |
| 20×4 character I2C LCD (alternativa) | × 1 | Amazon | |
| Arduino Uno Rev3 | × 1 | Amazon | |
| Jumper wires (maschio a femmina) | × 4 | Amazon | |
| USB cable type A/B | × 1 | Amazon |
Strumenti
Software
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.

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 funzionamento | 5 V |
| Controller | Controller LCD Hitachi HD44780 |
| Indirizzo predefinito | 0x27 |
| Risoluzione dello schermo | 2 righe × 16 caratteri |
| Risoluzione del carattere | 5 × 8 pixel |
| Dimensioni del modulo | 80 × 36 × 12 mm |
| Dimensioni dell’area visibile | 64.5 × 16.4 mm |
| Costo | Check 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.
Le connessioni sono anche riportate nella tabella qui sotto.
Connessioni I2C LCD
| LCD a caratteri I2C | Arduino |
|---|---|
| GND | GND |
| VCC | 5 V |
| SDA | A4 |
| SCL | A5 |
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.
| Scheda | SDA | SCL |
|---|---|---|
| Arduino Uno | A4 | A5 |
| Arduino Nano | A4 | A5 |
| Arduino Micro | 2 | 3 |
| Arduino Mega 2560 | 20 | 21 |
| Arduino Leonardo | 2 | 3 |
| Arduino Due | 20 | 21 |
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.

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

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).
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:

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:

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.



