Site icon Renzo Mischianti

SDD1306 OLED display: cablaggio nozioni di base con l’esp8266, esp32 e Arduino – 1

Display OLED ssd1306 arduino esp32 esp8266 basi

Display OLED ssd1306 arduino esp32 esp8266 basi

Spread the love

L’IC SSD1306 viene utilizzato per i display OLED più comuni, è un driver CMOS OLED/PLED a chip singolo con controller per sistema di visualizzazione grafica a matrice di punti a diodi emettitori di luce organici/polimerici. E’ formatp da 128 segmenti e 64 comuni.

Display OLED ssd1306 arduino esp32 esp8266 basics

L’SSD1306 integra il controllo del contrasto, la RAM del display e l’oscillatore, il che riduce il numero di componenti esterni e il consumo energetico. Ha un controllo della luminosità a 256 stadi. I dati/i comandi vengono inviati dall’MCU generale tramite l’interfaccia parallela compatibile con la serie 6800/8000 selezionabile tramite hardware, l’interfaccia I2C o SPI.

Il display OLED ssd1306 su AliExpress I2C SPI SSD1306 0.91 0.96 inch OLED


Caratteristiche

Cablaggio i2c

Arduino

Ricorda che Arduino funziona a 5v, quindi se la tua versione di Oled non supporta la logica a 5v devi inserire nel mezzo un convertitore di livello logico.

Arduino oled display sh1106 ssd1306 wiring

Qui il convertitore di livello logico Aliexpress

Arduino logic level converter 3v3 oled display sh1106 ssd1306 wiring

Il costruttore è abbastanza semplice:

/*
 * Arduino UNO 	<--> 	Oled
 * 3.3v					VCC
 * GND					GND
 * A4					SDA
 * A5					SCL
 */

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

[...]

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

esp8266

WeMos D1 mini esp8266 oled display sh1106 ssd1306 breadboard photo

Per ESP32 ed esp8266 è più semplice, perché il lavoro a 3.3v. Quindi non c’è bisogno di convertitore.

WeMos D1 mini esp8266 oled display sh1106 ssd1306 wiring

Il codice è lo stesso di Arduino, cambia solo il cablaggio (con standard i2c):

/*
 * WeMos D1	<--> 	Oled
 * 3.3v					VCC
 * GND					GND
 * D2					SDA
 * D1					SCL
 */

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

[...]

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

esp32

esp32 oled display sh1106 ssd1306 wiring
/*
 * ESP32	<--> 	Oled
 * 3.3v					VCC
 * GND					GND
 * 21					SDA
 * 22					SCL
 */

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

[...]

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

Cablaggio SPI

Arduino

Per SPI è necessario collegare più fili, non solo quello SPI ma anche RST e pin DC. Ricorda che Arduino ha un livello logico a 5v, quindi devi verificare che il tuo display supporti quella tensione.

Arduino oled display sh1106 ssd1306 SPI wiring
// Declaration for SSD1306 display connected using software SPI (default case):
#define OLED_MOSI   12
#define OLED_CLK   13
#define OLED_DC    9
#define OLED_CS    10
#define OLED_RESET 6
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

[...]

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

esp8266

WeMos D1 mini esp8266 oled display sh1106 ssd1306 wiring SPI breadboard photo

Per l’esp8266 ed esp32 è più semplice perché hanno una logica nativa a 3.3v.

WeMos D1 mini esp8266 oled display sh1106 ssd1306 wiring SPI
// Declaration for SSD1306 display connected using software SPI (default case):
#define OLED_MOSI   D7
#define OLED_CLK   D5
#define OLED_DC    D2
#define OLED_CS    D8
#define OLED_RESET D1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

[...]

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

esp32

esp32 oled display sh1106 ssd1306 wiring SPI
// Declaration for SSD1306 display connected using software SPI (default case):
#define OLED_MOSI   22
#define OLED_CLK   18
#define OLED_DC    16
#define OLED_CS    5
#define OLED_RESET 17
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

[...]

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

Libreria Adafruit

Tra le migliori librerie ci sono sempre quelle di Adafruit, gli obiettivi di Adafruit sono sempre semplicità e completezza.

