Utilizzo dei display in progetti con Raspberry Pi

Questo numero di Elektor Books presenta un capitolo tratto dal libro di Dogan Ibrahim "Using Displays in Raspberry Pi Projects" pubblicato da Elektor. Fin dalla loro introduzione, i display OLED sono stati favoriti dai Makers e dagli ingegneri dei sistemi embedded. In questo articolo esamineremo diverse modalità per implementare display OLED in vari progetti creando meno confusione possibile e con il minimo sforzo in termini di programmazione. Osiamo affermare che i suddetti requisiti puntano chiaramente verso Raspberry Pi, in quanto candidato perfetto. Scopriamolo in questo articolo!

Un diodo organico a emissione di luce (Organic Light-Emitting Diode, OLED) è un display LED nel quale lo strato elettroluminescente emissivo è costituito da una pellicola di composto organico in grado di emettere luce in presenza di una carica elettrica. Lo strato organico è situato tra due elettrodi, dei quali almeno uno è trasparente. I display OLED sono utilizzati in un gran numero di applicazioni commerciali, schermi televisivi, schermi di computer, smartphone, game console e altri dispositivi digitali. Gli OLED possono essere gestiti con controller a matrice passiva (PMOLED) o a matrice attiva (AMOLED). Solitamente, nei display di tipo PMOLED, ogni colonna e ogni linea sono controllate in maniera sequenziale, una alla volta. Nelle tipologie AMOLED un transistor backplane a film sottile è utilizzato per accedere e controllare direttamente l'accensione e lo spegnimento di ogni singolo pixel.

In generale, gli OLED hanno i seguenti vantaggi se comparati agli LCD:

  • Il consumo energetico degli OLED è molto basso, sono dunque ideali per gli schermi dei dispositivi mobile
  • I display OLED comportano ottimizzazione della qualità d'immagine, miglior contrasto, maggiore luminosità, angolo di visione più ampio e una frequenza di aggiornamento più rapida
  • Gli schermi OLED si caratterizzano per maggior durabilità, ciò li rende appropriati per essere utilizzati a un range di temperatura più esteso
  • Gli OLED possono essere flessibili, vengono infatti prodotti OLED pieghevoli, indossabili sul polso e così via dicendo

Gli OLED non sono comunque perfetti e comportano qualche svantaggio:

  • Il costo economico è piuttosto elevato
  • Si caratterizzano per un breve ciclo di vita (anche se numerose ricerche stanno cercando di ovviare a questo problema)
  • Data la loro naturale emissività, l'uso degli OLED può risultare problematico sotto la luce solare diretta

In Figura 1 sono rappresentati alcuni esempi di display OLED.

Utilizzo dei display OLED

Esiste un gran numero di display OLED disponibili in diverse misure e dimensioni, e con diverse matrici di pixel. È  ovviamente impossibile occuparci ora di tutti i tipi di display OLED disponibili sul mercato. In questo capitolo ci focalizzeremo su un modello piuttosto popolare, un display OLED 128x32 pixel, controllato con chip integrato SSD1306. Un ripasso delle caratteristiche del suddetto display potrebbe rivelarsi utile prima di cominciare a occuparsi del progetto. Il tipo di OLED che utilizzeremo è rappresentato in Figura 2.

Le specifiche di questo display OLED sono:

  • Risoluzione: 128 x 32 px
  • Colore Pixel: bianco (disponibile anche blu)
  • Dimensioni: 0.91 inch / 2,31 cm
  • Interfaccia:  I2C
  • Driver: SSD1306
  • 4 pin: GND, VCC, SCL (I2C), SDA (I2C)
  • Angolo di visione: > 160°
  • Tensione di esercizio: +3.3 V/+5 V

