
Lo schermo OLED
Questo modulo è un display OLED monocromatico 128×64 con interfaccia Grove a 4 pin I²C, adatto a mostrare testi e semplici indicatori grafici direttamente dall’Arduino Sensor Kit. Rispetto agli LCD, gli OLED offrono autoluminescenza, alto contrasto, ampio angolo di visione e basso consumo, perché non richiedono retroilluminazione.

L’OLED (Organic Light-Emitting Diode) usa materiali organici che emettono luce quando attraversati da corrente; non avendo una retroilluminazione, ogni pixel deve essere acceso/aggiornato dal controller. Nel Sensor Kit l’OLED 0,96″ (famiglia SSD1306/SSD1315) si controlla in modo semplificato tramite la libreria Arduino_SensorKit, che fornisce la classe Oled con metodi pronti per inizializzazione, posizionamento del cursore e stampa del testo.
Collegamento
- Inserire il modulo/display sul connettore I2C del Grove Base Shield, monta lo shield su Arduino UNO e collega via USB.
- Impostare l’interruttore del Base Shield su 5V (necessario per alimentare correttamente il display).
- Su Arduino UNO i pin I²C sono SDA=A4 e SCL=A5; l’indirizzo I²C tipico dei moduli SSD1306 è 0x3C (alcuni esemplari possono usare 0x3D). Se non risponde, esegui uno scanner I²C per verificarlo.
- Sull’Arduino Sensor Kit collegare il display al connettore I2C come mostrato nell’immagine che segue.

Librerie da utilizzare
Oled.begin() inizializza il controller con l’indirizzo corretto e imposta modalità/parametri base di comunicazione I²C.
Oled.setCursor(x,y) posiziona il cursore: con l’API U8x8 esposta dal kit lavori in celle di carattere 8×8 (circa 16 colonne × 8 righe su 128×64).
Oled.print(...) scrive testo/valori;
Oled.refreshDisplay() aggiorna lo schermo.
L’API U8x8 è “testo-only” e non richiede buffer RAM; per disegni pixel-level bisogna usare l’API grafica U8g2 (con font e funzioni grafiche più ricche).
Le differenze tra le due API:
- U8x8 = velocità e semplicità e solo per testo;
- U8g2 = grafica avanzata con e richiede più memoria.
Per i più curiosi
Il controller SSD1306 gestisce la RAM del display per pagine e supporta vari modi di indirizzamento (orizzontale/verticale/pagina). Le librerie si occupano dei dettagli, ma sapere che l’aggiornamento avviene “a blocchi” aiuta a capire perché alcune operazioni grafiche richiedono più tempo/buffer.
Specifiche del display
- Alimentazione: 3,3–5 V (compatibile con UNO).
- Interfaccia: I²C (Grove 4 pin).
- Indirizzo: 0x3C (varianti 0x3D).
- Caratteristiche d’uso: alto contrasto, basso consumo, ampia temperatura operativa (fino a –40…+85 °C su molte versioni).
Qualche consiglio da tenere a mente durante le sperimentazioni
- Non lasciare per ore la stessa immagine ad alto contrasto; meglio aggiornare periodicamente o usare una schermata di riposo.
- Stabilità del contenuto: se il testo “sfarfalla”, stampare prima su Serial Monitor per verificare i valori e ridurre la frequenza di refresh (es. ogni 100–200 ms).
- Differenza tra griglia di caratteri (U8x8) e coordinate in pixel (U8g2): una “barra” fatta di caratteri ha 16 step, mentre a pixel può averne 128.
Esempi pratici
Versione con commenti per gli studenti in cui viene dettagliato il funzionamento di ogni parte del codice.
Esempio 1 (semplice)
/*
Prof. Maffucci Michele
25/09/2025
OLED – Scrivere nome e cognome - versione 1
Inizializzare il display OLED del Sensor Kit e mostrare
"Allievo:" su una riga, poi Nome e Cognome sulla riga sotto.
*/
#include <Arduino_SensorKit.h> // Include la libreria del Sensor Kit.
// Questa libreria mette a disposizione l’oggetto 'Oled' (già pronto)
// per usare facilmente il display senza dover scrivere codice di basso livello (I2C).
void setup() {
Oled.begin();
// Inizializza il display OLED.
// Fa partire la comunicazione I2C e manda al display la sequenza di avvio.
// Senza questa riga lo schermo non mostra nulla.
Oled.setFlipMode(true);
// Ruota il contenuto di 180° (utile se lo vedi capovolto).
// Se nel tuo caso appare già dritto, puoi mettere false: Oled.setFlipMode(false);
Oled.setFont(u8x8_font_chroma48medium8_r);
// Sceglie il font (carattere) 8x8.
// Con un font 8x8 il display 128x64 si comporta come una griglia 16 colonne × 8 righe.
// Significa che setCursor(colonna, riga) userà numeri tra 0..15 (colonne) e 0..7 (righe).
Oled.clear();
// Pulisce lo schermo (cancella tutto quello che c’era prima).
Oled.setCursor(0, 2);
// Posiziona il cursore alla colonna 0, riga 2 (terza riga dall’alto).
// Le coordinate sono "a caratteri" (non in pixel).
Oled.print("Allievo:");
// Stampa il testo "Allievo:" nella posizione corrente.
Oled.setCursor(0, 4);
// Sposta il cursore alla riga 4 (quinta riga), colonna 0.
// Qui stamperemo nome e cognome.
Oled.print("Michele");
// Stampa il nome.
Oled.print(" ");
// Stampa uno spazio tra nome e cognome.
Oled.print("Maffucci");
// Stampa il cognome.
Oled.refreshDisplay();
// Aggiorna fisicamente lo schermo.
// Finché non richiami refreshDisplay(), il display potrebbe non mostrare i nuovi testi.
}
void loop() {
// Vuoto: non dobbiamo aggiornare nulla in continuazione.
// Il display mantiene il testo finché non lo cambiamo nel codice.
}
Esempio 1 – senza commenti
Nel caso servisse copiare ed incollare solamente il codice per poi inserire i propri commenti vi lascio anche la versione senza commenti:
#include <Arduino_SensorKit.h>
void setup() {
Oled.begin();
Oled.setFlipMode(true);
Oled.setFont(u8x8_font_chroma48medium8_r);
Oled.clear();
Oled.setCursor(0, 2);
Oled.print("Allievo:");
Oled.setCursor(0, 4);
Oled.print("Michele");
Oled.print(" ");
Oled.print("Maffucci");
Oled.refreshDisplay();
}
void loop() {
}


