Shield TFT LCD 3,5 pouces : un écran 480 × 320 sur un bus 8 bits rapide
La plupart des petits écrans utilisés en électronique amateur communiquent en SPI : une ligne d’horloge, une ligne de données, et chaque octet passe au compte-gouttes, un bit à la fois. Le shield rouge de 3,5 pouces de cet article fonctionne autrement. Retournez-le : au lieu de MOSI et SCK, vous trouverez huit lignes de données, LCD_D0 à LCD_D7, si bien que chaque coup d’horloge transporte un octet entier. Ajoutez 480 × 320 pixels, un film tactile résistif et un emplacement microSD, et vous obtenez l’un des plus grands écrans qui s’enfichent directement sur un Arduino Uno, sans un seul fil.
Il mérite qu’on s’y attarde, même si vous n’avez jamais possédé d’Uno. Nous l’avons relié à un ESP32-S3 doté d’un périphérique 8080 matériel, nous avons cadencé le bus à 20 MHz et lu depuis une carte microSD une vidéo plein écran en 480 × 320 à 25 images par seconde ; vous pouvez la voir dans la partie consacrée à la vitesse. Au programme : ce qu’il y a sur la carte, comment fonctionne son bus et comment le programmer, d’où vient la vitesse et où elle se perd, et ce qu’on peut construire avec, d’une station météo à un cadre photo ou un panneau mural.

De quelle carte il est question exactement
Les boutiques le vendent sous le nom « 3.5 inch TFT LCD Shield for Arduino UNO/Mega », et plusieurs usines fabriquent des cartes qui se ressemblent mais diffèrent par leurs composants. Celle de cet article a un circuit imprimé rouge, la sérigraphie 3.5″ TFT LCD Shield et un code de date 2026-01-27. Son détail le plus révélateur se trouve dans un coin : deux cases imprimées, ILI9488 et ILI9486, dont aucune n’est cochée. Le contrôleur lui-même est monté en chip-on-glass et caché sous la dalle : la carte ne dit donc pas lequel des deux elle porte.
Notre exemplaire affiche une image correcte et stable avec la séquence d’initialisation de l’ILI9488 : il s’agit donc très probablement d’un ILI9488. C’est une hypothèse de travail plutôt qu’une identification : les deux contrôleurs partagent les commandes de base, et la mauvaise séquence donne souvent une image, elle aussi, simplement avec un contraste médiocre ou du scintillement. Une autre carte de la même boutique peut porter l’autre puce. La face avant accueille un film tactile résistif 4 fils, avec une nappe à quatre contacts le long du bord supérieur, et le verre est marqué H1454 7-3. Nulle part sur la carte on ne trouve de puce de contrôleur tactile.


