Démo : “papier → caméra → OCR → LLM → JSON → ESP32 (LEDs + TFT)”.
1. Vue d’ensemble du système
Le projet se compose de trois blocs : front web (capture caméra), backend FastAPI (prétraitement + OCR + LLM), et ESP32 (serveur HTTP + exécution JSON + affichage TFT).
- L’utilisateur écrit une commande sur papier.
- Le navigateur capture l’image via la caméra (JPEG base64).
- Le backend OCR extrait un texte puis le LLM génère une commande JSON stricte.
- L’ESP32 reçoit ce JSON et exécute l’action + feedback TFT (cercles, compteurs, message).
2. Matériel et câblage
2.1 Matériel
- ESP32 Dev Module (Wi-Fi)
- Écran TFT SPI (ILI9341) + librairie TFT_eSPI
- 3 LEDs (rouge, verte, bleue) + résistances (220–330 Ω)
- Breadboard + fils Dupont
- PC pour FastAPI + navigateur avec caméra (webcam PC / caméra téléphone)
2.2 LEDs (GPIO)
| LED | GPIO | Montage |
|---|---|---|
| Rouge | 25 | GPIO → résistance → anode ; cathode → GND |
| Verte | 26 | GPIO → résistance → anode ; cathode → GND |
| Bleue | 27 | GPIO → résistance → anode ; cathode → GND |
Important : GND commun entre ESP32, TFT et LEDs.
2.3 TFT SPI (ILI9341)
| Signal | GPIO (exemple) | Remarque |
|---|---|---|
| MOSI | 23 | SPI data |
| SCLK | 18 | SPI clock |
| MISO | 19 | Optionnel selon module |
| CS | 15 | Chip select |
| DC | 2 | Data/Command |
| RST | 4 | Reset |
| BL | 32 ou 3.3V | Backlight |
2.4 Configuration TFT_eSPI
#define ILI9341_DRIVER
#define TFT_MOSI 23
#define TFT_SCLK 18
#define TFT_MISO 19 // optionnel
#define TFT_CS 15
#define TFT_DC 2
#define TFT_RST 4
#define SPI_FREQUENCY 27000000 // 27 MHz
3. ESP32 : serveur HTTP, JSON et affichage TFT
3.1 Rôle
- Connexion Wi-Fi + affichage IP sur TFT
- Serveur HTTP (port 80) avec endpoint
POST /command - Parsing JSON (ArduinoJson) et exécution d’une liste
actions[] - Feedback TFT : cercles RGB + compteurs + zone message
3.2 Format JSON attendu
{
"actions": [
{
"type": "set_led" | "display_text",
"colors": ["red","green","blue"] | [],
"state": "on" | "off" | "blink" | null,
"duration_s": number | null,
"delay_ms": number | null,
"blink_period_ms": number | null,
"message": string | null
}
]
}
colors est absent ou vide → l’action s’applique aux 3 LEDs.
3.3 Non-bloquant (millis)
Pas de delay() : timers d’extinction + clignotement gérés via millis(), et rafraîchissement TFT périodique (~200 ms).
L’ESP32 reste réactif et peut recevoir une nouvelle commande pendant une action longue.
4. Backend FastAPI : OCR + interprétation LLM
4.1 Endpoints
| Route | Méthode | Rôle |
|---|---|---|
/ | GET | Test : {"status":"ok"} |
/api/command | POST | Reçoit image_base64 → OCR → LLM → JSON → envoi ESP32 |
4.2 Prétraitement OpenCV (scan-like)
- Détection/redressement feuille (contour 4 points + warp perspective)
- Contraste (ex : CLAHE), resize contrôlé
- Seuillage adaptatif (plus robuste qu’Otsu si éclairage non uniforme)
- Morphologie : close/open pour renforcer les lettres et réduire le bruit
4.3 OCR (EasyOCR) + nettoyage
- Langues FR/EN, paramètres tolérants (beamsearch, seuils ajustés)
- Nettoyage : minuscules + corrections (1→l, 0→o, 5→s, 7→t) + regex + espaces
4.4 Interprétation LLM via OpenRouter (JSON strict)
Le LLM transforme un texte OCR bruité en JSON strict : couleurs, état (on/off/blink), durée, message TFT, et séparation en plusieurs actions (et/puis/ensuite).
Exemple :
"clignote toutes les leds pendant 20 et affiche bonjour"
→ actions[0] = set_led (blink, duration_s=20, blink_period_ms=500)
→ actions[1] = display_text ("bonjour")
5. Front Web : capture caméra et visualisation
- Activation caméra (
getUserMedia) - Capture via canvas → JPEG base64 → POST
/api/command - Affichage : texte OCR, JSON, statut d’envoi ESP32
- Overlay “Analyse en cours…” si traitement long
6. Résultats, limites et améliorations
6.1 Résultats
- Chaîne complète fonctionnelle : papier → caméra → OCR → LLM → ESP32
- Feedback local clair sur TFT (état LEDs + compteurs + message)
- Robuste face au bruit OCR grâce au LLM
6.2 Limites
- OCR manuscrit sensible : éclairage, reflet, inclinaison, lisibilité (majuscule + feutre noir recommandé)
- Dépendance réseau/LLM : latence, quotas, disponibilité
- Réseau local : backend et ESP32 doivent être joignables (IP ESP32 variable si DHCP)
Conclusion
Ce projet illustre une interaction naturelle “papier → IA → action” reliant vision, NLP et IoT. Grâce à une architecture modulaire (front / backend / ESP32), il est facile d’étendre les actions matérielles et d’améliorer la robustesse de l’OCR.
Galerie (figures)