Puoi trovarla su GitHub o scaricarla tramite il gestore di librerie dell’IDE di Arduino.

Arduino IDE manage library Adafruit ssd1306

Questa libreria ha 2 dipendenze Adafruit BusIO

Arduino IDE manage library Adafruit BusIO

e la libreria Adafruit GFX.

Arduino IDE manage library Adafruit GFX

Nozioni di base sul display

Puoi trovare le seguenti informazioni sul sito di Adafruit con molte altre cose, copio qui un sottoinsieme per dare semplici informazione di base e integro con alcuni altri suggerimenti.

Sistema di coordinate e unità

I pixel (elementi dell’immagine, i blocchi che costituiscono un’immagine digitale) sono indirizzati dalle coordinate orizzontali (X) e verticali (Y). Il sistema di coordinate posiziona l’origine (0,0) nell’angolo in alto a sinistra, con X positivo che aumenta a destra e Y positivo che aumenta verso il basso. Per utilizzare un layout “portrait” alto piuttosto che un formato “landscape” ampio è possibile applicare delle quattro impostazioni di rotazione, indicando quale angolo del display rappresenta l’angolo superiore sinistro .

I colori sono 1 (impostato) o 0 (trasparente). La semantica di un display OLED set/clear è “set” illuminato “clear” no.

Primitive grafiche

Qui una serie di comandi standard e cross display.

Disegnare pixels (punti)

The first is the drawing of an elementary pixel. Puoi chiamarlo con le coordinate X, Y e un colore e creerà un singolo punto:

void drawPixel(uint16_t x, uint16_t y, uint16_t color);

Disegnare linee

Puoi anche disegnare linee, con un punto iniziale e finale e un colore:

void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color);

Per le linee orizzontali o verticali, sono disponibili funzioni di disegno delle linee ottimizzate che evitano i calcoli angolari:

void drawFastVLine(uint16_t x0, uint16_t y0, uint16_t length, uint16_t color);
void drawFastHLine(uint8_t x0, uint8_t y0, uint8_t length, uint16_t color);

Rettangoli

Poi, rettangoli e quadrati possono essere disegnati e riempiti utilizzando le seguenti procedure. Ciascuno accetta una coppia X, Y per l’angolo superiore sinistro del rettangolo, una larghezza e un’altezza (in pixel) e un colore. drawRect() disegna solo la cornice (contorno) del rettangolo mentre fillRect() riempie l’intera area con un dato colore:

void drawRect(uint16_t x0, uint16_t y0, uint16_t w, uint16_t h, uint16_t color);void fillRect(uint16_t x0, uint16_t y0, uint16_t w, uint16_t h, uint16_t color);

Per creare un rettangolo solido con un contorno, usa prima fillRect(), quindi drawRect() su di esso.

Cerchi

Allo stesso modo, per i cerchi, puoi disegnare e riempire. Ogni funzione accetta una coppia X, Y per il punto centrale, un raggio in pixel e un colore:

void drawCircle(uint16_t x0, uint16_t y0, uint16_t r, uint16_t color);
void fillCircle(uint16_t x0, uint16_t y0, uint16_t r, uint16_t color);

Rettangoli arrotondati

Per i rettangoli con angoli arrotondati, sono nuovamente disponibili sia le funzioni di disegno che di riempimento. Ognuno inizia con X, Y, larghezza e altezza (proprio come i normali rettangoli), quindi c’è un raggio d’angolo (in pixel) e infine il valore del colore:

void drawRoundRect(uint16_t x0, uint16_t y0, uint16_t w, uint16_t h, uint16_t radius, uint16_t color);
void fillRoundRect(uint16_t x0, uint16_t y0, uint16_t w, uint16_t h, uint16_t radius, uint16_t color);

Ecco un ulteriore trucco: poiché le funzioni del cerchio sono sempre disegnate rispetto a un pixel centrale, il diametro del cerchio risultante sarà sempre un numero dispari di pixel.

Triangoli

Con i triangoli, ancora una volta ci sono le funzioni di disegno e riempimento. Ciascuno richiede ben sette parametri: le coordinate X, Y per tre punti d’angolo che definiscono il triangolo, seguite da un colore:

void drawTriangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);
void fillTriangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);