Caractéristiques techniques
| Élément | Ce que c’est | En pratique |
|---|---|---|
| Dalle | TFT 3,5 pouces, 320 × 480 en natif, 480 × 320 en paysage | 153 600 pixels : de quoi afficher un graphique légendé, une photo ou une image vidéo |
| Contrôleur | ILI9486 ou ILI9488, en chip-on-glass ; le nôtre se comporte comme un ILI9488 | Les deux demandent des séquences d’init différentes ; la mauvaise affiche quand même une image, mais moins bonne |
| Interface | Bus parallèle de type Intel 8080 : huit lignes de données plus CS, RS, WR, RD et RST | 13 broches côté hôte ; un octet par impulsion d’écriture |
| Couleur | RGB666, 262K couleurs, 3 octets par pixel : vérifié. RGB565, 65K couleurs, 2 octets : devrait fonctionner | Deux octets par pixel réduiraient le trafic d’un tiers |
| Horloge d’écriture | 20 MHz vérifiés avec des fils Dupont ; la fiche technique de l’ILI9488 autorise jusqu’à 25 MHz | Une image complète en 23 ms à trois octets par pixel |
| Tactile | Film résistif 4 fils, sans puce de contrôleur | L’hôte le mesure avec son propre ADC, via des broches partagées avec l’écran |
| Stockage | Lecteur microSD en SPI, broches D10–D13 de l’Uno | Photos, polices et vidéos sur la carte elle-même |
| Tension | 5 V sur la broche 5V ; régulateur AMS1117 3,3 V sur la carte | Une seule alimentation pour la dalle, la logique et le rétro-éclairage |
| Niveaux logiques | Hôte en logique 3,3 V : vérifié ; le shield a été conçu pour la logique 5 V d’un Uno | Fonctionne avec un ESP32, un RP2040 ou un STM32 aussi bien qu’avec les cartes AVR |
| Rétro-éclairage | Toujours allumé ; aucune broche de commande | Pas de réglage de luminosité par logiciel ; pour économiser l’énergie, coupez le 5 V |
| Format | Shield Arduino Uno R3, 28 broches | S’enfiche sur un Uno ou un Mega ; tout autre hôte demande des fils Dupont |
D’abord, un peu d’arithmétique. Une image compte 480 × 320 = 153 600 pixels : 460 800 octets à trois octets par pixel, 307 200 à deux. Le bus 8 bits transfère un octet par impulsion d’écriture : à 20 MHz, il transporte donc 20 millions d’octets par seconde, et une image complète prend 23 ms, ou 15,4 ms à deux octets par pixel. Le SPI, lui, transfère un bit par coup d’horloge. À 20 MHz, la limite que fixe la fiche technique de l’ILI9488 pour son interface SPI, la même image prend 184 ms, et même avec un SPI surcadencé à 40 MHz, il lui faut 92 ms.
Les broches : câbler d’après le marquage
Le shield reprend la disposition de l’Arduino Uno, mais le marquage compte davantage que les numéros de l’Uno. L’octet de données est scindé d’une manière qui en surprend plus d’un : LCD_D2 à LCD_D7 se trouvent sur les broches D2 à D7 de l’Uno, tandis que LCD_D0 et LCD_D1 ont été déplacées sur D8 et D9, afin que D0 et D1 restent libres pour le port série de l’Uno.
| Broche Uno | Marquage | Rôle |
|---|---|---|
| A0 | LCD_RD | Impulsion de lecture, active à l’état bas ; à maintenir à l’état haut |
| A1 | LCD_WR | Impulsion d’écriture, active à l’état bas ; la dalle capture les données sur son front montant |
| A2 | LCD_RS | Sélection de registre : 0 pour une commande, 1 pour des données ; D/C dans d’autres bibliothèques |
| A3 | LCD_CS | Sélection de la puce, active à l’état bas |
| A4 | LCD_RST | Reset, actif à l’état bas |
| D2–D7 | LCD_D2–D7 | Bits de données 2 à 7 |
| D8, D9 | LCD_D0, LCD_D1 | Bits de données 0 et 1 |
| D10 | SD_CS | Sélection de la microSD |
| D11 | SD_DI | Entrée de données de la microSD, MOSI |
| D12 | SD_DO | Sortie de données de la microSD, MISO |
| D13 | SD_SCK | Horloge de la microSD |
| 5V, GND | 5V, GND | Alimentent toute la carte |
| 3.3V | 3V3 | On ne sait pas où elle est reliée ; ne pas s’en servir pour alimenter |
Deux détails piègent bien des gens. Le marquage n’est imprimé qu’au dos, si bien qu’écran face à vous, les rangées de gauche et de droite changent de côté : câblez strictement d’après le marquage, jamais d’après la position. Et sur un Uno, le shield prend presque tout. Il reste D0 et D1, qui forment le port série, la broche A5, dépourvue de marquage, et les broches SPI partagées avec la carte mémoire. L’I²C disparaît, car A4, le SDA de l’Uno, sert de LCD_RST. Une station météo avec quelques capteurs réclame donc un Mega ou, mieux, une carte 32 bits reliée par des fils Dupont.
Comment dialogue le bus 8 bits
Le bus est de type Intel 8080, ce que la fiche technique de l’ILI9488 appelle DBI Type B. Il n’a pas d’horloge au sens du SPI : l’hôte place un octet sur D0–D7 et envoie une impulsion sur WR, et la dalle prend l’octet sur le front montant. RS indique la nature de l’octet : 0 pour une commande, 1 pour un paramètre ou des données de pixels. CS encadre la transaction, RST réinitialise le contrôleur, et RD est l’impulsion de lecture.
| Signal | Au repos | Rôle |
|---|---|---|
| CS | Haut | Bas tant que l’hôte dialogue avec la dalle |
| RS | Peu importe | 0 pour un octet de commande, 1 pour un paramètre ou des données de pixels |
| WR | Haut | Une brève impulsion basse par octet ; la dalle capture D0–D7 sur le front montant |
| RD | Haut | Ne doit jamais flotter ; maintenu haut sauf pendant une lecture |
| RST | Haut | Un niveau bas remet le contrôleur à zéro |
| D0–D7 | — | Pilotées par l’hôte ; la dalle ne les pilote que lorsque RD est bas |

