Boite Histoire
Présentation
Les jeunes enfants adorent souvent écouter des histoires, non seulement pour s'endormir mais également lors de temps de repos ou lors de (longs) trajets en voiture. Ma petite fille est de ceux-là, elle possède une boîte à histoire Lunii. Le produit est plutôt bon, mais relativement fragile (j'ai déjà remplacé le bouton) et ajouter des histoires est assez coûteux.
J'avais déjà réalisé une radio pouvant lire des fichiers MP3 avec un ESP32, je me suis donc mis au travail pour concevoir une boîte à histoires de mon crû. Elle doit posséder les caractéristiques suivantes
- Être simple à utiliser par un très jeune enfant (à partir de 2 ans)
- Être robuste, le soin apporté aux jouets n'étant généralement pas leur qualité première (en tout cas pour ma petite fille)...
- Pouvoir accueillir un nombre d'histoires assez important (au moins 100)
- Être extensible, ajouts d'histoires simple.
- Avoir un volume maîtrisé pour ne pas massacrer les oreilles, que ce soit sur haut-parleur ou au casque.
- Être alimentée par batterie, avec une durée de vie suffisante (au moins 8 à 10 heures) pour les longs voyages.
- Être d'un coût raisonnable (en tout cas moins cher qu'une Lunii à 70€)
Matériel
L'électronique est basée sur une carte ESP32.
J'ai choisi une carte LOLIN D32 Pro. Ces cartes sont de bonne qualité, et le modèle PRO possède un processeur ESP32-S2 qui permet le décodage MP3 même à débit élevé (par forcément nécessaire). La carte accueille en outre un port TF pour mettre une carte SD et un port de charge de batterie. Comme tout ESP32, le Wifi est bien sûr intégré. La carte possède aussi du Bluetooth mais ce n'est pas utilisé ici.
L'ESP32 est donc capable de décoder en temps réel un flux MP3, stéréo même si ici ce n'est pas utilisé. La sortie s'effectue via une des 2 interfaces I2S présente sur l'ESP. Un petit circuit MAX98357 se charge de l'amplification.
Liste matériel
Voici la liste des différents composants électroniques
- LOLIN D32 pro V2 : https://fr.aliexpress.com/item/1005006753478059.html, la version 2 possède l'ESP32 S2 avec 8Mo de flash plus la RAM SPI nécessaire pour le décodage de flux haute qualité. Les flux M4a sont par exemple prise en charge.
- MAX98357 : ampli I2S 3W. https://fr.aliexpress.com/item/1005006209483760.html Ampli 3W sur 4 ohms, largement dimensionné !
- Prise Jack femelle châssis : https://fr.aliexpress.com/item/1005006501723152.html Il faut choisir une prise stéréo les casques étant stéréo avec coupure du signal si branché.
- Haut Parleur : https://fr.aliexpress.com/item/1005006827350927.html . J'ai choisi un HP de 50mm de diamètre, si vous prenez un diamètre différent il faudra modifier le boîtier.
- Batterie 18650 : Vous pouvez choisir n'importe laquelle, et l'acheter au Fablab par exemple.
- Interrupteur avec voyant : https://www.amazon.fr/QUARKZMAN-Interrupteur-Bouton-Poussoir-Verrouillage-Diam%C3%A8tre/dp/B0D69PXVTD/ref=sr_1_4
- Résistance à ajuster pour le casque : environ 220 ohms
- Résistances pour détection charge : Environ 100 K ohms, chacune. Le but est de diviser par 2 la tension USB pour rester en dessous de 3.3V
- Prise USB C : https://fr.aliexpress.com/item/1005008299457563.html
- Contacts pour batterie : https://fr.aliexpress.com/item/1005005388896399.html
- 3 rondelles pour les touches. J'ai pris des rondelles "basiques" de 18mm extérieur, il faut que cela rentre dans les trous du boîtier... Il vaut mieux prendre des rondelles nickelées, plus faciles à souder que les rondelles inox.
Électronique
Le schéma est ci dessous sous forme d'image, le fichier KiCAD source est dans l'archive
Le câblage ne pose pas de grosses difficultés, il faut néanmoins être soigneux, ne pas utiliser des fils trop longs car la place finale est réduite.
Attention également, éviter de souder dans la boîte, le PLA supporte très mal la chaleur du fer à souder.
Pour la prise Jack, il faut faire attention au brochage, elles peuvent être différentes de celle utilisée chez moi. L'idée est bien sûr de couper le haut parleur quand le casque est branché. La résistance en série avec le casque devra être ajustée en fonction du casque. Avec un premier casque la valeur était de 1K, avec le casque en photo sur l'image de titre ce n'était plus que 270 ohms.
Boîtier
Le boîtier est réalisé en PLA. J'ai utilisé deux couleurs différentes, une pour le corps du boîtier (dessus), une autre pour les touches et l'arrière du boîtier. Il faut absolument une couleur différente pour les touches, sinon vous ne les verrez pas ! Pour ma petite fille l'avant est rose! Et je ne suis pour rien dans le choix de la couleur.
La conception a été faite avec FreeCAD, le fichier est bien sûr disponible dans l'archive.
Il comprend outre le boîtier lui même des modèles des divers composants utilisés.
La partie un peu spéciale concerne les touches qui sont "intégrées" au boîtier. Il y a une couche unique de plastique pour les touches. L'impression est ensuite arrêtée après cette couche. Puis on repart avec une nouvelle impression du boîtier lui même après avoir changé le filament.
Voici la marche à suivre pour imprimer les touches
- 1 Charger le fichier Boitierv2Dessus+Touches dans votre slicer. Personnellement j'utilise Prusa Slicer.
- Retourner le tout pour avoir la face avant sur le plateau
- Trancher (sans support)
- Indiquer au slicer de s'arrêter après UNE couche pour changer de couleur (soit à 0.4 mm)
- Exporter le fichier gcode sur l'imprimante, ce sera le premier fichier à imprimer.
- 2 Charger le fichier BoitierV2Dessus dans le slicer, le retourner également
- Trancher sans précaution particulière.
- Exporter le fichier gcode, il faudra ensuite imprimer ce fichier.
- 3 Impression des touches
- Lancer l'impression avec la couleur choisie pour les touches
- Quand l'imprimante indique changement de couleur, abandonner l'impression en cours !!!
- Changer le filament.
- Puis charger le second fichier gcode et l'imprimer. La boîtier est imprimé sur la petite surépaisseur des couches, cela se passe très bien.
C'est la procédure avec mon imprimante (PRUSA) je suppose qu'il existe l'équivalent pour d'autres marques d'imprimante.
J'ai tout imprimé avec une hauteur de couche de 0.2mm, mode speed sur la PRUSA (mais qui est quand même lente!)
Les différentes pièces à imprimer
Les 4 corps présents dans la pièce "part" boîtier sont à imprimer.
- Les touches à lier avec le dessus pour être sur du même calage sur l'imprimante. Le fichier .amf résultant est présent dans l'archive.
- La partie dessus
- La partie dessous
- Le cache touches. C'est une pièce optionnelle que l'on vient coller au dessus des rondelles qui forment les touches. Cela évite éventuellement certains accidents. Dans ma première version moins solide, ma petite fille 'brise tout' avait fait tomber la boîte assez violemment ce qui avait décollé la batterie qui avait ensuite décollé les touches dans la boîte qui s'étaient ensuite baladées dans la boîte ce qui avait fait un court circuit sur l'ESP 32, le grillant définitivement !
Dans la version actuelle tout est tenu avec des vis, plus de colle, sauf pour le cache touches. Pour coller le PLA j'utilise de la super glue, cela fonctionne bien, mais attention c'est assez long à coller. Comptez plusieurs minutes.
Pour les vis j'utilise des petites vis auto taraudeuses de 2x5 ou 2x6mm.
La batterie et le haut parleur sont maintenus par l'arrière du boitier.
Les touches
L'ESP 32 possède des capteurs capacitifs que j'ai voulu tester. Par défaut cela me semblait intéressant car très résistant. Le capteur lui même est une simple rondelle de 18mm de diamètre (trou de 6 mais aucune importance) sur lequel on soude un fil rejoignant l'ESP. Au niveau du boîtier, la face avant est un peu plus fine à cet endroit (1mm) au lieu de 3mm,la sensibilité est bonne.
A la première utilisation les touches doivent être calibrées. Sur le port série, l'ESP indique la marche à suivre pour la calibration de chacune des touches. Cela se fait en 3 étapes
- Ne PAS appuyer sur la touche, détermine le seuil OFF
- Puis appuyer de manière continue sur la touche, détermine le seuil ON.
- Puis faire quelques tests à votre convenance (pas obligatoire).
Les seuils sont stockés dans la mémoire non volatile de l'ESP, il n'est donc pas nécessaire de refaire la manip. Si l'utilisation des touches s'avère problématique voir ci dessous la partie interface réseau et relancer une calibration via l'interface TELNET. Les seuils peuvent aussi être ajustés finement via l'interface Telnet.
Logiciel
J'ai utilisé Visual Studio Code et platformio pour développer le projet.
Le fonctionnement est relativement simple. Après démarrage le processeur vient tester la carte SD pour compter les histoires présentes.
Ensuite il émet un son pour indiquer son démarrage.
Pour lire une histoire, il faut appuyer sur la touche Play/Pause. La touche FWD permet de passer à l’histoire suivante, la touche BACK permet de revenir à l'histoire précédente. Les histoires sont lues aléatoirement, mais la boîte se "rappelle" des dernières histoires lues pour y revenir. De même, le générateur aléatoire évite de revenir aux dernières histoires lues.
A la fin d'une histoire, elle passe automatiquement à une nouvelle histoire, mais ceci est configurable via l'interface Telnet (ou bien sûr dans le code).
Le projet utilise un certain nombre de bibliothèques. Elles sont incluses dans le fichier platformio, pas besoin d'aller les chercher.
- ESP32AudioI2S pour la partie AUDIO.
- ESPTelnet pour Telnet
- ESP_FTPServer_SD pour le serveur FTP
Réglage du volume
J'ai choisi volontairement une manière de régler le volume complexe que l'enfant peut difficilement mettre en œuvre. En effet avec sa Lunii, ma petite fille avait toujours tendance à écouter très fort (trop fort). Pour régler le volume, il faut appuyer pendant 20s sur la touche PLAY (sans interruption). La boîte entre alors dans le mode changement de volume (elle le dit). IL faut alors régler le volume avec les touches FWD (plus fort) et BACK (moins fort) tout en maintenant PLAY appuyé. A chaque appui, le nouveau volume est lu. Quand le volume recherché est atteint, relâcher la touche PLAY pour revenir au fonctionnement normal.
Batterie et charge batterie
La boîte incorpore une batterie Li-Ion 18650. Lors d'un test, la batterie à durer pendant environ 40h en fonctionnement avec le Wifi allumé, cela devrait durer au moins 50 heures en fonctionnement normal, dépendant évidemment de la qualité de la batterie. Quand la batterie commende à être déchargée la boîte le dit. Si elle est très déchargée, un second message est lu. Il faut alors recharger rapidement car après quelques minutes la boîte se coupe pour protéger la batterie.
Quand la prise USB de charge est connectée, la boîte le détecte et émet un message vocal. Attention, le câblage du circuit de charge impose que l'interrupteur soit enfoncé (allumé) pour charger la batterie, le message lu l'indique. La boîte fonctionne avec l'USB branché mais ne charge PAS la batterie si l'interrupteur est coupé.
Quand la charge est suffisante, un nouveau message vocal l'indique.
Interface réseau
La boîte est accessible en Wifi pendant quelques minutes (10mn par défaut) après démarrage. Ceci pour éviter de vider trop vite la batterie, mais cette période est configurable.
Elle a pour nom Histoire.local
Pour la première connexion à votre réseau, le code utilise le WPS. Lancer la recherche WPS sur votre box/routeur immédiatement avant ou après le premier démarrage. Ensuite, la boite mémorise vos informations de connexion. Attention, elle ne mémorise qu'un seul SSID (le dernier) si vous changez de lieu il faudra refaire la manip.
Si pas de connexion après 3'30 le Wifi se coupe. Pendant la recherche de réseau, la LED du bouton arrêt marche clignote rapidement, elle prend un rythme plus lent après connexion. Quand le Wifi se coupe, elle reste allumée fixe.
Quand vous changez de lieu, la boîte va chercher à se connecter au Wifi précédent pendant environ 30s et passe ensuite en mode recherche WPS. Cela se remarque avec le clignotement de la LED.
Serveur FTP
Pour charger les histoires, elle incorpore un serveur FTP (non protégé) sur le port 21. Les logiciels modernes ont du mal à accepter les FTP non cryptés mais ceci est encore possible notamment avec Filezilla. Ne pas tenir compte des messages d'avertissement. Le processeur n'est pas assez puissant pour un FTP crypté, le transfert FTP est déjà assez long comme cela !
La carte mémoire choisie est de 4Go, c'est largement suffisant pour un grand nombre d'histoires (environ 70 H!)
Attention, j'ai eu certains soucis en remplaçant des fichiers déjà présents. Cela a toujours fonctionné en ajoutant des fichiers mais le remplacement semble avoir un bug... Je n'ai pas creusé le serveur FTP ou l'interface SD pour savoir où était le coupable !
Le nom d'utilisateur/mot de passe ftp est thierry/thierry ! C'est super "secure". En ligne de commande ftp thierry@Histoire.local
Mode "ligne de commande"
J'ai également ajouté une interface Telnet pour piloter la boîte (mode utilisateur très averti...). Cela permet de configurer la durée Wifi, le fait que les histoires s’enchaîne ou pas....
Au moment de la construction, cela peut également être utilisé pour calibrer les touches.
L'interface Telnet est également utilisée pour sortir des messages d'état en gros équivalents à ceux présent sur le port série USB.
Faire telnet Histoire.local dans un terminal (Linux ou Windows) et vous avez accès à un mode ligne de commande TRÈS simplifié. Voici une petite liste des commandes disponibles, par ordre alphabétique, pas par ordre d'intérêt !
- bat : indique le niveau de la batterie.
- bye : déconnecte Telnet. Ensuite le Wifi se coupera après 30s
- cal : lance la calibration des touches (voir partie touches).
- clearnvs : le logiciel utilise la mémoire non volatile de l'ESP pour stocker les paramètres devant rester valides après arrêt. Cette commande efface tout réinitialise la boîte. En gros "Reset usine"
- cont 0|1 : force le mode lecture continu des histoires (si 1) ou pas (0). Si ce mode n'est pas activé, la lecture s’arrête à la fin de chaque histoire. Pour passer à une autre histoire appuyez sur PLAY ou FWD.
- forceWPS : force une recherche WPS. Fait un Reset sur la boîte et lance la procédure WPS au démarrage.
- pad : donne le seuil des 3 touches tactiles.
- pad OK 78 : force le seuil de la touche PLAY à 78. Dans la pratique il vaut mieux utiliser la procédure de calibration. Les valeurs possibles pour les seuils vont de 0 (ne sera JAMAIS détecté) à 127. Dans mon cas, les seuils étaient autour de 80, mais il y avait des différences notables entre les touches.
- pad FWD 79 : force le seuil de la touche FWD à 79.
- pad BACK 82 : : force le seuil de la touche BACK à 82.
- play 14 : lance la lecture de l'histoire 14
- ping : rien d'utile, réémet seulement pong pour vérifier la connexion telnet
- rst : relance la boîte.
- stop : arrête la lecture de l'histoire courante
- timeout : imprime la durée du timeout wifi en s.
- timeout 888 : fixe le timeout Wifi à 888s. Il doit être positif et inférieur à 1 000 000 de secondes soit plus de 11 jours !
- usb : indique le statut de la prise USB (branché ou non)
- vol : indique le niveau courant du volume.
- vol 15 : fixe le niveau du volume à 15. Les valeurs admissibles sont entre 1 et 22
Chargement du programme
Pour la première programmation du LOLIN, utiliser l'interface USB bien sûr. Ensuite vous pouvez utiliser le mode OTA (Over The Air) qui permet de charger le logiciel à distance. Bien pratique quand la carte est dans la boîte fermée !
Voir dans le fichier platformio.ini, mais la boîte s'appelle Histoire.local et le mot de passe est Thierry (attention à la majuscule !). Attention le nom utilisé pour l'OTA doit être identique à celui utilisé par mDNS car le logiciel OTA écrase l'autre nom
Avec platformio, quand on envoie le logiciel à la carte il essaie les deux cibles.
Les histoires
J'ai choisi de séparer le titre de l'histoire elle-même. La boîte lit d'abord le titre puis passe automatiquement au contenu après environ 1s. Cela permet de choisir plus vite l'histoire si l'une d'entre elles ne convient pas.
Chaque histoire est donc composée de 2 fichiers .MP3.
- Le premier nommé Txxx.MP3 contient le titre de l'histoire
- Le second nommé Hxxx.MP3 contient l'histoire elle-même.
La chaîne xxx est un nombre entre 001 et 999, la boîte permet donc d'avoir jusqu'à 999 histoires.
Attention la carte SD sur l'ESP n'est pas hyper rapide, avec beaucoup d'histoires la recherche dans le répertoire peut mettre un peu de temps gênant la réactivité du produit. Avec 100 histoires, aucun souci n'est à noter.
Les histoires sont à placer dans le répertoire Stories. Les autres fichiers présents dans le répertoire racine sont les messages qui sont lus par la boîte lors du fonctionnement.
Pour trouver les histoires, à vous de jouer. Il existe certaines histoires libre de droit sur le NET.
J'en ai sélectionné quelques unes que j'ai placées dans le répertoire Stories de l'archive. A vous de les utiliser ou pas !
Attention au niveau si vous récupérez des histoires sur Internet, le niveau peut être très variables. Un ajustement avec Audacity peut s'avérer nécessaire pour ne pas avoir de fortes variations entre histoires !
Archive
Voici l'archive qui devrait permettre de réaliser la votre.
C'est évidemment libre de droits, sans licence particulière au moins pour la partie dont je suis l'auteur. Pour les reste (les bibliothèques logicielles) merci de respecter la licence de l'auteur.
Dans l'archive, il y a une documentation utilisateur qui donne des détails supplémentaires sur l'utilisation de la boîte.