Caratteri e testo

Ci sono due procedure di base per disegnare le stringhe e per aggiungere testo. 

Puoi posizionare un singolo carattere in qualsiasi luogo e con qualsiasi colore. C’è solo un carattere (per risparmiare spazio) ed è pensato per essere 5×8 pixel, ma può essere passato un parametro di dimensione opzionale che ridimensiona il carattere di questo fattore (ad esempio size=2 renderà il testo a 10×16 pixel per carattere). È un po’ pixelato, ma avere un solo carattere aiuta a ridurre le dimensioni del programma.

void drawChar(uint16_t x, uint16_t y, char c, uint16_t color, uint16_t bg, uint8_t size);

Il testo è molto flessibile ma funziona in modo leggermente diverso. Invece di una procedura, la dimensione del testo, il colore e la posizione sono impostati in funzioni separate e quindi viene utilizzata la funzione print(), questo lo rende facile e fornisce tutte le stesse capacità di formattazione di stringhe e numeri del familiare Serial.print( )!

void setCursor(uint16_t x0, uint16_t y0);
void setTextColor(uint16_t color);
void setTextColor(uint16_t color, uint16_t backgroundcolor);
void setTextSize(uint8_t size);
void setTextWrap(boolean w);

Per impostazione predefinita, le righe di testo lunghe sono impostate per “andare a capo” automaticamente nella colonna più a sinistra. Per ignorare questo comportamento (in modo che il testo scorra sul lato destro del display, utile per gli effetti di selezione scorrevole), utilizzare setTextWrap(false). Il normale comportamento di wrapping viene ripristinato con setTextWrap(true).

Bitmaps

Puoi disegnare piccole bitmap monocromatiche (a un colore), utili per sprite e altre mini-animazioni o icone:

void drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h, uint16_t color);

Questo invia un blocco contiguo di bit al display, dove ogni bit “1” imposta il pixel corrispondente su “colore”, mentre ogni bit “0” viene saltato. x, y è l’angolo in alto a sinistra in cui viene disegnata la bitmap, w, h sono la larghezza e l’altezza in pixel.

Cancellazione o riempimento dello schermo

La funzione fillScreen() imposterà l’intero display su un dato colore, cancellando qualsiasi contenuto esistente:

void fillScreen(uint16_t color);

Puoi anche usare clearDisplay() per disattivare tutti i pixel.

void clearDisplay(void)

Per invertire la matrice (abilitare o disabilitare la modalità di inversione del display: bianco su nero vs nero su bianco) puoi usare invertDisplay.

void invertDisplay(bool i)

Per gestire la luminosità istantaneamente hai la funzione dim, che con true abilita la modalità di luminosità minima, false per la massima luminosità.

void dim(bool dim)

Per aggiornare la visualizzazione è possibile utilizzare.

void display(void)

Rotazione del display

Puoi anche ruotare il disegno. Possiamo ruotare solo di 0, 90, 180 o 270 gradi: qualsiasi altra cosa non è possibile.

void setRotation(uint8_t rotazione);

Scrollare la schermata

Sono presenti, inoltre, alcune funzioni per scorrere il contenuto dello schermo:

Utilizzo dei caratteri

Le versioni più recenti della libreria Adafruit GFX offrono la possibilità di utilizzare caratteri alternativi. Sono inclusi diversi caratteri alternativi, oltre alla possibilità di aggiungerne di nuovi.

Dopo aver #incluso Adafruit_GFX e le librerie specifiche per il display, includi i file di font che prevedi di utilizzare nel tuo schizzo. Per esempio:

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_SSD1306.h> // Hardware-specific library
#include <Fonts/FreeMonoBoldOblique12pt7b.h>

All’interno di questi file .h ci sono diverse strutture di dati, inclusa una struttura di caratteri principale che di solito avrà lo stesso nome del file di caratteri (meno .h). Per selezionare un font per successive operazioni grafiche, utilizzare la funzione setFont(), passando l’indirizzo  di questa struttura, come ad esempio:

tft.setFont(&FreeMonoBoldOblique12pt7b);