L'OLED basato su driver SSD1306 si interfaccia con il computer host attraverso l'interfaccia I2C (ad esempio, oltre ai pin GND e di alimentazione, sono richiesti solo 2 pin per l'interfaccia). Di default l'indirizzo del driver I2C è 0x3C.

Nella Figura 3 è rappresentata la connessione tra il Raspberry Pi e il display OLED. Normalmente il chip lavora a +3.3 V, ma c'è un regolatore di tensione sul chip che consente di operare anche a +5 V.

Installazione della libreria OLED

L'interfaccia I2C va abilitata su Raspberry Pi utilizzando lo strumento di configurazione
sudoraspi-config. Dopodiché dovrete installare la libreria OLED. In questo capitolo utilizzeremo la libreria Adafruit_Python_SSD1306.

Gli step vanno eseguiti come illustrato qui di seguito (alcune di queste librerie potrebbero essere già state installate sul vostro Raspberry Pi):

pi@raspberrypi:~ $ sudo apt install -y python3-dev

python3- pil python3- pip python3-setuptools python3-rpi.gpio
pi@raspberrypi:~ $ sudo pip3 install

adafruit-circuitpython-ssd1306

Prima di poter utilizzare qualsiasi dispositivo connettendolo all'interfaccia I2C, è necessario che l'indirizzo I2C venga rilevato. Per rilevare l'indirizzo I2C del display dovrete utilizzare il seguente comando nel terminale:

pi@raspberrypi:~ $ i2cdetect -y 1

Il risultato del procedimento è in Figura 4.

Progetto 1: Visualizzare i pixel ai 4 angoli del display

Le coordinate del display OLED sono reperibili in Figura 5. L'angolo superiore sinistro è (0,0). La coordinata X attraversa lo schermo da 0 a 127, mentre la Y passa da 0 a 31.

Listato del programma: nel box Listato 1 viene illustrato il programma OLEDCorners.py. Questo programma è incluso nel file di archivio del software del libro [1] sotto Downloads.

Listing 1: OLEDCorners.py.
#------------------------------------------------------------------
# SHOW THE PIXELS AT CORNERS OF THE DISPLAY
# =========================================
#
# This program shows the pixels at the four corners of the display
#
# Author: Dogan Ibrahim
# File : OLEDCorners.py
# Date : November 2020
#------------------------------------------------------------------
from board import SCL, SDA
import busio
import adafruit_ssd1306 

i2c = busio.I2C(SCL, SDA)
display = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c) 

display.fill(0) # Clear pixels
display.show() # Display data 

display.pixel(0,0,1) # Pixel at (0,0)
display.pixel(127,0,1) # Pixel at (127,0)
display.pixel(0,31,1) # Pixel at (0,31)
display.pixel(127, 31, 1) # Pixel at (127,31)
display.show() # Display the data

 

Listing 2: OLEDText.py.
#----------------------------------------------------------
# DISPLAY TEXT
# ============
#
# This program displays the text E L E K T O R at (15,5)
#
# Author: Dogan Ibrahim
# File : OLEDText.py
# Date : November 2020
#----------------------------------------------------------
from PIL import Image,ImageDraw,ImageFont
from board import SCL, SDA
import busio
import adafruit_ssd1306 

i2c = busio.I2C(SCL, SDA)
display = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c)
font = ImageFont.load_default() # Default font 

display.fill(0) # Clear display
display.show() 

width = display.width # Width
height = display.height # Height
image = Image.new('1',(width,height))
draw = ImageDraw.Draw(image)
draw.text((15, 5), "E L E K T O R", font = font, fill = 255)
display.image(image)
display.show()

All'inizio del programma, la libreria OLED Adafruit viene importata nel programma. I pixel vengono poi cancellati dalla funzione display.fill(0). È  consigliato cancellare sempre i pixel all'avvio del programma. I pixel ai 4 angoli dello schermo vengono poi accesi. Per visualizzare i dati sul display è necessario chiamare la funzione display.show().

In Figura 6 è rappresentato il display con i pixel accesi ai 4 angoli.

Progetto 2: visualizzare il testo

