Add FATFS LFN (heap, 255), LVGL stdio FS ('S' drive),
mbedTLS external+dynamic alloc, SPIRAM task stacks.
WiFi dynamic TX blocked by SPIRAM_TRY_ALLOCATE_WIFI_LWIP
Kconfig dep; static TX (TYPE=0) is correct for this board.
Lisael Box
Firmware ESP32-S3-BOX-3 pour une "boîte" à destination d'un jeune enfant : webradios FR enfants, boîte à sons (microSD), coin calme / respiration, horloge / veilleuse, et jeux adaptés. UI tactile LVGL, sans lecture obligatoire (gros boutons + icônes), volume bridé (plafond enfant).
⚠️ Statut : point de départ soigné, NON compilé / NON flashé. Ce dépôt a été écrit sans la carte ni ESP-IDF/ESP-ADF installés. Le code suit les APIs ESP-IDF 5.x, le BSP
esp-box-3(v3.2.x, LVGL 9) et ESP-ADF de façon idiomatique, mais rien n'a pu être bâti. Voir la section À vérifier sur le matériel — elle est honnête et exhaustive.
Matériel cible
- ESP32-S3-BOX-3 : ESP32-S3 (8 Mo PSRAM octal, 16 Mo flash), LCD 320×240 tactile capacitif, codec audio ES8311 + HP, micro ES7210, microSD, IMU (ICM-42670). Pas de capteur température/humidité externe sur la carte de base (un add-on AHT30 existe ; non supposé présent ici).
Stack logicielle
- ESP-IDF 5.4 / 5.5 (nouvelles APIs :
driver/i2c_master.h,driver/temperature_sensor.h,esp_netif_sntp.h, …). - BSP
espressif/esp-box-3^3.2.0(managed component) — écran, tactile, LVGL port, codec ES8311 (esp_codec_dev), microSD (FATFS), boutons, IMU. Tire transitivementesp_lvgl_port ^2, LVGL 9.x,esp_codec_dev ~1.5. - LVGL 9 pour l'UI tactile.
- ESP-ADF pour l'audio en streaming/décodage (webradio + lecture SD). ESP-ADF n'est pas un managed component : il s'installe à part (voir ci-dessous).
espressif/cjsonpour lemanifest.jsonSD et les réponses open-meteo.
Arborescence
lisael-box/
├── CMakeLists.txt # projet ; injecte ESP-ADF via ADF_PATH
├── partitions.csv # 16 MB : factory 4 MB + storage FAT
├── sdkconfig.defaults # défauts communs
├── sdkconfig.defaults.esp32s3# PSRAM octal, 16 MB flash, 240 MHz, LVGL/PSRAM
├── main/
│ ├── CMakeLists.txt # sources + REQUIRES (BSP, ADF guardé)
│ ├── idf_component.yml # managed deps (esp-box-3, cjson)
│ ├── Kconfig.projbuild # menuconfig : WiFi, lat/lon météo, volume
│ ├── lisael_config.h # constantes partagées (TZ, NVS keys, volume)
│ ├── app_main.c # séquence de boot + tâches
│ ├── net/
│ │ ├── wifi.{c,h} # STA + reconnexion + creds NVS/menuconfig
│ │ ├── sntp_time.{c,h} # SNTP + fuseau Europe/Paris
│ │ └── weather.{c,h} # open-meteo.com (HTTPS, sans clé) périodique
│ ├── audio/
│ │ ├── audio_player.{c,h}# façade codec ES8311 + volume bridé (NVS)
│ │ ├── radio_pipeline.{c,h} # ESP-ADF http_stream→decoder→i2s
│ │ └── sd_player.{c,h} # ESP-ADF fatfs→mp3→i2s + parse manifest.json
│ ├── ui/
│ │ ├── ui.{c,h} # shell LVGL + routeur de modes + styles
│ │ ├── fr_date.{c,h} # date FR en lettres (sans setlocale)
│ │ └── icons.{c,h} # glyphes/emoji des tuiles et boutons
│ └── modes/
│ ├── home.c # accueil : date FR, heure, météo, capteur, tuiles
│ ├── radio.c # écran webradios + volume/stop
│ ├── radios.h # liste de stations (URLs à vérifier)
│ ├── soundbox.c # grille SD depuis manifest.json
│ ├── calm.c # bulle de respiration (anim LVGL)
│ ├── clock.c # horloge/veilleuse + histoire du soir
│ └── games.c # Memory + Compter + Coloriage (stub)
└── sdcard/
├── README.md # disposition attendue de la carte
└── sounds/manifest.json # exemple de manifeste
Prérequis
-
ESP-IDF 5.4+ installé et exporté :
. $IDF_PATH/export.sh -
ESP-ADF installé séparément (audio streaming/décodage). ESP-ADF n'est pas distribué via le registre de composants ; on le clone et on exporte
ADF_PATH:git clone --recursive https://github.com/espressif/esp-adf.git ~/esp/esp-adf export ADF_PATH=~/esp/esp-adf # (esp-adf fournit aussi $ADF_PATH/export.sh qui définit ADF_PATH)Le
CMakeLists.txtracine ajoute$ADF_PATH/componentsàEXTRA_COMPONENT_DIRS. SiADF_PATHest absent, le projet configure quand même (UI/horloge/respiration), mais les modules audio (webradio, lecture SD) ne sont pas liés et renvoientESP_ERR_NOT_SUPPORTEDà l'exécution (gardes__has_include("audio_pipeline.h")).⚠️ Compatibilité de versions à vérifier. ESP-ADF s'épingle historiquement à des versions précises d'ESP-IDF, et son abstraction
audio_boardpeut entrer en conflit avec le BSPesp-box-3(les deux veulent gérer l'I2S/le codec). Voir À vérifier sur le matériel.
Build & flash
# 1. cibler l'ESP32-S3
idf.py set-target esp32s3
# 2. configurer le WiFi et la météo (lat/lon, ville)
idf.py menuconfig
# -> "Lisael Box configuration" -> Wi-Fi / Weather / Audio
# 3. build (télécharge les managed components dans managed_components/)
idf.py build
# 4. flash + monitor (macOS : le port apparaît en /dev/cu.usbmodem*)
idf.py -p /dev/cu.usbmodem* flash monitor
# (Linux : -p /dev/ttyUSB0 ou /dev/ttyACM0 ; Ctrl+] pour quitter le monitor)
Provisioning Wi-Fi
Deux voies :
- menuconfig :
Lisael Box configuration → Wi-Fi → SSID / password. Les valeurs partent dans le binaire (pratique en dev). - NVS à l'exécution :
lisael_wifi_save_credentials()écrit les cléswifi_ssid/wifi_passdans le namespacelisael; elles priment sur les valeurs menuconfig au boot suivant. Brancher un petit portail captif ou une commande console reste à faire (les valeurs menuconfig suffisent pour démarrer).
Météo
api.open-meteo.com (gratuit, sans clé, HTTPS via le CA bundle mbedTLS). La
latitude/longitude viennent de NVS (lat/lon) sinon des défauts menuconfig
(Paris). Rafraîchissement toutes les CONFIG_LISAEL_WEATHER_REFRESH_MIN min.
En cas d'échec réseau, l'accueil affiche —.
Carte microSD
Voir sdcard/README.md. En bref : FAT32, dossier
/sounds/ contenant des .mp3 + un manifest.json
([{file, title, emoji}]). Les clips seront générés plus tard par TTS FR.
Modes
| Mode | Fichier | Implémenté | Notes |
|---|---|---|---|
| Accueil | modes/home.c |
✅ | date FR en lettres, heure (SNTP), météo (open-meteo), temp interne de la puce (fallback), 5 tuiles |
| 📻 Webradios | modes/radio.c + audio/radio_pipeline.c |
✅ code / ⚠️ URLs | pipeline ESP-ADF http_stream→decoder→i2s ; URLs de stations à confirmer (modes/radios.h) |
| 🔊 Boîte à sons | modes/soundbox.c + audio/sd_player.c |
✅ | grille depuis manifest.json ; pipeline fatfs→mp3→i2s |
| 🫧 Coin calme | modes/calm.c |
✅ | bulle qui gonfle (~4 s) / dégonfle (~6 s) en boucle, "Inspire…/Souffle…", ambiance SD optionnelle |
| 🕐 Horloge/veilleuse | modes/clock.c |
✅ | grande heure + date FR, fond sombre doux, backlight tamisé, bouton "Histoire du soir" |
| 🎮 Jeux | modes/games.c |
✅ Memory + Compter / 🚧 Coloriage stub | feedback positif uniquement, pas de défaite ; Coloriage est un stub documenté (canvas tactile = plus lourd sur 320×240) |
Sécurité enfant
- Volume bridé : plafond
CONFIG_LISAEL_VOLUME_MAX_PERCENT(défaut 60 %), appliqué partout viaaudio_player.c(clamp_volume), persisté en NVS. - Pas de lecture requise : icônes/emoji + gros boutons (≥ 56 px).
- Jeux sans échec : aucun score punitif, retour "Bravo ! ⭐".
À vérifier sur le matériel
Liste honnête de ce qui n'a pas pu être testé et doit être validé sur une vraie carte :
- Compilation. Le code n'a jamais été bâti (ni ESP-IDF ni ESP-ADF
installés ici). Attendez-vous à des ajustements : noms exacts de composants
managés ESP-ADF dans
REQUIRES(audio_pipeline,audio_stream,esp-adf-libs,audio_sal) et includes/macros décodeur exacts (DEFAULT_ESP_MP3_DECODER_CONFIGvs…_AUDIO_DECODER_CONFIGvarie selon la révision ADF). cJSON = composant built-injsond'ESP-IDF. - Coexistence BSP ↔ ESP-ADF sur l'I2S/codec. C'est le point chaud. Le
BSP
esp-box-3initialise l'I2S et le codec ES8311 (bsp_audio_init/bsp_audio_codec_speaker_init), et ESP-ADFi2s_streamveut lui aussi posséder le port I2S. Deux approches connues, à arbitrer sur le matériel :- (A) ADF possède l'I2S : configurer
i2s_streamavec le port/pins du BOX-3 et ne pas appelerbsp_audio_init; n'utiliser le handle codec du BSP que pour le volume/gain. (approche codée ici) - (B) Le BSP possède l'I2S : écrire le PCM décodé vers le codec via
esp_codec_dev_write()depuis unraw_streamau lieu dei2s_stream. Les configsi2s_std(port, broches, horloge viai2s_stream_set_clk) dansradio_pipeline.c/sd_player.cportent desTODO(hardware)— elles doivent matcher les valeurs du BSP de votre version.
- (A) ADF possède l'I2S : configurer
- Version ESP-ADF compatible avec votre ESP-IDF 5.4/5.5 (ADF s'épingle
souvent à une révision IDF précise). L'abstraction
audio_boardd'ADF peut doublonner le BSP — c'est pourquoiboard.hn'est pas inclus. - URLs des webradios (
modes/radios.h) : ce sont des placeholders plausibles (Radio Pomme d'Api, Radio Doudou, etc.). Confirmez chaque flux (curl -I→audio/mpegouaudio/aac) et préférez du MP3 HTTP simple. - Polices / emoji LVGL. Les fonts Montserrat par défaut ne contiennent
pas les emoji ; les glyphes 📻🔊🫧… risquent d'apparaître en "tofu". Pour
les rendre, embarquez une police emoji (subset Noto via
lv_font_conv) ou remplacez par le set monochromeLV_SYMBOL_*(déjà utilisé pour les flèches et contrôles). Les accents FR (é, à, û, î) demandent une police Latin-1 — à vérifier aussi. - Tailles de police montserrat (
lv_font_montserrat_28/48) : activez-les dansmenuconfig → Component config → LVGL → Font usagesi elles ne sont pas dans le set par défaut. - Backlight / luminosité.
bsp_display_brightness_set()/bsp_display_backlight_on()supposés présents dans le BSP — à confirmer sur votre version (sinon le mode veilleuse ne tamise pas). - Capteurs. Seule la température interne de la puce
(
driver/temperature_sensor.h) est lue, en fallback : ce n'est PAS la température de la pièce. L'IMU ICM-42670 et l'éventuel AHT30 ne sont pas exploités (le BSP exposebsp_sensor_init— à brancher si voulu). - Profondeur de pile des tâches.
net/weatherà 8192 o (TLS+HTTP+JSON),tickà 4096 o, tâche LVGL gérée par le BSP — à surveiller au monitor (uxTaskGetStackHighWaterMark) sous charge audio + UI. - Mémoire de jeu (
games.c). Les états Memory/Compter sont alloués vialv_mallocet vivent le temps de l'écran (non libérés à la destruction) — OK pour une app mono-écran longue durée, à durcir si les écrans sont recréés en boucle. - Politique supply-chain. Conformément au dépôt parent, les deps doivent
à terme être miroitées/épinglées par hash contre la baseline auditée
(
idf_component.ymlne fige aujourd'hui que les versions sémantiques).
Licence
À définir (aligner sur la politique de l'org electron-rare).