vendredi 23 août 2019

Écran couleur SPI ST7735 et ESP32 / ESP8266


Aujourd'hui, je vous prodigue quelques conseils sur l'utilisation d'un petit écran couleur de 128 X 160 pixels, utilisant le protocole SPI, et basé sur le contrôleur ST7735, avec une carte ESP32 ou ESP8266.

Il existe plusieurs écrans similaires mais comportant certaines différences (par exemple, ceux dont le contrôleur est le S6D02A1 ou encore le ILI9163). Il est possible que mes indications vous soient utiles même si votre écran n'est pas rigoureusement identique à celui que j'ai utilisé.

Mon modèle porte la mention "KMR-1.8 SPI". Il est muni d'un lecteur de carte SD (que je n'ai pas utilisé pour l'instant) et de 16 connecteurs.




Connexions

Voici la façon de brancher votre écran à l'ESP32 ou à l'ESP8266 pour pouvoir utiliser sans modification la bibliothèque de Bodmer, que je vous présente un peu plus loin.

Schéma du circuit pour un module de développement STM32 (voir description un peu plus loin).

Schéma du circuit pour une carte Wemos D1 mini (voir description ensuite).

Allons-y broche par broche ( la broche numéro 1 de l'écran est celle qui est en bas sur les schéma ci-dessus):
  • #1 GND du KMR-1.8: GND de l'ESP8266 ou de l'ESP32
  • #2 VCC du KMR-1.8: sortie 5 V de l'ESP8266 ou de l'ESP32 *
  • #3 NC du KMR-1.8: Pas branché
  • #4 NC du KMR-1.8: Pas branché
  • #5 NC du KMR-1.8: Pas branché
  • #6 RESET du KMR-1.8: GPIO 2 de l'ESP8266 ou GPIO 4 de l'ESP32
  • #7 AO du KMR-1.8: GPIO 0 de l'ESP8266 ou GPIO 2 de l'ESP32
  • #8 SDA du KMR-1.8: GPIO 13 de l'ESP8266 ou GPIO 23 de l'ESP32
  • #9 SCL du KMR-1.8: GPIO 14 de l'ESP8266 ou GPIO 18 de l'ESP32
  • #10 CS du KMR-1.8: GPIO 15 de l'ESP8266 ou GPIO 15 de l'ESP32
  • #11 SCK du KMR-1.8: pas branché (lecteur de carte SD)
  • #12 MISO du KMR-1.8: pas branché (lecteur de carte SD)
  • #13 MOSI du KMR-1.8: pas branché (lecteur de carte SD)
  • #14 SD_CS du KMR-1.8: pas branché (lecteur de carte SD)
  • #15 LED+ du KMR-1.8: 3.3 V **
  • #16 LED- du KMR-1.8: GND
* Mon écran comporte un régulateur de tension 65z5 (portant la désignation "U2" sur le circuit imprimé) qui permet d'alimenter le module avec une tension de 5 V (si vous préférez l'alimenter avec 3,3 V, il faut fermer par une soudure le jumper "JP1" au verso de l'écran). Notez que certains écrans en apparence identiques sont conçus pour être alimentés avec 3,3 V! Sur ma carte ESP32, la broche "VIN" est directement liée au 5 V de l'alimentation USB et constitue donc une excellente sortie 5 V.

** Pour le rétroéclairage, j'ai utilisé une résistance de protection d'une centaine de ohms, mais elle ne semble pas obligatoire.

Installation de la bibliothèque TFT_eSPI

TFT_eSPI est une bibliothèque spécialement conçue pour piloter des écrans TFT SPI avec l'ESP32 ou l'ESP8266. Elle est compatible avec les contrôleurs ILI9341, ILI9163, ST7735, S6D02A1, ILI9481, ILI9486, ILI9488, HX8357D et ST7789! Elle a été conçue par Bodmer, le même qui a fait des bibliothèques similaires pour l'Arduino. Vous pouvez installer la bibliothèque TFT_eSPI par l'entremise du gestionnaire de bibliothèque de l'IDE Arduino.

Modifications à apporter au fichier User_Setup.h

Une fois la bibliothèque installée, il est très important d'ouvrir le fichier "User_Setup.h" afin d'y sélectionner les paramètres qui conviennent à votre écran. Le chemin d'accès, à partir de votre dossier "libraries", est "libraries / TFT_eSPI / User_Setup.h".

Parmi tous les contrôleurs énumérés, il faut en choisir un seul: pour mon écran, c'est le ST7735.


Ensuite, je choisi la définition qui correspond à mon écran: 128 pixels de largeur et 160 pixels de hauteur.

Il existe plusieurs variantes d'écrans basés sur le ST7735, et Bodmer les a classés selon la couleur de l'onglet de la pellicule qui protégeait l'écran lors de l'achat. En général, on les essaie au hasard jusqu'à ce qu'on tombe sur celle qui fonctionne; dans mon cas, il s'agit du ST7735_BLACKTAB. Si vous choisissez la mauvaise variante, votre écran fonctionnera quand même, mais avec les mauvaises couleurs, ou avec des bandes de pixels aléatoires sur les bords de l'image.

Si vous utilisez un ESP8266, il faut décommenter les lignes qui indiquent le numéro des broches reliées à CS, DC et RST. Bodmer a utilisé la numérotation des cartes NodeMCU. Si vous utilisez une carte ESP8266 qui ne respecte pas la même convention, utilisez plutôt les numéros de GPIO: remplacez "PIN_D8" par "15", "PIN_D3" par "0", et "PIN_D4" par "2".
Si vous utilisez un ESP32, les lignes à décommenter se trouvent un peu plus bas:


Exécution des exemples fournis avec la bibliothèque

Pour vérifier le fonctionnement correct de votre écran, il est temps de faire l'essai de quelques-uns des nombreux exemples fournis avec la bibliothèque (Menu Fichier / Exemples / TFTeSPI / 160 X 128 ). Si tout va bien, vous devriez voir apparaître une image sur l'écran. Si rien n'apparaît à l'écran, ça peut être causé par une connexion incorrecte, ou un paramètre mal réglé dans le fichier User_Setup.h ... bonne chance!



Quelques sketches

Je vous présente un premier sketch qui ne fait rien de très utile sauf explorer quelques fonctions simples de la bibliothèque:
  • setRotation: pour régler l'écran en mode portrait ou en mode paysage
  • fillScreen: pour remplir tout l'écran avec la couleur désirée
  • setTextColor: pour choisir la couleur du texte à écrire
  • drawString: pour écrire un texte qui débute à la position choisie
  • drawCentreString: pour écrire un texte dont le centre se trouve à la position choisie
  • drawLine: pour tracer une droite entre deux positions
  • drawRect: pour tracer le contour d'un rectangle
  • drawCircle: pour tracer le contour d'un cercle
  • drawRoundRect: pour tracer le contour d'un rectangle à coins arrondis
  • drawTriangle: pour tracer un triangle
  • fillRect: pour tracer un rectangle plein
  • fillCircle: pour tracer un cercle plein
  • fillRoundRect: pour tracer un rectangle plein à coins arrondis
  • fillTriangle: pour tracer un triangle plein
  • drawPixel: pour tracer un point

/*****************************************************
On dessine sur un écran TFT KMR-1.8 SPI
Version pour ESP8266 / ESP32
Plus d'infos:
https://electroniqueamateur.blogspot.com/2019/08/ecran-couleur-spi-st7735-et-esp32.html
Les couleurs prédéfinies par la bibliothèque sont:
TFT_BLACK TFT_NAVY TFT_DARKGREEN TFT_DARKCYAN
TFT_MAROON TFT_PURPLE TFT_OLIVE TFT_LIGHTGREY
TFT_DARKGREY TFT_BLUE TFT_GREEN TFT_CYAN
TFT_RED TFT_MAGENTA TFT_YELLOW TFT_WHITE
TFT_ORANGE TFT_GREENYELLOW TFT_PINK
*****************************************************/
#include <TFT_eSPI.h>
#include <SPI.h>
TFT_eSPI ecran = TFT_eSPI();
void setup() {
ecran.init();
ecran.setRotation(1); // réglage de l'écran en mode paysage (0 pour mode portrait)
randomSeed(analogRead(A0)); // pour la génération de nombres aléatoires
}
void loop() {
// compte à rebours
// fond vert
ecran.fillScreen(TFT_GREEN);
// texte pourpre sur fond vert
// puisqu'on a spécifié une couleur de fond, le texte
// masquera ce qui était écrit prédécemment
ecran.setTextColor(TFT_PURPLE, TFT_GREEN);
// on écrit "5", à la position x = 80, y = 35, avec la police #7
ecran.drawCentreString("5", 80, 35, 7);
delay(500);
ecran.drawCentreString("4", 80, 35, 7);
delay(500);
ecran.drawCentreString("3", 80, 35, 7);
delay(500);
ecran.drawCentreString("2", 80, 35, 7);
delay(500);
ecran.drawCentreString("1", 80, 35, 7);
delay(500);
// présentation des 4 polices de caractère (2, 4, 6 et 7)
// 6 et 7 ne comportent que des chiffres
ecran.fillScreen(TFT_WHITE); // fond blanc
ecran.setTextColor(TFT_BLACK); // texte noir
ecran.drawString("123", 20, 25, 2); // police #2
delay(500);
ecran.setTextColor(TFT_DARKGREEN); // texte vert
ecran.drawString("123", 10, 70, 4); // police #4
delay(500);
ecran.setTextColor(TFT_BLUE); // texte bleu
ecran.drawString("123", 60, 10, 6); // police #6: chiffres seulement
delay(500);
ecran.setTextColor(TFT_RED ); // texte rouge
ecran.drawString("123", 50, 60, 7); // police #7: chiffres seulement
delay(500);
// formes géométriques simples
ecran.fillScreen(TFT_BLACK); // fond noir
ecran.drawLine(5, 64, 155, 64, TFT_YELLOW); // ligne horizontale à y = 64
ecran.drawLine(80, 5, 80, 123, TFT_YELLOW); // ligne verticale à x = 80
delay(500);
// contour d'un rectangle x= 15, y = 5, largeur = 50, hauteur = 50, couleur vert
ecran.drawRect( 15, 5, 50, 50, TFT_GREENYELLOW);
delay(500);
// contour d'un cercle: x = 120, y = 30, rayon = 25, couleur orange
ecran.drawCircle(120, 30, 25, TFT_ORANGE);
delay(500);
// contour de rectangle à coins arrondis x = 8, y = 80, largeur = 60, hauteur = 30, rayon du coin = 5, couleur rose
ecran.drawRoundRect(8, 80, 60, 30, 5, TFT_PINK); // contour d'un rectangle à coins arrondis
delay(500);
// contour de triangle x1 = 120 y1 = 70 x2 = 90 y2 = 120 x3 = 150 y3 = 120 couleur cyan
ecran.drawTriangle(120, 70, 90, 120, 150, 120, TFT_CYAN);
delay(500);
// même chose, mais avec des formes pleines plutôt que des contours.
ecran.fillRect( 15, 5, 50, 50, TFT_GREENYELLOW);
delay(500);
ecran.fillCircle(120, 30, 25, TFT_ORANGE);
delay(500);
ecran.fillRoundRect(8, 80, 60, 30, 5, TFT_PINK);
delay(500);
ecran.fillTriangle(120, 70, 90, 120, 150, 120, TFT_CYAN);
delay(500);
ecran.fillScreen(TFT_YELLOW);
// on trace des points au hasard
for (int i = 1; i < 10000; i++) {
int x = random(159);
int y = random(127);
ecran.drawPixel(x, y, TFT_BLACK); // draw pixel: un seul point
delay(1);
}
}

La vidéo ci-dessous permet de constater le résultat.



Un deuxième sketch présente à l'écran la mesure de l'entrée analogique A0.

/*****************************************************
Affichage d'une mesure analogique sur un écran TFT
KMR-1.8 SPI
Version pour ESP8266 / ESP32
Plus d'infos:
https://electroniqueamateur.blogspot.com/2019/08/ecran-couleur-spi-st7735-et-esp32.html
*****************************************************/
#include <TFT_eSPI.h>
#include <SPI.h>
TFT_eSPI ecran = TFT_eSPI();
int valeurPrec = 9999; // la valeur déjà affichée à l'écran (on commence par une valeur impossible afin de forcer la mise à jour)
void setup() {
ecran.init();
ecran.setRotation(1); // réglage de l'écran en mode paysage
ecran.fillScreen(TFT_BLACK); // on dessine un fond noir
// on écrit "tension", en petits caractères, centré en haut
// de l'écran (cet affichage ne changera pas):
ecran.setTextColor(TFT_YELLOW);
// positionx: 80, position y: 10, police de caractère #4
ecran.drawCentreString("Tension:", 80, 10, 4);
ecran.setTextSize(2); // la valeur numérique sera écrite en taille 2
}
void loop() {
int valeur;
// mesure de la tension à l'entrée A0
valeur = map(analogRead(A0), 0, 4095, 0, 330);
if (valeur != valeurPrec) { // la valeur mesurée a changé
int xpos = 10; // position x du début du texte
xpos = 10;
// on écrit la nouvelle valeur en vert sur fond noir
// puisqu'on a spécifié une couleur de fond, la nouvelle valeur
// masquera celle qui était déjà inscrite à l'écran
ecran.setTextColor(TFT_GREEN, TFT_BLACK);
xpos += ecran.drawFloat(valeur / 100.0, 2, xpos, 40, 4);
ecran.drawString(" V", xpos, 35, 4);
// enveloppe de la jauge rectangulaire
// positionx: 14, positiony: 95, largeur 134, hauteur 14, couleur noir
ecran.fillRect( 14, 95, 134, 14, TFT_BLACK);
ecran.drawRect( 14, 95, 134, 14, TFT_WHITE);
// partie mobile de la jauge rectangulaire
ecran.fillRect( 16, 97, map(valeur, 0, 330, 0, 130), 10, TFT_RED);
valeurPrec = valeur;
delay(1000);
}
}

À lire aussi

Le même écran a également été utilisé avec une carte Arduino Uno , avec une carte STM32 et avec un Raspberry Pi Pico.

D'autres écrans peuvent évidemment être pilotés par une carte ESP8266 ou ESP32, comme par exemple un écran OLED SH1106, un écran Nokia 5110 ou un classique afficheur 16 X 2.

Vous pouvez également consulter la liste de tous les articles concernant l'ESP8266 et l'ESP32.


Yves Pelletier
   (TwitterFacebook)


2 commentaires:

  1. J'adore ! Y a bien plus de renseignements dans ce tuto que dans le site de la lib tout au moins pour moi.... J'ai vu qu'on pouvait aussi changer la taille des caractères avec tft.setTextSize mais je ne sais pas comment changer de fonts...

    RépondreSupprimer
  2. Merci, que de temps gagné !

    RépondreSupprimer