In questo progetto, il testo "ELEKTOR" viene visualizzato cominciando dalle coordinate del display (15,5).

Listato del programma: il Listato 2 mostra il programma OLEDText.py. Questo usa le funzioni della libreria PIL [2].

All'avvio del programma, i moduli immagine e font della libreria PIL vengono importati nel programma. Di default viene poi caricato automaticamente il font appartenente alla libreria. Dopodiché il programma cancella i pixel. Il width e height memorizzano la larghezza (128) e l'altezza (32) del display.

Per creare un'immagine, innanzitutto bisogna creare un'immagine vuota delle dimensioni dello schermo. Ciò si realizza con il seguente enunciato:

image = Image.new('1', (width, height))

Con questo oggetto immagine viene creato l'oggetto disegno, il quale viene usato per creare forme e testo:

draw = ImageDraw.Draw(image)

In questo programma vogliamo visualizzare il testo sulle coordinate (15,5) e dunque viene utilizzata la funzione draw.text:

draw.text((15, 5), "E L E K T O R", font = font, fill = 255)

Nota bene: fill = 255 disegna l'immagine in bianco, mentre = 0 rende l'immagine in nero. Dopodiché dobbiamo visualizzare l'immagine chiamando le funzioni display.image(image) e display.show(). In Figura 7 è presente la rappresentazione del testo visualizzato.

Progetto 3: visualizzare le forme

Possiamo creare diversi tipi di forme sul display. Per la lista completa delle funzioni, potete fare riferimento alla libreria PIL presente nella documentazione (ci sono molte altre funzioni oltre a quelle brevemente descritte qui).

Rettangolo:
(x,y) corrispondono all'angolo superiore sinistro del rettangolo. Outline corrisponde al colore della linea di contorno della forma (255 per bianco, 0 per nero), fill corrisponde al colore di riempimento della forma (255 per bianco, 0 per nero).

draw.rectangle((x, y, width, height), outline = nn, fill = mm)

Ellisse:

draw.ellipse((x, y, width, height), outline = nn, fill = mm)

Linea:

(x,y) corrispondono alla prima coordinata; (x2, y2) corrispondono alla seconda coordinata

draw.line((x1, y1, x2, y2), fill = mm)

Arco:

draw.arc((x1,x2,y1,y2), s1, s2, fill = mm)

Disegnate un arco tra l'inizio (s1) e la fine degli angoli (s2) all'interno del box (x1, x2, y1, y2).

Corda:

draw.chord((x1,x2,y1,y2), s1, s2, fill = mm)

Disegnate una linea tra inizio (s1) e fine degli angoli (s2) all'interno del box (x1, x2, y1, y2).

Fetta di torta:

draw.pieslice((x1,y1,x2,y2), s1, s2, fill = mm)

Uguale all'arco ma prevede anche delle linee rette che vanno dal punto finale al centro del perimetro di selezione.

Punto:

draw.point((x1,x2), fill = mm)

Disegnate dei pixel sulle date coordinate. Può essere disegnato più di un pixel, come mostrato qui sotto, dove 3 pixel individuali vengono disegnati sulle seguenti coordinate:

draw.point([(x1,y1), (x2,y2), (x3,y3)], fill = mm)

Poligono:

draw.polygon([(x1,y1), (x2,y2), (x3,y3), ......], outline = nn, fill = mm)

Disegnate un poligono, in cui le linee di contorno consistono in linee rette tra le date coordinate, in più una linea retta tra la prima e l'ultima coordinata. La lista delle coordinate può comporsi di qualsiasi sequenza di oggetti contenenti due tuple [(x,y), ...] oppure due valori numerici [x,y, ...]. Dovrebbe contenere almeno tre coordinate. Il programma OLEDRect.py mostrato nel Listato 3 illustra il disegno di un rettangolo agli angoli del display con all'interno il testo "RECTANGLE", visualizzabile in Figura 8.

