mercredi 7 avril 2021

Utilisation d'un écran tactile TFT SPI 240 X 320 (ILI9341) avec un ESP8266

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. 



Pour interagir avec l'écran, il est possible d'utiliser un doigt; mais puisque sa surface utile est assez petite (5 cm par 4 cm), l'écran est accompagné d'un stylet qui permet de toucher une position beaucoup plus précise.

Attention: on trouve sur le marché des versions non-tactiles de cet écran. Lisez soigneusement la description avant d'acheter...



Connexions

Le module comporte 18 broches: 
  • 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
Les broches dont le symbole commence par la lettre T concernent le capteur tactile: il n'est pas nécessaire de les brancher si vous désirez utiliser l'écran comme simple afficheur.

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"


J'ai ensuite ouvert le fichier "Setup1_ILI9341.h" qui se trouve dans le dossier "User_setups".


Aux lignes 6, 7 et 8, on choisi le numéro des broches de l'ESP8266 qui correspondent aux broches CS, DC et RST de l'écran. Les broches indiquées sont déjà correctes si vous utilisez un module NodeMcu. Si ce n'est pas le cas, vous devrez probablement remplacer "PIN_D8" par "15", "PIN_D3" par "0" et "PIN_D4" par 2.

Sur la capture d'écran ci-dessus, portez attention à la ligne 11, qui ne se trouvait pas dans le fichier au départ: j'ai indiqué la broche qui correspond à la broche T_CS (chip select du capteur tactile):

"#define TOUCH_CS PIN_D2"

Ici encore, si vous n'utilisez pas un module NodeMcu, vous devrez peut-être utiliser le numéro de la broche GPIO 4:

"#define TOUCH_CS 4"

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:


Yves Pelletier (TwitterFacebook)


2 commentaires:

  1. Ce commentaire a été supprimé par l'auteur.

    RépondreSupprimer
  2. Bonjour,
    En dehors du touchscrenn tout fonctionne bien !
    Auriez vous la solution ?
    Merci pour vos réponses.
    L'Arsène.

    RépondreSupprimer