Cet article a été mis à jour le 13 mai 2021 (ajout d'un deuxième sketch).
Dans cet article, nous branchons à un ESP8266 un écran tactile TFT de 240 X 320 pixels (2,4"), muni d'un contrôleur ILI9341, qui communique sur le bus SPI.
- 2 broches pour l'alimentation
- 7 broches pour l'affichage
- 5 broches pour le capteur tactile
- 4 broches pour le lecteur de carte SD (que je n'utilise pas dans cet article)
J'ai branché l'écran à l'ESP8266 de cette façon:
- Broche VCC de l'écran - Sortie 3,3 V de l'ESP8266
- Broche GND de l'écran - Broche GND de l'ESP8266
- Broche CS de l'écran - Broche GPIO 15 (D8) de l'ESP8266
- Broche RESET de l'écran - Broche GPIO 2 (D4) de l'ESP8266
- Broche DC/RS de l'écran - Broche GPIO 0 (D3) de l'ESP8266
- Broche SDI (MOSI) de l'écran - Broche GPIO 13 (D7) de l'ESP8266
- Broche SCK de l'écran - Broche GPIO 14 (D5) de l'ESP8266
- Broche LED de l'écran - Sortie 3,3 V de l'ESP8266
- Broche SDO (MISO) de l'écran - Broche GPIO 12 (D6) de l'ESP8266
- Broche T_CLK de l'écran - Broche GPIO 14 (D5) de l'ESP8266
- Broche T_CS de l'écran - Broche GPIO 4 (D2) de l'ESP8266
- Broche T_DIN de l'écran - Broche GPIO 13 (D7) de l'ESP8266
- Broche T_DO de l'écran - Broche GPIO 12 (D6) de l'ESP8266
- Broche T_IRQ de l'écran - pas connectée
Installation de la bibliothèque
J'ai installé la bibliothèque TFT_eSPI de Bodmer par l'entremise du gestionnaire de bibliothèques de l'IDE Arduino.
Configuration de la bibliothèque (fichiers User_Setup)
Avant d'utiliser la bibliothèque TFT_eSPI, il est important de la configurer en fonction du type d'écran que nous utilisons. Pour ce faire, vous devez ouvrir le répertoire où la bibliothèque TFT_eSPI a été installée (dans le dossier "libraries" de votre sketchbook Arduino).
Deux possibilités s'offrent à vous:
- Apporter les modifications nécessaires dans le fichier User_Setup.h
- Sélectionner un fichier User_Setup prédéfini
C'est cette deuxième option que j'ai utilisé: j'ai d'abord ouvert le fichier "User_Setup_Select.h" et j'y ai décommenté la ligne 24: "#include <User_Setups/Setup1_ILI9341.h>". De cette façon, la bibliothèque utilisera les informations consignées dans le fichier "Setup1_ILI9341.h"
La bibliothèque TFT_eSPI est maintenant configurée pour l'utilisation de notre écran avec un ESP8266. Si, à une autre occasion, vous désirez utiliser un autre microcontrôleur ou un autre écran, il s'agira de sélectionner un autre fichier User_Setup.
Exemple de sketch: deux boutons
La bibliothèque TFT_eSPI comporte un grand nombre d'exemples très instructifs.
Je vous propose ci-dessous un sketch très simple qui permet d'explorer l'affichage de texte et de formes géométriques simples, ainsi que la gestion de boutons virtuels à l'écran.
Deux boutons s'affichent au bas de l'écran: un bouton qu'on touche pour faire apparaître un rectangle, et un autre qui permet d'afficher un cercle.
L'exemple Keypad_240X320 (fourni avec la bibliothèque) montre comment conserver les données de calibration de l'écran dans un fichier SPIFF pour qu'il ne soit pas nécessaire de répéter cette calibration à chaque utilisation (je n'ai pas inclus cette fonctionnalité dans mon sketch).
-
/* | |
Démonstration d'écran tactile à deux "boutons" | |
TFT SPI 2.4" 320 X 240 pixels | |
Plus d'infos: | |
https://electroniqueamateur.blogspot.com/2021/04/utilisation-dun-ecran-tactile-tft-spi.html | |
*/ | |
#include <SPI.h> | |
#include <TFT_eSPI.h> | |
TFT_eSPI tft = TFT_eSPI(); // https://github.com/Bodmer/TFT_eSPI | |
// Création de 2 objets boutons | |
#define NOMBRE_BOUTONS 2 | |
TFT_eSPI_Button bouton[NOMBRE_BOUTONS]; | |
void setup() { | |
tft.init(); | |
tft.setRotation(3); // portrait: 0 ou 2, paysage: 1 ou 3. | |
touch_calibrate(); // procédure de calibration de l'écran tactile | |
// affichage d'un message à l'écran: | |
tft.fillScreen(TFT_BLACK); // on efface tout (fond noir) | |
tft.setFreeFont(&FreeSansOblique12pt7b); // police de caractère | |
tft.setCursor(20, 70); // position du début du message | |
tft.setTextSize(1); | |
tft.setTextColor(TFT_WHITE, TFT_BLACK); | |
tft.println("Choisissez la forme desiree"); | |
// création de deux boutons | |
// premier bouton: son centre est positionné à x = 80 et y = 200, largeur 120, | |
// hauteur 50, contour en noir, remplissage rouge, texte en blanc, taille de texte 1. | |
bouton[0].initButton(&tft, 80, 200, 120, 50, TFT_BLACK, TFT_RED, TFT_WHITE, "rectangle", 1); | |
bouton[0].drawButton(); | |
// deuxième bouton: son centre est positionné à x = 250 et y = 200, largeur 120, | |
// hauteur 50, contour en noir, remplissage vert, texte en noir, taille de texte 1. | |
bouton[1].initButton(&tft, 250, 200, 120, 50, TFT_BLACK, TFT_GREEN, TFT_BLACK, "cercle", 1); | |
bouton[1].drawButton(); | |
} | |
//------------------------------------------------------------------------------------------ | |
void loop(void) { | |
uint16_t t_x = 0, t_y = 0; // coordonnées touchées par l'utilisateur | |
boolean pressed = tft.getTouch(&t_x, &t_y); // vrai si contact avec l'écran | |
// On vérifie si la position du contact correspond à celle d'un bouton | |
for (uint8_t numero = 0; numero < NOMBRE_BOUTONS; numero++) { | |
if (pressed && bouton[numero].contains(t_x, t_y)) { | |
bouton[numero].press(true); | |
} else { | |
bouton[numero].press(false); | |
} | |
} | |
// Vérifions maintenant si l'état d'un des boutons a changé | |
for (uint8_t numero = 0; numero < NOMBRE_BOUTONS; numero++) { | |
// si le bouton vient d'être relâché, on le redessine avec sa forme normale | |
if (bouton[numero].justReleased()) { | |
bouton[numero].drawButton(); | |
} | |
// si le bouton vient d'être pressé... | |
if (bouton[numero].justPressed()) { | |
bouton[numero].drawButton(true); // on le redessine avec les couleurs inversées | |
// ...puis on fait ce que l'utilisateur a demandé: | |
switch (numero) { | |
case 0: // premier bouton | |
tft.fillRect(0, 0, 320, 160, TFT_BLACK); // pour effacer le dessin précédent | |
tft.fillRect(60, 30, 200, 100, TFT_CYAN); // rectangle 200 de largeur et 100 de hauteur | |
break; | |
case 1: // deuxième bouton | |
tft.fillRect(0, 0, 320, 160, TFT_BLACK); // pour effacer le dessin précédent | |
tft.fillCircle(160, 80, 50, TFT_YELLOW); // cercle centré à x = 160 et y = 80 | |
break; | |
} | |
delay(10); // anti-rebond | |
} | |
} | |
} | |
// procédure de calibration de l'écran tactile | |
void touch_calibrate() | |
{ | |
uint16_t calData[5]; | |
uint8_t calDataOK = 0; | |
tft.fillScreen(TFT_BLACK); | |
tft.setCursor(25, 70); | |
tft.setTextFont(2); | |
tft.setTextSize(2); | |
tft.setTextColor(TFT_WHITE, TFT_BLACK); | |
tft.println("Touchez l'ecran a "); | |
tft.setCursor(15, 110); | |
tft.println("chaque coin indique."); | |
tft.setTextFont(1); | |
tft.println(); | |
tft.calibrateTouch(calData, TFT_YELLOW, TFT_BLACK, 20); | |
tft.setTextColor(TFT_GREEN, TFT_BLACK); | |
tft.println("Calibration terminee!"); | |
} |
-
Exemple de sketch: un bouton coulissant
J'ai écrit ce deuxième sketch pour qu'il soit utilisé avec une carte STM32, mais il fonctionne à la perfection sur un ESP8266, sans la moindre modification, puisque les informations propres au microcontrôleur se trouvent dans le fichier User_Setup.
Il s'agit cette fois d'un bouton coulissant qui pourrait servir à contrôler la luminosité d'une LED, la positon d'un servomoteur, etc.
-
/*************************************************************************** | |
Bouton coulissant sur un écran tactile TFT SPI 2.4" 320 X 240 pixels | |
Pour plus d'infos: | |
https://electroniqueamateur.blogspot.com/2021/04/utilisation-dun-ecran-tactile-tft-spi_25.html | |
******************************************************************************/ | |
#include <SPI.h> | |
#include <TFT_eSPI.h> | |
TFT_eSPI tft = TFT_eSPI(); // https://github.com/Bodmer/TFT_eSPI | |
#define VALEUR_MAX 100 // valeur affichée quand le bouton est poussé à l'extrême droite | |
#define LARGEUR 20 // largeur du bouton | |
#define HAUTEUR 40 // hauteur du bouton | |
#define POSY 150 // position verticale du bouton coulissant | |
#define LIMITE_GAUCHE 30 // extrémité gauche au 20e pixel | |
#define LIMITE_DROITE 290 // extrémité droite au 100e pixel | |
uint16_t x_precedent = 160 ; // position horizontale précédemment touchée (160 est le centre de l'écran) | |
// routine qui redessine le contenu de l'écran | |
void dessineContenu(uint16_t posx) { | |
uint16_t postxt; | |
// on ne permet pas que le bouton dépasse les limites établies | |
if (posx < LIMITE_GAUCHE) { | |
posx = LIMITE_GAUCHE; | |
} | |
if (posx > LIMITE_DROITE) { | |
posx = LIMITE_DROITE; | |
} | |
// on efface le bouton, là où il se trouvait précédemment | |
tft.fillRect(x_precedent - LARGEUR / 2, POSY - HAUTEUR / 2 - 2 , LARGEUR, HAUTEUR + 4, TFT_BLACK); | |
// on dessine la ligne horizontale | |
tft.drawLine(LIMITE_GAUCHE, POSY, LIMITE_DROITE, POSY, TFT_WHITE); | |
// on dessine le bouton à sa nouvelle position | |
tft.fillRect(posx - LARGEUR / 2, POSY - HAUTEUR / 2, LARGEUR, HAUTEUR, TFT_YELLOW); | |
// on efface l'ancienne valeur numérique | |
postxt = 90; | |
tft.setTextColor(TFT_BLACK); | |
postxt += tft.drawFloat(calcule_valeur(x_precedent), 1, postxt, 50, 4); | |
// on écrit la nouvelle valeur numérique | |
postxt = 90; | |
tft.setTextColor(TFT_GREEN); | |
postxt += tft.drawFloat(calcule_valeur(posx), 1, postxt, 50, 4); | |
x_precedent = posx; | |
} | |
// routine qui calcule la valeur numérique qui correspond à la position du bouton coulissant | |
float calcule_valeur (uint16_t valeur_brute) { | |
float valeur_convertie; | |
valeur_convertie = 1.0 * (valeur_brute - LIMITE_GAUCHE) / ( LIMITE_DROITE - LIMITE_GAUCHE) * VALEUR_MAX; | |
return valeur_convertie; | |
} | |
void setup() { | |
tft.init(); | |
tft.setRotation(3); // portrait: 0 ou 2, paysage: 1 ou 3. | |
touch_calibrate(); // procédure de calibration de l'écran tactile | |
tft.fillScreen(TFT_BLACK); // on efface tout (fond noir) | |
dessineContenu(160); | |
} | |
void loop(void) { | |
uint16_t t_x = 0, t_y = 0; // coordonnées touchées par l'utilisateur | |
boolean pressed = tft.getTouch(&t_x, &t_y); // vrai si contact avec l'écran | |
if (pressed) { // si on touche l'écran | |
if (t_x != x_precedent) { // si on a changé de position | |
dessineContenu(t_x); | |
} | |
} | |
} | |
// procédure de calibration de l'écran tactile | |
void touch_calibrate() | |
{ | |
uint16_t calData[5]; | |
uint8_t calDataOK = 0; | |
tft.fillScreen(TFT_BLACK); | |
tft.setCursor(25, 70); | |
tft.setTextFont(2); | |
tft.setTextSize(2); | |
tft.setTextColor(TFT_WHITE, TFT_BLACK); | |
tft.println("Touchez l'ecran a "); | |
tft.setCursor(15, 110); | |
tft.println("chaque coin indique."); | |
tft.setTextFont(1); | |
tft.println(); | |
tft.calibrateTouch(calData, TFT_YELLOW, TFT_BLACK, 20); | |
tft.setTextColor(TFT_GREEN, TFT_BLACK); | |
tft.println("Calibration terminee!"); | |
} |
-
À lire également
Le même écran tactile, utilisé avec une carte STM32 Blue Pill.
D'autres afficheurs utilisés avec l'ESP8266:
- Écran couleur SPI ST7735
- Écran OLED I2C SH1106
- Écran Nokia 5110
- Afficheur LCD 16 X 2
- Afficheur numérique à base de TM1638
Yves Pelletier (Twitter, Facebook)
Ce commentaire a été supprimé par l'auteur.
RépondreSupprimerBonjour,
RépondreSupprimerEn dehors du touchscrenn tout fonctionne bien !
Auriez vous la solution ?
Merci pour vos réponses.
L'Arsène.