Listing 3: LEDRect.py.
#--------------------------------------------------------------
#
# DISPLAY A RECTANGLE WITH TEXT INSIDE
# ====================================
#
# In this progra a rectangle is displayed at the corners of the
# display and text R E C T A N G L E is displayed inside
#
# Author: Dogan Ibrahim
# File : OLEDRect.py
# Date : November.py
#---------------------------------------------------------------
from PIL import Image,ImageDraw,ImageFont
from board import SCL, SDA
import busio
import adafruit_ssd1306 

i2c = busio.I2C(SCL, SDA)
display = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c)
font = ImageFont.load_default() 

display.fill(0)
display.show() 

width=(display.width)
height=(display.height)
image=Image.new('1',(width,height))
draw=ImageDraw.Draw(image)
draw.rectangle((0,0, 127, 31),outline = 255, fill = 0)
draw.text((15, 12),"R E C T A N G L E", font = font, fill = 255)
display.image(image)
display.show()

Il programma OLEDShape1.py rappresentato nel Listato 4 visualizza 4 rettangoli. All'interno del rettangolo 1 viene visualizzato il numero 1, all'interno del rettangolo 2 viene visualizzato il numero 2 e così via, come mostrato in Figura 9.

Listing 4: OLEDShape1.py.
#--------------------------------------------------------------
#
# DISPLAY 4 RECTANGLES WITH NUMBERS 1,2,3,4
# =========================================
#
# In this progra 4 rectangles are displayed. Number 1 is displayed
# inside rectangle 1, number 2 inside rectangle 2, and so on
#
# Author: Dogan Ibrahim
# File : OLEDShape1.py
# Date : November 2020
#---------------------------------------------------------------
from PIL import Image,ImageDraw,ImageFont
from board import SCL, SDA
import busio
import adafruit_ssd1306 

i2c = busio.I2C(SCL, SDA)
display = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c)
font = ImageFont.load_default() 

display.fill(0)
display.show() 

width=(display.width)
height=(display.height)
image=Image.new('1',(width,height))
draw=ImageDraw.Draw(image)
draw.rectangle((0,0, 127, 31),outline = 255, fill = 0)
draw.line((64, 0, 64, 31), fill = 255)
draw.line((0, 16, 127, 16), fill = 255)
draw.text((32, 4), "1", font = font, fill = 255)
draw.text((94, 4), "2", font = font, fill = 255)
draw.text((32, 17),"3", font = font, fill = 255)
draw.text((94, 17),"4", font = font, fill = 255)
display.image(image)
display.show()

Il programma OLEDShape2.py rappresentato nel Listato 5 visualizza una corda e un poligono a 4 angoli. Il parametro di riempimento del poligono (fill) è settato su 255, ottenendo così un riempimento bianco. Il risultato è visibile in Figura 10.

Listing 5: LEDShape2.py.
#--------------------------------------------------------------
#
# DISPLAY A CHORD AND A POLYGON
# =============================
#
# In this program a chord and a polygon are drawn. The polygon is
# filled with white
#
# Author: Dogan Ibrahim
# File : OLEDShape2.py
# Date : November 2020
#---------------------------------------------------------------
from PIL import Image,ImageDraw,ImageFont
from board import SCL, SDA
import busio
import adafruit_ssd1306 

i2c = busio.I2C(SCL, SDA)
display = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c)
font = ImageFont.load_default() 

display.fill(0)
display.show() 

width=(display.width)
height=(display.height)
image=Image.new('1',(width,height))
draw=ImageDraw.Draw(image)
draw.chord((0, 0, 90, 30), 10, 180, fill = 255)
draw.polygon([(100,5), (120,9), (120,25), 
(100,30)],outline=255,fill=255)
display.image(image)
display.show()

Progetto 4: creare e visualizzare una Bitmap