Voilà tout le protocole. Une commande part avec RS à l’état bas, et ses paramètres suivent avec RS à l’état haut. Les pixels ne diffèrent en rien des paramètres : après la commande RAMWR, 0x2C, chaque octet envoyé avec RS à l’état haut atterrit dans la mémoire de la dalle, et le flux peut durer aussi longtemps que l’hôte le souhaite.
Dessiner : une fenêtre et un flux
Le contrôleur garde toute l’image dans sa propre mémoire et rafraîchit lui-même la dalle à partir de celle-ci : l’hôte n’envoie donc que ce qui change. Pour dessiner, l’hôte ouvre une fenêtre : CASET, 0x2A, fixe la première et la dernière colonne, PASET, 0x2B, la première et la dernière ligne. Après RAMWR, les pixels remplissent cette fenêtre de gauche à droite et de haut en bas, sans aucune coordonnée intermédiaire. Deux fonctions de bus, l’une pour un octet de commande, l’autre pour des octets de données, suffisent à tout portage :
static void set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
uint8_t ca[4] = { (uint8_t)(x0 >> 8), (uint8_t)x0,
(uint8_t)(x1 >> 8), (uint8_t)x1 };
uint8_t pa[4] = { (uint8_t)(y0 >> 8), (uint8_t)y0,
(uint8_t)(y1 >> 8), (uint8_t)y1 };
lcd_write_cmd(0x2A); lcd_write_data(ca, 4); // CASET: columns
lcd_write_cmd(0x2B); lcd_write_data(pa, 4); // PASET: rows
}
// A solid rectangle in RGB666: 3 bytes per pixel, one window
static void fill_rect(uint16_t x, uint16_t y, uint16_t w, uint16_t h,
uint8_t r, uint8_t g, uint8_t b) {
const uint8_t px[3] = { r, g, b };
set_window(x, y, x + w - 1, y + h - 1);
lcd_write_cmd(0x2C); // RAMWR
for (uint32_t i = 0; i < (uint32_t)w * h; i++) {
lcd_write_data(px, 3);
}
}
C’est avec la fenêtre que la vitesse se gagne ou se perd. Envoyez autant de pixels que possible dans une même fenêtre : une fenêtre par pixel coûte onze octets de commandes et de coordonnées pour trois octets de couleur.
Formats de pixel et orientation
Deux registres déterminent l’aspect de l’image. COLMOD, 0x3A, fixe le format de pixel. 0x66, c’est le RGB666 : trois octets par pixel, avec la couleur dans les six bits de poids fort de chaque octet, et c’est ce qui tourne sur notre carte. 0x55, c’est le RGB565, deux octets par pixel : les deux fiches techniques le prévoient pour le bus parallèle et les bibliothèques populaires l’y utilisent, mais nous ne l’avons pas encore testé sur cet exemplaire. Si le nombre d’octets envoyés par pixel ne correspond pas à COLMOD, les aplats sortent sous forme de fines rayures de mauvaises couleurs qui ne couvrent qu’une partie de la fenêtre.
MADCTL, 0x36, fixe l’orientation et l’ordre des couleurs. Sur cette carte, la valeur 0x28 donne une image paysage de 480 × 320 correcte et sans effet miroir, et c’est grâce au bit BGR qu’elle contient que les couleurs partent dans l’ordre R, G, B tout simple. Un rouge et un bleu intervertis se corrigent avec ce bit, un effet miroir avec les bits MX et MY, et des axes permutés avec MV, jamais dans le code de l’application.
| MADCTL | Image | Sur cette carte |
|---|---|---|
| 0x48 | Portrait, 320 × 480 | Valeur standard, non testée |
| 0x28 | Paysage, 480 × 320 | Vérifiée |
| 0x88 | Portrait, retourné | Non testée |
| 0xE8 | Paysage, retourné | Non testée |
ILI9486 ou ILI9488 ?
En théorie, le contrôleur décline son identité : la commande 0xD3 renvoie un octet factice, suivi de 0x00, 0x94 et 0x86 ou 0x88. En pratique, beaucoup de shields de cette famille sont en écriture seule. Leurs tampons de bus sont câblés dans un seul sens, des broches vers la dalle, si bien que rien de ce que dit la dalle n’atteint jamais l’hôte. La bibliothèque populaire MCUFRIEND_kbv relit alors son propre octet de commande et annonce l’ID 0xD3D3 ; son sketch de test signale ce cas comme un shield en écriture seule.
Sur une telle carte, le contrôleur s’identifie à l’œil. Initialisez-le avec la séquence de l’ILI9488 et dessinez des aplats, des dégradés de gris et de couleur et une grille d’un pixel, puis recommencez avec la séquence de l’ILI9486, et gardez celle qui donne des dégradés lisses, un bon contraste et aucun scintillement. Nous n’avons pas essayé de lire l’ID sur la nôtre. Avec la séquence de l’ILI9488, son image est correcte : c’est donc elle qui figure ci-dessous.
La séquence d’initialisation de l’ILI9488 qui fonctionne sur cette carte
RST: high 50 ms, low 50 ms, high 150 ms ; hardware reset
0x01 ; SWRESET, wait 120 ms
0x28 ; DISPOFF
0xE0: 00 03 09 08 16 0A 3F 78 4C 09 0A 08 16 1A 0F ; positive gamma
0xE1: 00 16 19 03 0F 05 32 45 46 04 0E 0D 35 37 0F ; negative gamma
0xC0: 17 15 ; power control 1
0xC1: 41 ; power control 2
0xC5: 00 12 80 ; VCOM control
0x36: 48 ; MADCTL: portrait, BGR
0x3A: 66 ; COLMOD: RGB666
0xB0: 00 ; interface mode
0xB1: A0 ; frame rate
0xB4: 02 ; inversion control
0xB6: 02 02 3B ; display function
0xB7: C6 ; entry mode
0xF7: A9 51 2C 82 ; adjust control 3
0x11 ; SLPOUT, wait 120 ms
0x29 ; DISPON, wait 25 ms
0x36: 28 ; MADCTL: landscape
Chaque ligne est une commande suivie de ses octets de paramètres. Avec COLMOD à 0x55 au lieu de 0x66, la dalle attendrait du RGB565, que nous n’avons pas encore testé. Les valeurs des registres correspondent au pilote ILI9488 de TFT_eSPI, à ceci près que la bibliothèque choisit 0x55 pour les bus parallèles. La variante pour l’ILI9486 se trouve dans le guide de programmation, à la fin de l’article.
D’où vient la vitesse
Le SPI transfère un bit par coup d’horloge. Le bus 8 bits, un octet. À horloge égale, cela fait huit fois plus de données, et c’est toute la raison pour laquelle cette interface d’un autre âge est toujours là : elle demande treize broches au lieu de quatre ou cinq, mais elle remplit un grand écran en une fraction du temps.