Esempio 1 – avanzato
Versione con commenti per gli studenti in cui viene dettagliato il funzionamento di ogni parte del codice.
/*
Prof. Maffucci Michele
25/09/2025
Scrive nome e cognome dell’allievo sul display OLED del Sensor Kit.
- Usa la libreria Arduino_SensorKit (oggetto Oled).
- Dimostrazione uso di: const char*, Oled.begin(), setFlipMode, setFont, setCursor, print, clear, refreshDisplay.
*/
#include <Arduino_SensorKit.h> // Include la libreria che espone l’oggetto 'Oled'.
// -----------------------------------------------------------------------------
// DICHIARAZIONE DELLE STRINGHE
// 'const char*' = puntatore a caratteri costanti (stringa C in sola lettura).
// Puntano a letterali con terminatore '\0' (durata statica, non vanno modificati).
// -----------------------------------------------------------------------------
const char* nomeAllievo = "Michele"; // sostituisci con il nome reale (es. "Luca")
const char* cognomeAllievo = "Maffucci"; // sostituisci con il cognome (es. "Rossi")
void setup() {
// ---------------------------------------------------------------------------
// INIZIALIZZAZIONE DEL DISPLAY
// Oled.begin() avvia l'I2C e programma il controller del display (SSD1306/1315).
// Senza questa chiamata, il display non mostrerà nulla.
// ---------------------------------------------------------------------------
Oled.begin();
// setFlipMode(true) ruota il contenuto di 180°.
// Usarlo se il testo appare "capovolto" a causa dell’orientamento fisico.
// Mettere false se già si vede diritto.
Oled.setFlipMode(true);
// Seleziona il font 8x8 "chroma48medium8_r".
// Con font 8x8, lo schermo 128x64 si comporta come una griglia 16 colonne × 8 righe.
Oled.setFont(u8x8_font_chroma48medium8_r);
// ---------------------------------------------------------------------------
// PULIZIA E STAMPA DEL CONTENUTO
// ---------------------------------------------------------------------------
// Cancella tutto il contenuto precedente del display.
Oled.clear();
// Posiziona il cursore (colonna=0, riga=2) in coordinate "a caratteri" (non pixel).
// (0,2) significa: prima colonna, terza riga della griglia 16x8.
Oled.setCursor(0, 2);
// Stampa un’etichetta. Con la macro F("...") il testo resta in flash (serve per risparmiare RAM).
Oled.print(F("Allievo:"));
// Vai a riga 4, colonna 0, e stampa nome + cognome separati da spazio.
Oled.setCursor(0, 4);
Oled.print(nomeAllievo); // stampa la stringa puntata da 'nomeAllievo'
Oled.print(" "); // spazio tra nome e cognome
Oled.print(cognomeAllievo);
// Aggiorna fisicamente lo schermo: senza refresh, la nuova scritta potrebbe non apparire.
Oled.refreshDisplay();
}
void loop() {
// Nessuna azione periodica: il display mantiene il contenuto finché non lo cambiate.
// (Se volete far lampeggiare o scorrere il testo, lo fareste nel loop)
}
Esempio 1 – avanzato – senza commenti
#include <Arduino_SensorKit.h>
const char* nomeAllievo = "Michele";
const char* cognomeAllievo = "Maffucci";
void setup() {
Oled.begin();
Oled.setFlipMode(true);
Oled.setFont(u8x8_font_chroma48medium8_r);
Oled.clear();
Oled.setCursor(0, 2);
Oled.print(F("Allievo:"));
Oled.setCursor(0, 4);
Oled.print(nomeAllievo);
Oled.print(" ");
Oled.print(cognomeAllievo);
Oled.refreshDisplay();
}
void loop() {
}
Che cosa significa char*? Perché const char* qui?
char è il tipo carattere in C/C++ (1 byte).
char* è un puntatore a char: invece di contenere direttamente un carattere, contiene l’indirizzo di memoria dove si trova una sequenza di caratteri (una stringa in stile C).
- Le stringhe letterali scritte tra virgolette, es.
"Nome", sono array di char terminati da \0 (null terminator). Hanno durata statica: esistono per tutta l’esecuzione del programma e sono solitamente in sola lettura.
Per questo si usa:
const char* nomeAllievo = "Nome";
const indica che non vogliamo (e non dobbiamo) modificare quei caratteri (sono un letterale costante).
- Il tipo completo si legge: “puntatore a char costanti“. Potete cambiare il puntatore (farlo puntare ad un’altra stringa), ma non i caratteri a cui punta.
Alternative possibili
const char nomeAllievo[] = "Nome";
(array di char costanti: il compilatore conosce la lunghezza e non potete riassegnare il nome dell’array).
String nomeAllievo = "Nome";
(classe Arduino String: comoda ma usa più RAM dinamica; in progetti grandi può frammentare l’heap).
Nota su Arduino/AVR: i letterali come "testo" possono occupare SRAM a runtime se non si usa la macro F("testo") o PROGMEM. Nel nostro sketch la dimensione è minuscola, ma per testi lunghi conviene Oled.print(F("Allievo:")) per risparmiare RAM.
A cosa serve Oled.begin()
Oled.begin() inizializza il display OLED del Sensor Kit. In pratica:
- Avvia la comunicazione I²C verso il controller del display (SSD1306/SSD1315) all’indirizzo corretto.
- Manda la sequenza di setup al controller (accensione, modalità, contrasto di base, orientamento di default, ecc.).
- Prepara l’oggetto
Oled a ricevere comandi come setCursor, print, clear, refreshDisplay.
Senza Oled.begin() il display non risponde ai comandi, quindi va chiamato una volta nel setup().
Esempio 2
Lettura del valore analogico del potenziometro, visualizza il valore numerico grezzo dell’ADC e del valore percentuale sul display con barra (a carattere) di avanzamento.
Collegare il potenziometro all’ingresso A0.