In questa sezione creeremo un'immagine bitmap 128 x 32 e poi la visualizzeremo sul display. L'immagine che andremo a creare consiste nella lettera A maiuscola. Gli step sono i seguenti:

Creazione dell'immagine: useremo il programma Microsoft Paint per creare la nostra immagine.

Avviare il programma MS Paint.

  • Cliccate Home Resize e poi Pixels. Settare pixel orizzontali a 128 e i verticali a 64, come mostrato in Figura 11. Cliccare OK
  • Cliccate View e poi Zoom In per ingrandire la griglia
  • Disegnate la forma che volete con il mouse. In questo progetto si tratta di scrivere in maiuscolo la lettera A, come mostrato in Figura 12
  • Salvare il file, per es. LetterA.png
  • Copiare il file nella home directory (/home/pi) su Raspberry Pi. Per copiare il file potete usare il programma WinSCP, reperibile gratuitamente.

Il programma finale, OLEDBitmap.py, è reperibile nel Listato 6. La funzione Image.open viene utilizzata per aprire il file d'immagine, che risulta ridimensionato e convertito in colore a 1-bit come richiesto dalla libreria. In Figura 13 la rappresentazione del display.

Listing 6: OLEDBitmap.py.
-------------------------------------------------------
#
# DISPLAY BITMAP
# ==============
#
# This progra displays a bitmap image
#
# Author: Dogan Ibrahim
# File : OLEDBitmap.py
# Date : November 2020
#-----------------------------------------------------
from PIL import Image,ImageDraw,ImageFont
from board import SCL, SDA
import busio
import adafruit_ssd1306 

i2c = busio.I2C(SCL, SDA)
display = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c) 

display.fill(0)
display.show() 

width=(display.width)
height=(display.height)
image=Image.new('1',(width,height))
image=Image.open('LetterA.png').resize((width,height),\
Image.ANTIALIAS).convert('1')
display.image(image)
display.show()

Tutti i programmi trattati in questo articolo sono disponibili sulla pagina web di Elektor dedicata a questo libro [1]. In pagina fate scroll down fino alla sezione Downloads dove troverete i pacchetti cumulativi. Scaricate il file .zip, estraetelo sul vostro computer e poi avviate i 6 programmi Python di cui ci siamo occupati in questo articolo.

Nota dell'Editore

Questo articolo è un estratto del libro "Using Displays in Raspberry Pi Projects", formattato e adattato agli standard editoriali e al layout di Elektor Magazine. Trattandosi dell'estratto di una pubblicazione più estesa, alcuni termini potrebbero riferirsi a discussioni appartenenti ad altre parti del testo originale. Autore ed Editore hanno fatto del loro meglio per scongiurare questa evenienza e saranno felici di rispondere ai vostri quesiti. Dettagli di contatto nel box Domande e Commenti.

Riferimenti

[1] Cumulative programs download: www.elektor.com/using-displays-in-raspberry-pi-projects
[2] PIL Library: http://effbot.org/imagingbook/imagedraw.htm

Prodotti correlati

> Book: D. Ibrahim, Using Displays in Raspberry Pi Projects (Elektor 2021)
www.elektor.com/using-displays-in-raspberry-pi-projects
> E-Book: D. Ibrahim, Using Displays in Raspberry Pi Projects (Elektor 2021)
www.elektor.com/using-displays-in-raspberry-pi-projects-e-book

Domande o Commenti?

Avete domande o commenti relativi a questo articolo? Inviate un'email all'autore all'indirizzo d.ibrahim@btinternet.com o ad Elektor all'indirizzo editor@elektor.com.

Contributori

Text: Dogan Ibrahim
Editor: Jan Buiting
Layout: Giel Dols

WEB LINK

ARTICOLO ORIGINALE IN INGLESE AL LINK: Using Displays in Raspberry Pi Projects | Elektor Magazine

Scarica subito una copia gratis

Scrivi un commento

Seguici anche sul tuo Social Network preferito!

Send this to a friend