Arduino - Display TFT LCD Sommario Hardware

Arduino - Display TFT LCD
Un display TFT LCD è una variante dei display a cristalli liquidi (LCD) che utilizza la tecnologia dei
Thin-Film Transistor (TFT) e, a differenza di altri LCD a matrice passiva, si avvale di uno schermo a
matrice attiva nel quale ogni singolo pixel è collegato a un transistor e ad un condensatore che ne
mantengono attivamente lo stato. Questo tipo di gestione, aumentando il numero di pixel che lo
schermo è in grado di supportare anche il contrasto, rende possible migliorare alcune delle
caratteristiche delle immagini visualizzate.
Sommario
In questo articolo descriveremo la scheda (shield) di uno schermo TFT LCD da 2,8 pollici (7,1 cm) per
Arduino che, in una prima fase, valuteremo confrontandone le caratteristiche tecniche (le prime
riportate di seguito sono quelle del modello di TFT usato come campione) con quelle dei principali
modelli in commercio. Successivamente descriveremo nel dettaglio il codice necessario al
funzionamento ed all'utilizzo dello shield, proponendo alcune prime semplici applicazioni.
Hardware
Nella tabella seguente sono visibili le caratteristiche tecniche di alcune versioni dei modelli di shield
TFT reperibili presso vari rivenditori, ed il link della documentazione disponibile presso i siti dei
produttori e/o rivenditori. Da una semplice comparazione tra i vari modelli è possibile descrivere gli
shield esaminati come sistemi Arduino / Arduino Mega compatibili con display TFT Touch da 2,8"
multicolre e con un touch-screen resistivo a 4-conduttori. L'integrazione con i sistemi Arduino è resa
possibile da connettori sottostanti alla base di supporto del display compatibili con quelli presenti sulla
scheda del microcontrollore. Alcune differenze che è possibile evidenziare, sono relative all'integrato
utilizzato per il pilotaggio del display, al tipo di interfaccia ed al chip di controllo del display
impiegato. Le interfacce utilizzate sono l'SPI, la parallela con trasferimento ad 8 bit per i dati e 4 bit per
i controlli. Un caso particolare è quello del modulo ITDB02-2.8, un TFT LCD da 2.8" con 65K colori e
una risoluzione di 320 x 240, che utilizza l'integrato ILI9325DS per il controllo dell'LCD, e che espone
inoltre, nella parte sottostante del modulo, anche un socket per SD card. Infine si evidenzia che per il
funzionamento di questo display è possibile utilizzare le librarie software UTFT.
2.8" Touch LCD Touch Shield [LinkSprite]
Caratteristiche
Alimentazione
Assorbimento
Dimensioni LCD
Angolo di visione
Risoluzione
Valore
4.5
250
2.8
60~120
320x240
Unità
Volt
mA
Pollici
Gradi
Pixel
2.8'' TFT LCD Touch Shield V1.0 [SeeedStudio]
Caratteristiche
Alimentazione
Assorbimento
Dimensioni LCD
Angolo di visione
Risoluzione
Colori LCD
Valore
4.5
250
2.8
60~120
320x240
65k
Unità
Volt
mA
Pollici
Gradi
Pixel
Colori LCD
Retroilluminazione
LCD driver IC
Interfaccia
65k
LED
ILI9341
SPI
4-Wire resistive
Touch Screen
touch screen
Area Attiva
43.2*57.3
ESD contact discharge
±4
ESD air discharge
±8
Dimensioni
72.5x54.7x18
Peso
24±2
Retroilluminazione
LCD driver IC
mm
KV
KV
mm
g
2.8" TFT LCD Touch Shield [ITDB02-2.8 -]
Caratteristiche
Alimentazione
Assorbimento
Dimensioni LCD
Angolo di visione
Risoluzione
Colori LCD
Retroilluminazione
LCD driver IC
Interfaccia
Touch Screen
Area Attiva
Espansione
Espansione
Dimensioni
Peso
Valore
Unità
3,3 - 5
Volt
250
mA
2.8“
Pollici
60~120
Gradi
320 * 240
Pixel
262k
LED
ILI9325DS
Parallela (8 bit Dati +
4 bit CTRL)
4-Wire resistive
touch screen
43.2*57.3
mm
SD Card Socket
Supporto Librerie
UTFT
56x54 (no impilabile) mm
60±2
g
LED
ST7781R
Parallela (8bit Dati
Interfaccia
+ 4bit CTRL)
4-Wire resistive
Touch Screen
touch screen
Area Attiva
43.2*57.3
ESD contact discharge
±4
ESD air discharge
±8
Dimensioni
72.5x54.7x18
Peso
24±2
mm
KV
KV
mm
g
2.8'' TFT LCD Touch Shield V2.0 [SeeedStudio]
Caratteristiche
Alimentazione
Assorbimento
Dimensioni LCD
Angolo di visione
Risoluzione
Colori LCD
Retroilluminazione
LCD driver IC
Interfaccia
Touch Screen
Area Attiva
ESD contact discharge
ESD air discharge
Dimensioni
Peso
Valore
5
250
2.8"
60~120
320x240
65k
LED
ILI9341
SPI
4-Wire resistive
touch screen
43.2*57.3
±4
±8
72.5x54.7x18
24±2
Unità
Volt
mA
Pollici
Gradi
Pixel
mm
KV
KV
mm
g
L’installazione dell'hardware è facile: basta collegare lo shield TFT al vostro Arduino e, a seconda del
modello di display LCD touch screen, potremmo optare per la realizzazione di un sistema integrato di
visualizzazione che consenta una gestione semplifcata, oppure scegliere uno shield che non utilizzi per
il suo funzionamento molti dei pin di I/O digitali messi a disposizione dal microcontrollore (ad esempio
gli shield che hanno on-board il soket per SD card avranno evidentemente meno linee di I/O disponibili
per l'utente). In questo documento faremo comunque riferimento allo shield per touch screen TFT a
colori da 2,8 pollici commercializzato da Linksprite e del quale riportiamo due viste nelle foto
successive.
Vista Superiore
Vista capovolt
Come potete vedere, lo shield è in grado di coprire completamente un Arduino Uno (o altra scheda
compatibile) e offre una semplice soluzione per ottenere, come interfaccia utente, un ampio display. Lo
schermo ha una risoluzione di 320 x 240 pixel, supporta fino a 65536 colori assorbendo circa 250 mA
di corrente dall’alimentazione interna dei 5V di Arduino. A differenza di altri LCD a colori questo
modello, non occuperà tutti i pin di I/O digitali: utilizza infatti il bus SPI per il controllo del display
(pin D10 - D13), più quattro pin analogici (A0 - A3) se si vuole utilizzare anche il sensore a
sfioramento. Oltre a queste opzioni, nel caso si voglia utilizzare anche il connettore onboard per le
micro SD Card, sarà necessario considerare l'impiego di altri pin. La versatilità di questo shield
consentirà, con un pò di fantasia, con l’esperienza acquisita nell'utilizzo di Arduino e con la
spiegazione che troverete nel seguito, di creare in poco tempo ogni tipo di schermo di interfaccia.
Librerie & Software
1) Installazione
La prima operazione da fare è quella dell'installazione della libreria di supporto software per il pieno
utilizzo dello shield LCD. Acquisiamo i file necessari direttamente dal sito del produttore Linksprite e,
una volta eseguito il download del file compresso, lo scompattiamo all'interno di una specifica cartella
"TFT_Touch_library" nella directory in cui si trova il file compresso scaricato. In questa cartella
troverete due cartelle "TFT_Touch” e “TouchScreen" che dovranno essere copiate nella directory di
installazione dell'IDE di Arduino, ovvero in ...\Arduino-1.0.x \libraries. Conclusa la copia delle cartelle
sarà necessario rinominare la directory "TFT" presente nella cartella ...\Arduino-1.0.x \libraries in
"TFT_OLD" e rinominare la directory "TFT_Touch" copiata in precedenza come "TFT". Conclusa
questa serie di operazioni testiamo lo shield, per verificare che funzioni, cercando di ottenere qualche
primo risultato. Avviate dunque l'editor grafico di Arduino (IDE) e caricate l'esempio paint dalla
omonima directory presente nella cartella “examples” inclusa nella libreria TFT precedentemente
rinominata. A questo punto, con uno stilo o con uno strumento a una punta arrotondata, possiamo
selezionare il colore da utilizzare dalla tavolozza dei colori riportata di fianco e cominciare a disegnare
a mano libera direttamente sul display, così come mostrato nel video successivo.
Lo schermo non è provvisto di pellicola protettiva: è quindi importante fare sempre attenzione al tipo di
strumento utilizzato per disegnare, che deve essere sempre a punta arrotondata e liscia. Di seguito una
immagine campione di quanto è possibile disegnare utilizzando lo shield TFT.
2) Utilizzo del display LCD
Per poter usufruire delle funzioni caratteristiche di questo particolare tipo di display LCD è necessario
esaminare il codice che bisogna aggiungere ai vari sketch di arduino.
Per includere le librerie utili a tal fine, si ricorre all'ausilio di poche semplici linee di codice che
andranno inserite prima della routine di void setup () e che riportiamo di seguito:
1 #include <stdint.h>
2 #include <TFTv2.h>
3 #include <SPI.h>
A questo punto, una volta incluse ed inizializzate le librerie, è possibile analizzare le funzioni
disponibili per la visualizzazione nel display di testo e di oggetti grafici. Per far questo la libreria TFT
andrà inizializzata inserendo nella routine in void setup () il codice necessario:
1 void setup()
2 {
Tft.TFTinit();
3
// altre inizializzazioni
4
5 }
Prima però è necessario comprendere come definire i colori che dovranno essere impiegati all'interno
di ciascuna delle varie funzioni grafiche disponibili al fine di migliorarne l'utilizzo in differenti contesti
di elaborazione.
3) Definizione dei colori
Le funzioni messe a disposizioni dalle librerie di gestione dell'LCD necessitano, per il loro corretto
funzionamento, di un parametro identificativo del colore da utilizzare che può essere passato alla
funzione in differenti formati.
Ad esempio si può scegliere un colore utilizzando i descrittori definiti per le dieci tinte di base
predefinite - RED, GREEN, BLUE, BLACK, YELLOW, WHITE, CYAN, BRIGHT_RED, GRAY1 e
GRAY2; o in alternativa, creare il proprio valore di colore.
Per questo i colori sono definiti da numeri di 16 bit espressi in notazione esadecimale: 5 bit per il rosso,
6 per il verde e 5 per il blu, tutti concatenati e con i quali si definisce in binario il byte corrispondente
(16bit) al colore, così come riportato di seguito:
MSB > RRRRRGGGGGGRRRRR < LSB
Questo tipo di formato è noto come RGB565 e con il nostro display possono essere rappresentati, in
notazione esadecimale (il byte che definisce il colore è lungo 16 bit), tutti i colori con le relative
sfumature.
Il colore nero – ad esempio – sarà costituito da una sequenza di soli zero, poi convertita in esadecimale;
il bianco da soli uno, ecc. Questo processo di conversione dei valori RGB normali in RGB565 è
solitamente piuttosto complesso, ma è possibile per questo, utilizzare uno dei tanti strumenti di
conversione dei colori disponibili in internet.
4) Visualizzazione del testo
Le funzioni disponibili per la gestione e la visualizzazione di caratteri, stringhe di testo, numeri interi e
variabili in virgola mobile permettono una rappresentazione grafica variegata per questo tipo di dati.
Di seguito riportiamo la sintassi ed alcune spiegazioni generali di utilizzo per questo tipo di funzioni:
1
2
3
4
5
6
7
8
Tft.drawChar(char, x, y, size, colour);
// visualizza singolo carattere
Tft.drawString(string, x, y, size, colour);
// visualizza stringa o arrays di caratteri
Tft.drawNumber(integer, x, y, size, colour);
// visualizza numero intero
Tft.drawFloat(float, x, y, size, colour);
// visualizza numero a virgola mobile
In ciascuna di queste esse, si nota che il primo parametro indica la variabile o i dati da visualizzare; x
ed y rappresentano invece le coordinate del primo carattere mostrato in alto a sinistra; e colour può
essere – come spiegato in precedenza – o il colore predefinito (RED, WHITE, etc), o il valore
esadecimale (0x00, 0xFF, etc) corrispondente a quello che si desidera per le stringhe di testo (ad
esempio, 0xFFE0 è il giallo). Un meccanismo di funzionamento particolare è quello della funzione
drawFloat () che nella sua rappresentazione è limitata alla visualizzazione di due cifre decimali, ma –
se necessario – è possibile aumentarle: per farlo, bisogna chiudere l'IDE Arduino (se è in esecuzione),
aprire il file TFTv2.cpp che si trova nella cartella della libreria TFT, e cercare la riga:
1 INT8U decimal = 2;
quindi modificate il valore riportato con il numero delle cifre decimali che si vogliono visualizzare.
Cambiate il valore della variabile INT8U da 2 a 4 ed eseguite il programma successivo per vedere
come la modifica apportata cambi la modalità di azione di questa funzione nella visualizzazione del
testo dei numeri decimali, così come raffigurato nell'immagine riportata a destra.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
include <stdint.h>
#include <TFTv2.h>
#include <SPI.h>
char ascii = 'a';
char h1[] = "Hello";
char h2[] = "world";
float f1 = 3.12345678;
void setup()
{
Tft.TFTinit();
}
void loop()
{
Tft.drawNumber(12345678, 0, 0, 1, 0xF800);
Tft.drawChar(ascii,0, 20,2, BLUE);
Tft.drawString(h1,0, 50,3,YELLOW);
Tft.drawString(h2,0, 90,4,RED);
Tft.drawFloat(f1, 4, 0, 140, 2, BLUE);
}
5) Funzioni grafiche
Una delle prime esigenze quando si utilizza un display LCD TFT è quella della cancellazione dello
schermo. Questa operazione è demandata ad una specifica funzione che si occupa della sua esecuzione
riempiendo lo schermo con il colore nero e la cui sibtassi riportiamo di seguito:
1 Tft.fillScreen()
Un altro aspetto applicativo di particolare interesse è costituito dalla possibilità di gestire direttamente
la grafica dello schermo. Ci sono funzioni per disegnare singoli pixel, cerchi, cerchi pieni, linee,
rettangoli e rettangoli pieni. Con queste e con un po’ di adeguata programmazione è possibile creare
ogni tipo di immagine e diagramma da visualizzare sull'LCD. Le funzioni grafiche messe a
disposizione dell'utente sono le seguenti:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Tft.setPixel(x, y, COLOUR);
// accende un pixel alle coordinate x,y di colore = COLOUR
Tft.drawLine(x1, y1, x2, y2, COLOUR);
// disegna una linea da x1, y1 a x2, y2 di colore = COLOUR
Tft.drawCircle(x, y, r, COLOUR);
// disegna un cerchio con centr a x, y e raggio r di colore = COLOUR
Tft.fillCircle(x, y, r, COLOUR);
// disegna un cerchio pieno con centro a x, y e raggio radius r
// di colore COLOUR
Tft.drawRectangle(x1, y1, x2, y2 ,COLOUR);
// disegna un rettangolo da x1, y1 (angolo superiore sinistro) a x2, y2
// (angolo inferiore destro) di colore = COLOUR
Tft.Tft.fillRectangle(x1, y1, x2, y2 ,COLOUR);
// disegna un rettangolo pieno da x1, y1 angolo superiore sinistro) a x2, y2
// (angolo inferiore destro) di colore = COLOUR
Il seguente programma dà una dimostrazione del funzionamento delle funzioni sopra elencate:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdint.h>
#include <TFTv2.h>
#include <SPI.h>
int x, y, x1, x2, y1, y2, r;
void setup()
{
randomSeed(analogRead(0));
Tft.TFTinit();
}
void loop()
{
// random pixels
for (int i=0; i<500; i++)
{
y=random(320);
x=random(240);
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
Tft.setPixel(x, y, YELLOW);
delay(5);
}
delay(1000);
Tft.fillScreen(); // clear screen
// random lines
for (int i=0; i<50; i++)
{
y1=random(320);
y2=random(320);
x1=random(240);
x2=random(240);
Tft.drawLine(x1, y1, x2, y2, RED);
delay(10);
}
delay(1000);
Tft.fillScreen(); // clear screen
// random circles
for (int i=0; i<50; i++)
{
y=random(320);
x=random(240);
r=random(50);
Tft.drawCircle(x, y, r, BLUE);
delay(10);
}
delay(1000);
Tft.fillScreen(); // clear screen
// random filled circles
for (int i=0; i<10; i++)
{
y=random(320);
x=random(240);
r=random(50);
Tft.fillCircle(x, y, r, GREEN);
delay(250);
Tft.fillCircle(x, y, r, BLACK);
}
delay(1000);
Tft.fillScreen(); // clear screen
// random rectangles
for (int i=0; i<50; i++)
{
y1=random(320);
y2=random(320);
x1=random(240);
x2=random(240);
Tft.drawRectangle(x1, y1, x2, y2, WHITE);
delay(10);
}
delay(1000);
Tft.fillScreen(); // clear screen
// random filled rectangles
for (int i=0; i<10; i++)
77
78
79
80
81
82
83
84
85
86
87
88 }
{
y1=random(320);
y2=random(320);
x1=random(240);
x2=random(240);
Tft.fillRectangle(x1, y1, x2, y2, RED);
delay(250);
Tft.fillRectangle(x1, y1, x2, y2, BLACK);
}
delay(1000);
Tft.fillScreen(); // clear screen
I risultati conseguiti sono mostrati nel video sottostante.
7. Utilizzare il touch screen
Il touch screen funziona in modo del tutto simile in tutte le versioni di shield documentate in
precedenza, in quanto si tratta di un touch screen di tipo resistivo. Il meccanismo di funzionamento si
basa sulla rapida appplicazione di una tensione su un asse del display, che varia al variare posizione in
cui si esercita la pressione dello stilo utilizzato per il puntamento, se ne misura il valore utilizzando uno
degli ingressi analogici del microcontrollore e si ripete l'identico processo per l'altro asse dell'LCD.
Da un punto di vista software è possibile utilizzare una libreria touch screen dedicata, inclusa nel file
compresso (.zip) della libreria, scaricata per l'inizializzazione di tutto il sistema all'inizio di questo
tutorial. Il software in essa contenuto semplifica notevolmente la gestione del touch screen e possiamo
verificarlo praticamente caricando il programma TouchScreen d’esempio incluso nella libreria. Aprite
il monitor seriale, quindi iniziate a toccare lo schermo. Vi restituirà le coordinate dell’area
corrispondente al pixel che state toccando, insieme con i dati relativi alla pressione - come mostrato in
questo video.
Prendete nota dei valori relativi alla pressione, poiché dovranno essere considerati durante la creazione
di progetti che utilizzano il touch screen. Qualora non venissero presi in considerazione, si potrebbe
riscontrare la rilevazione di numerosi falsi positivi, rischiando perciò di acquisire dati non utilizzabile
nell'ambito del progetto che si vuole realizzare. Il programma precedente fornisce un metodo molto
semplice per determinare quale parte dello schermo viene toccata; si possono quindi creare e sviluppare
programmi che intervengono in funzione dell’area toccata. Nel programma "touch" fornito come
esempio, le coordinate x e y sono state mappate con le variabili p.x e p.y, mentre la pressione è
mappata da p.z. Si consiglia di eseguire sperimentazioni con lo schermo ed il modello di touch screen a
disposizione per determinare quali sono i valori di pressione rilevati. Nel seguente esempio se il valore
di pressione p.z non risulterà maggiore di 300, non si produrrà alcun effetto. Cercheremo quindi di
creare un semplice interruttore sensibile al tocco, con una metà dello schermo per l’ON e l'altra metà
per l’OFF. Di seguito riportiamo il codice di programma necessario:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include
#include
#include
#include
<stdint.h>
<TFTv2.h>
<SPI.h>
<TouchScreen.h>
// determina i pins connessi all'hardware del touch screen
// A0~A3
define YP A2 // deve essere un pin analogico identificato con notazione "An"
#define XM A1 // deve essere un pin analogico identificato con notazione "An"
#define YM 14 // può essere un pin digitale, in questo caso A0
#define XP 17 // può essere un pin digitale, in questo caso A3
#define TS_MINX 116*2
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#define TS_MAXX 890*2
#define TS_MINY 83*2
#define TS_MAXY 913*2
// Per una migliore lettura della pressione, dobbiamo conoscere la resistenza
// tra X+ e X- si può utilizzare un multimetro per leggerla
// Il TFT Touch shield da 2.8" ha una resistenza di 300 ohms tra le X
TouchScreen ts = TouchScreen(XP, YP, XM, YM);
void setup()
{
Serial.begin(9600);
Tft.TFTinit();
Tft.fillScreen(); // clear screen
}
void loop()
{
// punta un oggetto e registra le coordinate x y e z
Point p = ts.getPoint();
p.x = map(p.x, TS_MINX, TS_MAXX, 0, 240);
p.y = map(p.y, TS_MINY, TS_MAXY, 0, 320);
Serial.println(p.y);
if (p.y < 160 && p.z > 300) // metà schermo superiore ?
{
// off
Tft.fillCircle(120, 160, 100, BLACK);
Tft.drawCircle(120, 160, 100, BLUE);
} else if (p.y >= 160 && p.z > 300)
{
// on
Tft.fillCircle(120, 160, 100, BLUE);
}
}
Di fatto abbiamo diviso lo schermo in due parti e definito che ogni tocco utile allo spegnimento debba
avere un valore per Y inferiore a 160; il resto dello schermo corrisponde invece all’area di accensione.
La scelta tra le due opzioni (acceso o spento) è gestita con due istruzioni IF che, utilizzano anche un
AND ( " && " ) per controllare che la pressione esercitata sullo schermo sia superiore a 300 (ricordate,
questo valore può cambiare a seconda dei casi e delle esigenze), consentono di definire come
"effettivo" il tocco rilevato, accendendo o spegnendo conseguentemente l'interruttore virtuale creato.
Di seguito troverete la sezione approfondimenti nella quale sono state riportate indicazioni utili al
completamento di questo tutorial con il quale intanto abbiamo definito le modalità di utilizzo di un
display LCD touch screen con Arduino?".
Non resta che ampliare le conoscenze e gli ambiti applicativi del display LCD per un utilizzo a 360
gradi delle potenzialità insite in questo tipo di hardware e guardare il video riportato di seguito per
vedere i risultati del programma precedentemente illustrato.
Approfondimenti
Da un punto di vista applicativo, questo tipo di LCD, può essere utilizzato ad esempio come periferica
di visualizzazione delle informazioni provenienti da sistemi di rilevamento dati, come sistema grafico
di controllo di utenze elettriche asservite, etc. Un altro possibile utilizzo è quello della visalizzazione di
immagini da una memory card inserita nel soket della SD Card presente on board in questo shield.
L'ampiezza delle informazioni disponibili per questo ed altri aspetti di utilizzo dell'hardware presentato
e valutato, ci orienta verso la consultazione di specifiche guide operative. Nel caso si volesse utilizzare
il lettore di memory card, può essere interessante lo studio di questo programma demo; esso include
infatti alcuni file di immagini d’esempio che possono essere utilizzate come campione per questo tipo
di applicazione. Ulteriori interessanti approfondimenti sono anche quelli associati all'utilizzo del touch
screen per i quali si rimanda alla consultazione dei materiali informativi disponibili in rete.
Links
http://homotix.it/catalogo/arduino-shield/touch-lcd-shield-for-arduino
http://linksprite.com/wiki/index.php5?title=Touch_LCD_Shield
http://www.seeedstudio.com/wiki/2.8''_TFT_Touch_Shield_V1.0
https://www.youtube.com/user/tronixstuff/videos