/*
Prof. Maffucci Michele
25/09/2025
OLED
- Leggere il valore analogico dal potenziometro (0..1023 su Arduino UNO).
- Converte il valore in percentuale (0..100%).
- Visualizza il valore grezzo (ADC), la percentuale e una barra orizzontale su OLED.
Note:
- Usiamo la libreria Arduino_SensorKit che fornisce l'oggetto 'Oled' (display SSD1306/1315 via I2C).
- La barra è disegnata come sequenza di caratteri ASCII ('#').
*/
#include <Arduino_SensorKit.h> // Include l'API semplificata per i sensori e l'OLED del Sensor Kit
// --------------------- CONFIGURAZIONE INGRESSO ANALOGICO ---------------------
// PIN del potenziometro: collega il cursore del pot al pin A0 (e gli altri due capi a +5V e GND).
const int PIN_POT = A0;
// Variabili per memorizzare il valore letto (grezzo) e la percentuale calcolata.
int valoreADC = 0; // Gamma tipica su UNO: 0..1023 (10 bit)
int percento = 0; // 0..100 (%)
// L'OLED in modalità font 8x8 ha circa 16 colonne: la barra avrà da 0 a 16 "blocchi" pieni.
const uint8_t LARGHEZZA_BAR = 16;
// -----------------------------------------------------------------------------
// Funzione di utilità: disegna una barra percentuale su una riga 'y' del display.
// Parametri:
// - y: indice riga (0..7 se font 8x8; 0 è la prima riga in alto).
// - percent: valore 0..100 che determina la lunghezza della barra.
// -----------------------------------------------------------------------------
void disegnaBarraPercento(uint8_t y, uint8_t percent) {
// Converte la percentuale 0..100 nel numero di "blocchi" (0..16)
// (uint32_t) evita overflow nella moltiplicazione su microcontrollori a 16 bit.
uint8_t pieni = (uint32_t)percent * LARGHEZZA_BAR / 100;
// 1) Pulisce la riga della barra: stampa 16 spazi per "cancellare" ciò che c'era prima.
Oled.setCursor(0, y); // posiziona il cursore all'inizio riga
for (uint8_t i = 0; i < LARGHEZZA_BAR; i++) {
Oled.print(' '); // spazio = cella vuota
}
// 2) Ridisegna i "blocchi" pieni (da sinistra verso destra) usando un carattere visibile e portabile ('#').
Oled.setCursor(0, y); // torna all'inizio riga
for (uint8_t i = 0; i < pieni; i++) {
Oled.print('#'); // carattere della barra
}
}
void setup() {
// ------------------------ INIZIALIZZAZIONE OLED ----------------------------
Oled.begin(); // inizializza I2C e il controller del display
Oled.setFlipMode(true); // ruota 180° se il testo appare capovolto (mettere false se OK)
Oled.setFont(u8x8_font_chroma48medium8_r); // font 8x8: griglia circa 16 colonne × 8 righe
// Pulizia e titolo
Oled.clear(); // cancella lo schermo
Oled.setCursor(0, 0); // colonna 0, riga 0 (prima riga)
Oled.print("Potenziometro"); // titolo
Oled.refreshDisplay(); // aggiorna la visualizzazione
}
void loop() {
// ----------------------------- LETTURA ADC --------------------------------
// Per stabilizzare il valore (ridurre rumore), facciamo una media di 4 campioni.
long somma = 0;
for (int i = 0; i < 4; i++) { somma += analogRead(PIN_POT); // legge l'ingresso analogico A0: 0..1023 delay(2); // piccola pausa per lasciare stabilizzare } valoreADC = somma / 4; // media semplice dei 4 campioni // ----------------------- SCALATURA IN PERCENTUALE ------------------------- // 'map' converte da una scala a un'altra: qui 0..1023 > 0..100.
// Nota: 'map' restituisce un intero; per scale diverse potresti usare una formula float.
percento = map(valoreADC, 0, 1023, 0, 100);
// ----------------------------- STAMPA TESTO -------------------------------
// Riga 2: mostriamo il valore ADC grezzo.
Oled.setCursor(0, 2); // colonna 0, riga 2
Oled.print("ADC: "); // spazi finali per "coprire" cifre residue
Oled.setCursor(5, 2); // posiziona circa a metà riga
Oled.print(valoreADC); // valore numerico 0..1023
// Riga 3: mostriamo la percentuale.
Oled.setCursor(0, 3);
Oled.print("Perc: ");
Oled.setCursor(6, 3);
Oled.print(percento); // 0..100
Oled.print("%");
// ------------------------------ BARRA GRAFICA -----------------------------
// Disegna la barra percentuale alla riga 5 (sesta riga).
disegnaBarraPercento(5, percento);
// Aggiorna fisicamente il display (altrimenti potresti non vedere le modifiche).
Oled.refreshDisplay();
// Piccolo delay per fluidità; valori troppo bassi aumentano il "flicker",
// valori troppo alti rendono meno reattivo l'aggiornamento.
delay(60);
}

Buon Coding a tutti 🙂