Pour la théorie complète
Ce tutoriel reste pratique. Pour comparer SPI, I2C et UART en détail (vitesse, nombre de fils, cas d’usage), consulte le concept Les bus de communication.
Câbler un écran TFT_eSPI et dessiner texte, formes et couleurs
Écran TFT en SPI avec un ESP32
Découvrir le bus SPI en pratique en câblant un écran TFT (ST7789 ou ILI9341), en configurant la bibliothèque TFT_eSPI, puis en dessinant du texte et des formes.
Logiciels :
Machines/Outils :
Le SPI (Serial Peripheral Interface) est le bus de communication le plus rapide et le plus utilisé pour piloter un écran. Ce tutoriel couvre :
Contrairement à l’I2C (2 fils, plusieurs esclaves par adressage), le SPI utilise 4 fils et sélectionne son esclave par une broche dédiée :
| Fil | Rôle |
|---|---|
| MOSI | Master Out Slave In — données envoyées par l’ESP32 vers l’écran |
| MISO | Master In Slave Out — données renvoyées par le périphérique (inutilisé pour un écran en écriture seule) |
| SCK (ou SCLK) | Horloge, générée par l’ESP32 |
| CS (Chip Select) | Sélectionne l’esclave actif — un fil dédié par périphérique sur le bus |
Un écran ajoute généralement deux broches supplémentaires, hors du bus SPI standard :
| Fil | Rôle |
|---|---|
| DC (Data/Command) | Indique si l’octet envoyé est une commande ou une donnée de pixel |
| RST | Reset matériel de l’écran |
Relie les 6 broches de l’écran à l’ESP32. Les broches CS, DC et RST peuvent être câblées sur n’importe quel GPIO libre ; SCK et MOSI doivent utiliser un bus SPI matériel de l’ESP32 pour de bonnes performances.
Écran TFT ESP32
VCC ──────────── 3,3 V
GND ──────────── GND
CS ──────────── GPIO10
DC ──────────── GPIO11
RST ──────────── GPIO12
SCK ──────────── GPIO13
MOSI ──────────── GPIO14
BLK ──────────── 3,3 V (ou un GPIO pour piloter le rétroéclairage)
TFT_eSPI est la bibliothèque de référence pour piloter ces écrans sur ESP32 : rapide, et compatible avec de nombreux contrôleurs (ST7789, ILI9341, ST7735…). Sa particularité : la configuration matérielle (pins, contrôleur) ne se fait pas dans le code, mais dans un fichier User_Setup.h séparé.
Dans le Library Manager, recherche TFT_eSPI et installe la bibliothèque de Bodmer. Le fichier User_Setup.h à modifier se trouve dans le dossier de la bibliothèque installée (Documents/Arduino/libraries/TFT_eSPI/User_Setup.h).
Ajoute la bibliothèque dans platformio.ini, puis force le chargement de ta configuration personnalisée avec build_flags :
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
lib_deps =
bodmer/TFT_eSPI
build_flags =
-DUSER_SETUP_LOADED=1
-include User_Setup.h
Crée ensuite un fichier User_Setup.h à la racine de ton projet (à côté de platformio.ini) :
// User_Setup.h
#define ST7789_DRIVER // adapte selon le contrôleur de ton écran (ST7789, ILI9341...)
#define TFT_CS 10
#define TFT_DC 11
#define TFT_RST 12
#define TFT_SCLK 13
#define TFT_MOSI 14
#define SPI_FREQUENCY 40000000
TFT_eSPI expose un système de coordonnées (0,0) en haut à gauche de l’écran.
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();
void setup() {
tft.init();
tft.setRotation(1); // paysage (0 à 3 selon l'orientation voulue)
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setTextSize(2);
tft.setCursor(10, 10);
tft.print("Hello ESP32 !");
tft.drawRect(20, 50, 60, 30, TFT_WHITE); // rectangle contour
tft.fillCircle(160, 65, 15, TFT_RED); // cercle plein
tft.drawLine(0, 100, tft.width(), 100, TFT_GREEN);
}
void loop() {}
TFT_eSPI code chaque couleur sur 16 bits (5 bits rouge, 6 bits vert, 5 bits bleu) plutôt que les 24 bits habituels (RGB888). Des constantes couvrent les couleurs courantes (TFT_BLACK, TFT_WHITE, TFT_RED, TFT_GREEN, TFT_BLUE, TFT_YELLOW…), et une couleur personnalisée se construit avec :
uint16_t orange = tft.color565(255, 140, 0); // rouge, vert, bleu (0-255 chacun)
tft.fillCircle(80, 65, 15, orange);
Contrairement à un écran OLED bufferisé (comme le SSD1306), TFT_eSPI dessine directement à l’écran à chaque appel : il n’y a pas de display() à invoquer pour valider un rendu. En contrepartie, il faut effacer explicitement une forme avant de la redessiner ailleurs, sous peine de laisser une traînée :
int x = 20;
void loop() {
tft.fillCircle(x, 65, 10, TFT_BLACK); // efface l'ancienne position
x = (x + 5) % tft.width();
tft.fillCircle(x, 65, 10, TFT_WHITE); // dessine la nouvelle
delay(30);
}
L’écran affiche un texte, des formes fixes, et un cercle blanc qui se déplace horizontellement en boucle sans laisser de traînée. Ce motif « effacer l’ancienne position puis dessiner la nouvelle » est la base de toute animation avec TFT_eSPI.
delay() par un minuteur basé sur millis() pour animer l’écran sans jamais bloquer la lecture d’autres entrées (bouton, joystick).