Sur cette famille de contrôleurs en particulier, le SPI part en outre avec un handicap. En SPI, l’ILI9486 n’accepte la pleine couleur que sous forme 18 bits, et bien que la fiche technique de l’ILI9488 mentionne la couleur 16 bits pour son mode SPI 4 fils, en pratique ces puces sont pilotées à trois octets par pixel, et c’est exactement ce que font les bibliothèques populaires. La même fiche technique plafonne à 20 MHz l’horloge d’écriture SPI de l’ILI9488. Son bus parallèle a droit à un cycle d’écriture de 40 ns, soit 25 MHz : nos 20 MHz restent donc dans la spécification. L’ILI9486 est plus lent : sa fiche technique exige au moins 66 ns par écriture, soit environ 15 MHz. Si votre carte s’avère porter cette puce, commencez en dessous de cette valeur.
Mais le bus n’est jamais plus rapide que l’hôte qui le pilote. Basculer treize broches une à une avec digitalWrite() fait de l’interface la plus rapide de la carte l’une des plus lentes. Écrire des registres de port entiers vaut beaucoup mieux, et un périphérique matériel avec DMA, c’est l’idéal : le LCD_CAM d’un ESP32-S3, le PIO d’un RP2040 ou le FSMC d’un STM32 envoient les octets tout seuls pendant que le processeur prépare les suivants.
Notre test : vidéo à 25 i/s depuis une carte microSD
L’hôte était l’ESP32-S3-CAM N16R8 de notre article précédent, reliée au shield par des fils Dupont. Sur cette carte, les 13 lignes du bus ont pris des GPIO qu’utilise normalement la caméra, si bien que la caméra est restée sur la touche pendant ce test. Le bus passait par le pilote esp_lcd i80 d’ESP-IDF, sur le périphérique LCD_CAM du S3, avec une horloge d’écriture de 20 MHz, la séquence de l’ILI9488, le RGB666 et l’orientation paysage. Deux tampons DMA de 30 720 octets, de quoi loger 10 240 pixels chacun, travaillent à tour de rôle : pendant que l’un part vers la dalle, l’autre se remplit.
Le lecteur vidéo répartit le travail entre les deux cœurs. L’un lit les fichiers MJPEG sur la microSD de la carte hôte ; l’autre décode chaque image avec la bibliothèque JPEGDEC et pousse les blocs décodés directement dans les tampons DMA, en convertissant le RGB565 en RGB666 au passage. Résultat : une vidéo plein écran en 480 × 320, stable, à 25 images par seconde. Sur les 40 ms dont dispose chaque image, le bus en consomme 23. En SPI surcadencé à 40 MHz, la même image demanderait 92 ms rien que sur le bus : les 25 i/s seraient donc hors d’atteinte avant même qu’un seul pixel soit décodé.
La configuration du bus tient en deux structures. Voici comment notre pilote s’y prend. RD n’en fait pas partie du tout : esp_lcd n’a pas de chemin de lecture, et un GPIO ordinaire se contente donc de maintenir RD à l’état haut.
esp_lcd_i80_bus_config_t bus_config = {};
bus_config.dc_gpio_num = PIN_LCD_RS;
bus_config.wr_gpio_num = PIN_LCD_WR;
bus_config.clk_src = LCD_CLK_SRC_PLL160M;
bus_config.data_gpio_nums[0] = PIN_LCD_D0; // likewise [1] to [7]
bus_config.bus_width = 8;
// One DMA chunk: 32 lines of 320 pixels in RGB666
bus_config.max_transfer_bytes = 320 * 32 * 3;
esp_lcd_new_i80_bus(&bus_config, &i80_bus);
esp_lcd_panel_io_i80_config_t io_config = {};
io_config.cs_gpio_num = PIN_LCD_CS;
io_config.pclk_hz = 20 * 1000 * 1000; // 20 MHz write clock
io_config.trans_queue_depth = 10;
io_config.lcd_cmd_bits = 8;
io_config.lcd_param_bits = 8;
io_config.dc_levels.dc_cmd_level = 0; // RS low: command
io_config.dc_levels.dc_data_level = 1; // RS high: data
esp_lcd_new_panel_io_i80(i80_bus, &io_config, &io_handle);
Ensuite, esp_lcd_panel_io_tx_param() envoie les commandes avec leurs paramètres, et esp_lcd_panel_io_tx_color() met les données de pixels en file d’attente pour le DMA et rend la main aussitôt. C’est aussi là que se cache le piège : il ne faut pas remplir de nouveau un tampon avant la fin de son transfert, sinon des blocs de l’image sortent corrompus.
Il reste deux limites. Avec les réglages habituels, le contrôleur rafraîchit la dalle depuis sa mémoire environ 60 fois par seconde, et le shield ne sort pas le signal de tearing effect qui permettrait à l’hôte de caler ses écritures sur ce rafraîchissement : un mouvement rapide peut donc laisser apparaître une ligne de déchirure. Et un tampon d’image complet, 460 800 octets en RGB666, ne tient que dans une PSRAM externe : c’est pourquoi notre pilote envoie plutôt de petits morceaux depuis la mémoire interne.
Quel hôte, quelle bibliothèque
Le shield a été conçu pour l’Uno, mais l’Uno est l’hôte le plus lent qu’il puisse avoir. Le tableau résume les solutions habituelles ; le guide de programmation en fin d’article donne les contraintes de broches de chacune.
| Hôte | Solution | À surveiller |
|---|---|---|
| Arduino Uno | S’enfiche tel quel. MCUFRIEND_kbv avec Adafruit_GFX, plus Adafruit TouchScreen pour le film | 2 Ko de SRAM : pas de tampon d’image, les images sont lues en flux depuis la carte. L’octet de données est réparti sur deux ports, ce qui coûte du temps |
| Arduino Mega | S’enfiche tel quel. MCUFRIEND_kbv | Les broches de l’Uno tombent sur des ports dispersés du Mega, ce qui est plus lent que sur l’Uno ; mémoire et broches à revendre |
| ESP32 | esp_lcd i80 via l’I2S, LovyanGFX, TFT_eSPI | GPIO34–39 ne servent qu’en entrée. Les cartes au format Uno comme la Wemos D1 R32 y placent LCD_RS, LCD_CS et LCD_RST : ces trois lignes sont à recâbler |
| ESP32-S3 | esp_lcd i80 sur LCD_CAM avec DMA, comme dans notre test ; LovyanGFX et Arduino_GFX utilisent aussi LCD_CAM | N’importe quel GPIO peut porter n’importe quel signal. TFT_eSPI fonctionne aussi, mais sur le S3, il bascule les registres GPIO sans DMA |
| RP2040 | TFT_eSPI avec PIO et DMA | D0–D7 doivent être sur des GPIO qui se suivent |
| STM32 | FSMC ou FMC en mode 8080 si le boîtier le permet ; sinon, écritures de port | Les broches FSMC sont fixes pour chaque boîtier |
Quel que soit l’hôte, prévoyez les broches en pensant au tactile : le film partage des lignes avec l’écran, et ses extrémités analogiques demandent des broches compatibles ADC. Nous y revenons plus bas.
Sur un Uno, le plus rapide pour démarrer est MCUFRIEND_kbv. Nous n’avons pas exécuté nous-mêmes ce sketch sur un Uno : c’est la méthode standard de la bibliothèque, avec un ajout pour les cartes en écriture seule.
#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;
void setup() {
Serial.begin(9600);
uint16_t id = tft.readID();
Serial.print(F("ID = 0x"));
Serial.println(id, HEX);
// A write-only shield reads back 0xD3D3: name the controller yourself
if (id == 0xD3D3) id = 0x9488;
tft.begin(id);
tft.setRotation(1); // landscape, 480 × 320
tft.fillScreen(0x0000); // black
tft.setTextColor(0x07E0); // green
tft.setTextSize(3);
tft.setCursor(24, 24);
tft.print(F("Hello, 480 x 320"));
}
void loop() {}
Le tactile sans contrôleur tactile
Le film tactile est du type résistif 4 fils classique : deux couches résistives qui se touchent là où l’on appuie. Il n’y a ni XPT2046 ni puce similaire pour le lire. À la place, ses quatre électrodes sont reliées à des lignes que l’écran utilise déjà, et l’hôte les mesure avec son propre ADC. Il applique une tension aux bornes d’une couche et lit, par l’autre couche, la tension au point de contact, puis inverse les rôles pour l’autre axe.
Les lignes qui portent les électrodes varient d’une carte à l’autre, et sur la nôtre, nous ne les avons pas encore repérées. Sur les shields de cette famille, les extrémités analogiques se trouvent généralement sur LCD_WR, LCD_RS ou LCD_CS, et les extrémités numériques sur des lignes de données comme LCD_D6 et LCD_D7. Un multimètre les trouve en une minute : carte hors tension, deux paires entre les lignes de commande et les lignes de données présentent quelques centaines d’ohms, environ 300 pour une couche et 500 pour l’autre.
Lire le tactile revient alors à emprunter ces broches à l’écran. Attendez que le bus soit au repos, gardez inactive la ligne de commande qui n’est pas une électrode pour que la dalle ignore le bruit, prenez plusieurs échantillons, et rendez à chaque broche son rôle d’affichage avant le transfert suivant. Sautez cette dernière étape, et vous obtiendrez des pixels aléatoires et un écran figé. Avec un périphérique matériel comme LCD_CAM, c’est plus difficile encore, car il faut détacher les broches du périphérique puis les y rattacher : décidez donc comment vous lirez le tactile avant de figer le brochage. Le film préfère aussi les grandes cibles : des boutons de la taille du bout du doigt lui conviennent bien mieux qu’une interface façon smartphone.
microSD, alimentation et rétro-éclairage
L’emplacement microSD a ses propres lignes SPI, SD_CS, SD_DI, SD_DO et SD_SCK, sur les broches D10 à D13 de l’Uno, électriquement séparées du bus de l’écran. Sur tout autre hôte, il peut aller sur n’importe quelles broches compatibles SPI. Nous ne l’avons pas testé sur cet exemplaire : pour la vidéo ci-dessus, l’ESP32-S3 lisait la carte de son propre emplacement. Si vous ne l’utilisez pas, laissez ses lignes non connectées ou maintenez SD_CS à l’état haut.
L’alimentation arrive en 5 V sur la broche 5V. Le régulateur de la carte fournit le 3,3 V de la dalle et des tampons de bus, et un hôte en 3,3 V pilote directement la logique. Ne touchez pas à la broche 3V3 : on ne sait pas où elle est reliée, et elle ne remplace pas l’alimentation 5 V. Le rétro-éclairage n’a pas de broche de commande et reste allumé tant que la carte est alimentée : on ne peut donc ni le tamiser ni l’éteindre par logiciel ; DISPOFF et SLPIN effacent l’image, pas la lumière. Nous n’avons pas mesuré le courant. À titre indicatif, la spécification de la dalle d’un shield Uno de 3,5 pouces similaire donne 90 mA en valeur typique pour son rétro-éclairage à six LED : une alimentation USB trop faible ou le petit régulateur d’une carte de développement méritent donc une vérification à l’ampèremètre.
Que construire avec ce shield
Le 480 × 320 est une taille confortable : assez grande pour un graphique aux légendes lisibles, une photo ou une rangée de boutons de la taille du bout du doigt, assez petite pour se remplir vite. C’est pourquoi cette catégorie d’écrans revient sans cesse dans les projets, aussi bien sur ce shield précis que sur ses cousins.