Per le chiamate successive a tft.print() ora utilizzeranno questo carattere. La maggior parte degli altri attributi che in precedenza funzionavano con il carattere integrato (colore, dimensione, ecc.) funzionano in modo simile qui.

Per tornare al carattere standard a dimensione fissa, chiama setFont(), passando NULL o nessun argomento:

tft.setFont();

Semplici sketch

Ora qualche sketch completo per mostrare le funzioni di base.

Scrivere testo

Ecco un semplice sketch che scrive un testo sullo schermo in una posizione specifica.

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup() {
  Serial.begin(115200);

  delay(2000);
  Serial.println(F("Starting!"));

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }
  Serial.println(F("Initialized!"));

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(2000); // Pause for 2 seconds

  // Clear the buffer
  display.clearDisplay();
  // Refresh (apply command)
  display.display();

  // Set color of the text
  display.setTextColor(SSD1306_WHITE);
  // Set position of cursor
  display.setCursor(10, 20);
  // Set text size multiplier (x1 standard size)
  display.setTextSize(1);
  // print text like Serial
  display.print(F("www.mischianti.org"));

  display.setCursor(10, 50);
  // Set color of the text and color of the background
  display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
  display.setTextSize(1);
  display.print(F("www.mischianti.org"));

  // Refresh (apply command)
  display.display();
}

void loop() {
}

Il risultato è:

ssd1306 write text on oled display

Disegna pixel e linee

Ora disegneremo un singolo pixel e una linea.

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup() {
  Serial.begin(115200);

  delay(2000);
  Serial.println(F("Starting!"));

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }
  Serial.println(F("Initialized!"));

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(2000); // Pause for 2 seconds

  // Clear the buffer
  display.clearDisplay();
  // Refresh (apply command)
  display.display();

  // Draw a single pixel
  display.drawPixel(10, 10, SSD1306_WHITE);

  // Draw line
  display.drawLine(10, 35, 114, 54, WHITE);

  // Refresh (apply command)
  display.display();
}

void loop() {
}

E il risultato:

ssd1306 draw pixels and lines on oled display

Disegna rettangoli normali, arrotondati e quadrati

Qui lo sketch.

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup() {
  Serial.begin(115200);

  delay(2000);
  Serial.println(F("Starting!"));

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }
  Serial.println(F("Initialized!"));

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(2000); // Pause for 2 seconds

  // Clear the buffer
  display.clearDisplay();
  // Refresh (apply command)
  display.display();

  // Draw a rectangle perimeter
  display.drawRect(25, 10, 30, 20, WHITE);

  // Draw a filled rectangle
  display.fillRect(25, 40, 30, 20, WHITE);

  // Draw a round rectangle perimeter
  display.drawRoundRect(75, 10, 30, 20, 5, WHITE);

  // Draw a round rectangle perimeter
  display.fillRoundRect(75, 40, 30, 20, 5, WHITE);

  // Refresh (apply command)
  display.display();
}

void loop() {
}

E qui il risultato

ssd1306 draw round rectangle square oled display

Disegnare cerchio e triangolo

Le ultime forme sono cerchio e triangolo, qui lo sketch.

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup() {
  Serial.begin(115200);

  delay(2000);
  Serial.println(F("Starting!"));

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }
  Serial.println(F("Initialized!"));

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(2000); // Pause for 2 seconds

  // Clear the buffer
  display.clearDisplay();
  // Refresh (apply command)
  display.display();

  // Draw a circle perimeter
  display.drawCircle(40, 20, 10, WHITE);

  // Draw a filled circle
  display.fillCircle(40, 50, 10, WHITE);

  // Draw a triangle perimeter
  display.drawTriangle(75, 10, 105, 20, 80, 30, WHITE);

  // Draw a filled triangle
  display.fillTriangle(75, 40, 105, 50, 80, 60, WHITE);

  // Refresh (apply command)
  display.display();
}

void loop() {
}

E qui il risultato.

ssd1306 draw circle triangle oled display

Grazie

  1. Display OLED SDD1306: utilizzo di base con esp8266, esp32 e Arduino
  2. Display OLED SDD1306: immagini, splash e animazioni
  3. SDD1306 e PCF8574: gestisci più dispositivi su singolo i2c con interrupt

Spread the love
Exit mobile version