1. Une station météo
Le montage le plus populaire de tous. Dans le projet Instructables Second Multi-functional Weather Station, un Arduino Mega porte exactement ce type de shield ILI9486 de 3,5 pouces, avec une horloge DS3231 et des capteurs DHT22 et BMP280, et utilise l’emplacement microSD du shield pour un album d’environ un millier de photos converties en BMP. D’autres montages se passent carrément de capteurs. Sur le blog thesolaruniverse, un ESP32 doté d’un shield de 3,95 pouces de même conception récupère la météo sur OpenWeatherMap par Wi‑Fi et l’affiche via le bus 8 bits avec TFT_eSPI. Un projet Elektor de décembre 2023 fait de même sur une carte Makerfabs ESP32-S3 avec un ILI9488 de 3,5 pouces, et lit les réglages Wi‑Fi et la ville dans un fichier de la carte mémoire.
2. Un cadre photo
L’emplacement microSD fait presque à lui seul du shield un cadre photo. MCUFRIEND_kbv fournit un exemple showBMP qui lit les fichiers BMP directement sur la carte, via les broches 10 à 13, et indique le temps de chargement de chacun. Sur un ESP32, le pilote esp-idf-parallel-tft de nopnop2002 affiche des fichiers BMP, JPEG et PNG sur les shields de cette famille et calibre aussi leur film tactile. C’est dans les transitions, fondus ou volets, que le bus parallèle se rentabilise : chaque étape d’une transition redessine tout l’écran, et une image complète coûte 23 ms sur ce bus, contre un dixième de seconde ou plus en SPI.
3. Un lecteur vidéo
Notre propre test représente le cas le plus exigeant : du MJPEG lu sur une carte à 25 i/s. Pour partir d’une base toute faite, les exemples MJPEG de la bibliothèque Arduino_GFX affichent la fréquence d’images moyenne et ventilent le temps entre lecture, décodage et dessin, ce qui en fait un banc d’essai pratique pour n’importe quelle carte. Larry Bank, l’auteur de JPEGDEC, le décodeur qu’utilise notre lecteur, a piloté un vieux shield Uno ILI9486 de 3,5 pouces depuis un RP2040 via PIO et DMA, et y a affiché des GIF animés ; son compte rendu s’intitule Breathing new life into an old LCD shield.
4. Une console de jeu
Les jeux demandent exactement ce que ce bus sait bien faire : redessiner beaucoup de pixels plusieurs fois par seconde. Le projet ESP32-S3_Uno-nofrendo fait tourner l’émulateur NES nofrendo sur une carte ESP32-S3 au format Uno, avec un shield 8 bits ILI9488 enfiché directement dessus, et charge les ROM depuis la carte microSD ; il n’a encore ni joystick ni son. Dans un registre plus simple, un clone de Tetris pour Arduino Mega avec un shield ILI9486 tire sa musique d’un transmetteur FM pour voiture : pour l’entendre, il faut régler une radio sur 87,5 MHz. La série de tutoriels Dumblebots construit un logiciel de dessin façon Paint et un morpion sur le même type de shield de 3,5 pouces, film tactile compris.
5. Un panneau tactile mural
Un panneau domotique est l’usage évident d’un écran tactile de cette taille, et là, les cousins tout faits l’emportent généralement. Le WT32-SC01 Plus associe un ESP32-S3 à un écran de 3,5 pouces en 480 × 320 sur le même type de bus 8 bits. openHASP en fait un panneau commandé par MQTT et bâti sur LVGL, et avec un composant communautaire, ESPHome peut le piloter pour Home Assistant. AirQualitySensor-IDF transforme la même carte en moniteur de qualité de l’air : il lit des capteurs de particules, de CO₂, de température et d’humidité, et trace six heures d’historique avec LVGL. Si vous avez une imprimante 3D, vous possédez peut-être déjà un écran de cette catégorie : l’interface Color UI de Marlin tourne sur des écrans tactiles de 3,5 pouces en 480 × 320 comme le MKS TFT35, reliés au STM32 de l’imprimante par le bus parallèle FSMC.
6. Instruments de mesure
Une trace d’oscilloscope doit être redessinée plusieurs fois par seconde, ce qui convient à un bus rapide. Un projet open source associe un STM32F303 à un écran ILI9486 de 3,5 pouces pour un oscilloscope à 2 Méch/s avec un enregistrement de 4096 points. DLO-138, un firmware open source pour le populaire kit DSO-138, pilote le plus petit ILI9341 de ce kit sur un bus 8 bits et en fait un oscilloscope à deux voies, avec en plus deux voies numériques. Pour les jauges, les compteurs et les graphiques, TFT_eSPI propose tout un dossier d’exemples écrits pour le 480 × 320.
Encore quelques idées que d’autres ont déjà réalisées sur des écrans 480 × 320 :
- Un navigateur GPS hors ligne. IceNav-v3 affiche des cartes OpenStreetMap hors ligne sur un ESP32-S3 et prend en charge les dalles ILI9488 en SPI comme sur des bus parallèles 8 ou 16 bits.
- Un écran « en cours de lecture ». La télécommande Spotify de ThingPulse affiche la pochette de l’album et accorde la couleur du fond à celle de la pochette, sur un ILI9488 de 3,5 pouces.
- Une radio avec vue du spectre. Un récepteur toutes bandes construit autour de la puce Si4735 et d’un ESP32 affiche un spectre et une cascade sur un ILI9488 de 4 pouces en 480 × 320.
Les cousins : le même écran sous d’autres formes
Le shield appartient à une grande famille. Si son format ou son bus ne convient pas à un projet, l’un de ses cousins fera peut-être l’affaire. Tous sont en 480 × 320, sauf les shields Uno plus petits :
| Écran | Contrôleur et bus | Bon à savoir |
|---|---|---|
| Shields Uno de 2,4 et 2,8 pouces | ILI9341 et autres ; parallèle 8 bits | Même brochage et mêmes bibliothèques, en 240 × 320 |
| Modules SPI de 3,5 pouces, comme le MSP3520 | ILI9488 ; SPI 4 fils | Peu de broches, tactile sur ses propres lignes SPI, trois octets par pixel |
| Shields Uno de 3,95 pouces | ILI9486 et autres ; parallèle 8 bits | Dalle plus grande, même câblage |
| WT32-SC01 Plus | ST7796 ; parallèle 8 bits, ESP32-S3 intégré | Un panneau tout prêt pour openHASP, ESPHome et LVGL |
| Makerfabs ESP32-S3 Parallel TFT, 3,5 pouces | ILI9488 ; parallèle 16 bits, ESP32-S3 intégré | Bus deux fois plus large |
| ESP32-3248S035, le Cheap Yellow Display de 3,5 pouces | ST7796 ; SPI, ESP32 intégré | Complet et bon marché, mais en SPI |
| MKS TFT35 | ILI9488 ou ST7796 ; parallèle FSMC | L’écran tactile de bien des imprimantes 3D |
Forces et faiblesses
| Points forts | Points faibles |
|---|---|
| S’enfiche directement sur un Uno ou un Mega | Sur un Uno, il prend presque toutes les broches, I²C compris |
| 480 × 320 avec tactile et microSD sur une seule carte | ILI9486 ou ILI9488 : la carte ne dit pas lequel, et elle peut être en écriture seule |
| Un bus 8 bits : une image complète en 23 ms à 20 MHz, fréquence vérifiée | Treize fils de signal sur tout hôte sur lequel il ne s’enfiche pas |
| Fonctionne avec des hôtes en 3,3 V : ESP32, RP2040, STM32 | Sans périphérique de bus matériel, l’essentiel de la vitesse est perdu |
| Vidéo plein écran à 25 i/s depuis un ESP32-S3 | Pas de signal de tearing effect sur les broches |
| Tactile sans puce supplémentaire | Le film tactile partage des broches avec l’écran et a besoin de l’ADC de l’hôte |
| Un emplacement microSD sur des lignes SPI séparées | Le rétro-éclairage est toujours allumé, sans aucun moyen de le tamiser |
Conclusion
Le shield TFT LCD de 3,5 pouces a tout d’une relique de l’ère de l’Arduino Uno, et sur un Uno, il se comporte comme tel : il prend presque toutes les broches et remplit l’écran au rythme d’un processeur 8 bits. Mais donnez-lui un hôte doté d’un vrai périphérique parallèle, et le vieux bus montre pourquoi il a survécu : un octet par coup d’horloge, une image complète de 480 × 320 en 23 ms, de la vidéo à 25 i/s.
Pour une station météo, un cadre photo, un panneau de commande ou un petit instrument de mesure, c’est largement suffisant, à condition que le premier essai parte d’une configuration éprouvée :
- Vérifiez l’absence de court-circuit sur 5V, 3V3 et GND, puis branchez d’abord GND et le 5 V sur la broche 5V.
- Câblez d’après le marquage au dos, jamais d’après la position, et maintenez LCD_RD à l’état haut dès le départ.
- Utilisez la séquence de l’ILI9488, COLMOD 0x66 et MADCTL 0x28, à 10 MHz au plus.
- Dessinez d’abord des aplats et des dégradés ; si l’image est délavée ou scintille, essayez la séquence de l’ILI9486.
- Augmentez l’horloge progressivement, jusqu’à 20 MHz sur un ILI9488.
- Ajoutez le film tactile et la carte microSD en dernier, l’un après l’autre.
Tout ce qui précède, et davantage, réuni dans un seul fichier : le guide de programmation de ce shield. Le brochage selon le marquage, la temporisation du bus et les limites des fiches techniques, les séquences d’initialisation des deux contrôleurs, les formats de pixel, la rotation, le tactile et la microSD, une procédure de mise en route et un guide de dépannage, chaque affirmation étant signalée comme vérifiée, probable ou inconnue. Confiez-le à un agent de programmation avant qu’il n’écrive la moindre ligne de code de pilote.