05
févr.
'21

Interphones sans-fil, comment que ça n'avance pas

Publié le 05 février 2021

L'année 2021 démarre plutôt bien, et j'ai profité des premiers lives Twitch de l'année pour continuer la bidouille de minitels mais aussi pour tenter de convertir deux anciens téléphones à cadrans rotatifs en interphones sans-fil. Tandis que la modification des minitels suit son cours (je viens tout juste de souder le connecteur du clavier du Minitel), la conversion des vieux téléphones en interphones sans-fil se révèle plus problématique que prévu. Petit point rapide dans ce billet des soucis rencontrés, des solutions testées, et de l'avenir de ce projet.

Des interphones sans-fil ?

Revenons deux minutes à l'origine de ce projet. On trainait en famille dans un vide-grenier (oui, à l'époque où c'était encore possible) et je suis tombé sur un de ces vieux téléphones à cadran rotatif, ce même type de téléphone que j'utilisais tout petit pour appeler mes grands-parents. Il faut avouer que composer le numéro à 8 chiffres -- dans cet ancien temps la numérotation n'était pas encore à 10 chiffres -- était vraiment amusant: on plaçait le doigt dans le numéro souhaité, puis on faisait tourner le cadran jusqu'en butée, et ce dernier revenait en position initiale en faisant un petit bruit de crécelle. Tout nostalgique que j'étais, j'en ai acheté deux exemplaires pour moins de 10€, avec en tête l'idée de les réhabiliter à la maison.

Dans un premier temps, on souhaitait s'en servir comme second téléphone fixe, mais il s'est avéré que la méthode de génération du numéro composé n'est plus supportée par les réseaux téléphoniques d'aujourd'hui. Le système de numérotation par impulsion de l'ancien temps ne peut donc fonctionner, et il est donc impossible de passer des appels avec ce type de téléphone. Du coup, pourquoi ne pas les transformer en interphones sans-fil ? Tant qu'à faire, autant intégrer de la modernitude dans ces vieilleries ! Et c'est d'un pratique pour appeler les enfants qui jouent dans la mezzanine pour leur demander de mettre le couvert, pardi 😇.

Exemple d'usage

Premiers essais, premiers échecs

Tout excité à l'idée de réaliser ce projet (on était en 2020 à ce moment là), je teste dans un premier temps si les micros et les hauts-parleurs des téléphones fonctionnent, ce qui est le cas. Puis je connecte un micro à une entrée analogique d'un arduino Nano, et je code un petit programme qui échantillonne le signal en provenance du micro (amplifié avec un module lm386, histoire d'avoir un niveau de signal suffisant) et le retransmet sur le haut-parleur, lui aussi couplé à un module d'amplification similaire. Et miracle, ça fonctionne ! Bon d'accord, le son est pourri, mais ça fonctionne !

La voix humaine varie entre 40 et 1500 Hertz (d'après Musimem), et l'arduino Nano que j'utilisais, cadencé à 16 MHz, ne peut pas échantillonner plus vite que 615 384 échantillons à la seconde, ou plus simplement 615 kHz. C'est plutôt pas mal, mais la résolution sonore est limitée car le convertisseur analogique/numérique (ou ADC) ne produit des valeurs que sur 8 bits au vu de la vitesse d'échantillonnage requise. Ceci dit, le résultat n'était pas trop mal !

Le souci avec un système de communication bi-directionnelle comme un interphone, c'est qu'il faut gérer en même temps la conversion du signal audio en provenance du micro en échantillons numériques, l'envoi de ces échantillons, mais aussi la conversion des échantillons numériques reçus en signal analogique à destination du haut-parleur. Ca veut donc dire faire plein d'autres choses que de l'échantillonnage de la voix, ce qui réduit la vitesse d'échantillonnage effective.

Avec ce premier test réussi, j'ai tenté l'implémentation d'un projet existant (Long Range Arduino Based Walkie Talkie using nRF24L01 [EN]) visant à transmettre de la voix sur du 2.4 GHz, mais sans succès. Comme je m'y attendais, l'arduino voit sa vitesse d'échantillonnage réduite et la piètre résolution du convertisseur analogique/numérique n'arrange pas la qualité sonore. En cherchant un peu plus, je me rends alors compte que je ne suis pas le seul qui s'est cassé la tête sur ce type d'usage, comme le démontre le retour d'expérience de GreatScott!! sur Hacakday [EN].

Il va falloir tester autre chose.

ESP32 à la rescousse (ou pas)

Vu que pas mal de mes connaissances m'ont parlé en bien des systèmes produits par Espressif et notamment la plateforme ESP32, je me suis demandé s'il était possible que ces derniers fassent l'affaire. J'ai pu expérimenter le développement sur ESP32 avec mon projet de smartwatch programmable (la vénérable T-Watch 2020 v1 de Lilygo), et je dois avouer que ça m'a bien bluffé. Je décidais donc de donner sa chance à l'ESP32, et commandais un ESP32 NodeMCU sur Amazon pour prototyper tout ça.

Prototypage des interphones lors du live Twitch

C'est à ce moment là (donc début 2021, si vous suivez) que j'ai commencé à prototyper sur ESP32 lors de lives sur Twitch, et les premiers résultats ont été assez satisfaisants. J'ai réussi à échantillonner le son du micro et à l'envoyer sur le haut-parleur, mais la qualité était juste horrible. Ceci dit, c'était encore acceptable. C'est quand j'ai commencé à interfacer l'ESP32 à un service accessible en WiFi que les choses se sont gâtées. L'envoi du son sur le service distant fonctionnait, mais d'une part la qualité n'était pas merveilleuse du tout, mais de la donnée était perdue et il y avait un décalage énorme (entre 5 à 10 secondes) entre l'échantillonnage par l'ESP32 et la transmission via WiFi.

Alors oui, l'ESP32 ça fonctionne bien, mais il a beaucoup de mal à réaliser en même temps la conversion du signal audio en échantillons numériques et la transmission de ces derniers. Et encore, c'était sans intégrer la convesion numérique/analogique pour la restitution du son sur le haut-parleur. Bref, ça devenait mal engagé. Certes l'ESP32 NodeMCU ne coûte pas bien cher, mais il souffre de plusieurs défauts.

Le premier défaut concerne la conversion numérique/analogique (DAC): la résolution du DAC interne de l'ESP32 est de 8 bits, on ne peut donc coder que des valeurs de 0 à 256, qui constitueront autant de "paliers" dans la tension de sortie et donc une imprécision dans le signal audio restitué. Surtout que la conversion analogique/numérique (ADC) ne souffre pas de cette limitation, la résolution étant de 12 bits. La réduction de 12 bits à 8 bits altère le son de manière significative, et impacte de fait la qualité de la communication. Le second défaut concerne l'électronique du NodeMCU: l'entrée analogique est parasitée par une alimentation du circuit un peu mal fichue, et par l'absence de quelques composants permettant de filtrer l'audio entrant. C'est aussi ce qui ressort des tests qu'a effectué atomic14 dans sa vidéo youtube [EN]: le son est parasité, la qualité sonore très dégradée, et sans prendre en compte la transmission via le réseau !

Encore un fail, mais bon ça m'aura permis de bien prendre en main le dev sur ESP32.

Alors, comment faire ?

Une des solutions possibles consiste à externaliser la conversion numérique/analogique et analogique/numérique, idéalement en employant des composants permettant d'échantillonner avec une bonne résolution (12 bits dans les deux cas), et fournissant un débit suffisant pour avoir une bonne qualité audio. On pourrait aussi envisager l'emploi d'un microphone I2S (qui fournit directement des échantillons numériques), mais je n'ai pas envie de perdre le grain du microphone du téléphone original.

La solution idéale pour le prototypage consiste à utiliser une carte adaptée, en l'occurence une esp32-lyrat-mini, compatible avec le framework esp-adf d'Espressif. Ce framework est dédié au traitement audio, et cette carte compatible intègre tout ce qu'il faut pour faire la conversion analogique/numérique et numérique/analogique via des composants externes. Elle intègre aussi des filtres adaptés, histoire d'avoir une meilleure qualité sonore. En bref, c'est vraiment une board faite pour cet usage. Comme un crétin, je ne pensais pas devoir en arriver là pour réaliser ce projet, mais je pense que je ne vais pas avoir d'autre choix. J'ai passé commande, on verra dans quelques semaines ce que ça donne 😀.

ESP32-Lyrat-Mini
09
déc.
'20

Attaquer du ZigBee pour moins de 10€ ? Yes we can !

Publié le 09 décembre 2020

to (Killer)bee or not to (Killer)bee

Je me suis récemment attaqué à la rétro-ingénierie du Ninja Badge de la DEFCON 18, et il se trouve que ce badge communique avec d'autres badges similaires via la couche MAC du protocole ZigBee (IEEE 802.15.4). Disposant d'un HackRF One, j'ai réussi à décoder les messages envoyés à l'aide de Gnuradio Companion, mais il m'était très difficile de coder un outil permettant de faire de l'envoi et de la réception en simultané, le HackRF One n'étant pas full-duplex. Il m'a donc fallu trouver un plan B.

Quand il s'agit de recevoir et de transmettre des paquets ZigBee, le framework Killerbee sauve pas mal la vie. Ce framework écrit en Python s'interface avec des équipements adaptés, et est en mesure de sniffer et injecter des paquets ZigBee. Enfin, quand on l'utilise avec des équipements qui le permettent. En effet, le seul device abordable qui était compatible avec ce framework est le RZ Raven d'ATMEL, dont la production a été arrêtée et qui est actuellement introuvable. Les équipements restants sont plus coûteux, comme l'ApiMote d'Attify (150$), le TelosB Mote, ou encore des cartes Silicon Labs compatibles (~300€). Par ailleurs, il existe bien un second équipement pas cher, une clé USB à base de TI CC2531, mais cette dernière ne supporte que le sniffing, ce qui ne me suffisait pas.

Une clé TI CC2531

J'ai donc commandé une de ces clés USB à base de TI CC2531, et j'ai réussi à capturer des paquets ZigBee et à débuter l'analyse du protocole de communication du badge. Cependant, impossible d'envoyer de manière fiable des paquets, et donc d'interagir avec ce dernier. Je commençais sérieusement à douter du framework, et songeais à trouver une solution alternative. Il était clair à ce moment que personne n'avait implémenté le support de l'injection de paquet pour cette clé USB, malgré plusieurs demandes faites via des issues sur leur repository Github. La réponse apportée ? "Do it yourself", si je résume le propos. Eh bien faisons ça alors.

Création d'un firmware pour le TI CC2531

Ayant déjà développé sur des puces gérant des communications radio dans le cadre de mes recherches sur le protocole Bluetooth Low Energy, développer un firmware spécifique pour la puce TI CC2531 ne me faisait pas tellement peur. Par contre, si je pouvais éviter d'y passer trois semaines, ça m'arrangerait passablement. J'ai donc commencé à scruter le web à la recherche de kits de développement permettant de développer pour cette puce, avec potentiellement le support de la couche radio déjà disponible. Je suis assez rapidement tombé sur le code de Contiki, un micro-système d'exploitation qui supporte notamment la puce en question. Et pour lequel la couche radio est déjà implémentée, yippie !

Je me suis donc lancé dans le développement de ce firmware, en ajoutant une couche de communication par port série (exposé via la connectique USB) afin de piloter la puce à partir d'un ordinateur qui communique avec le code gérant la radio. La structure de Contiki, qui propose un semblant de processus, permet d'implémenter cela de manière très simple. Le premier test a pu être rapidement effectué, et s'est montré très concluant: j'arrivais à sniffer et transmettre des paquets ZigBee, autrement dit j'avais une bonne base de travail. J'ai bouclé le développement du firmware en moins d'une semaine, et mis le code à disposition (ainsi qu'une release pré-compilée) sur mon repository Github associé.

Ajout d'un driver à Killerbee

Développer un firmware c'est bien, mais faire en sorte que Killerbee puisse communiquer avec est encore mieux. En parallèle, j'ai donc implémenté un driver spécifique dans le framework Killerbee, capable de communiquer avec le firmware en question et qui supporte ainsi le sniffing et l'injection de paquets. Ce développement a été effectué sur la branche py3 du projet, qui n'est pas encore la version 3.0 officielle de Killerbee mais qui devrait l'être une fois que le portage sur Python 3.0 sera terminé, grâce à la réactivité de RiverLoopSec qui a poussé des modifications en attente quand je les ai sollicité sur Twitter (encore merci à eux !).

Ce driver est ainsi capable de sniffer des paquets ZigBee, avec pour seule limitation que ces paquets doivent avoir un FCS (une somme de contrôle) valide (il est possible d'ajouter le support des paquets invalides, mais je ne l'ai pas encore fait). Il est par ailleurs capable d'envoyer des paquets, là encore sans possibilité de contrôler le FCS. Mais c'est bien suffisant pour ce que j'ai à faire sur ce matériel. Il a d'ailleurs fallu trouver un petit nom à ce firmware, et celui proposé par tartofraise lors d'un live Twitch a été retenu: Bumblebee.

Le code du driver est intégré dans mon fork de Killerbee, disponible en suivant ce lien.

Comment installer et utiliser Bumblebee ?

Le code source et une version pré-compilée du firmware ont été rendus publics sur mon dépôt Github associé, qui détaille par ailleurs plusieurs méthodes permettant d'installer ce dernier sur une clé TI CC2531. Basiquement, il vous faudra un programmateur CC-Debugger, ou un Raspberry Pi voire un Arduino. Une fois le firmware installé sur la clé, cette dernière est prête à l'emploi.

Sur l'ordinateur, installer killerbee à l'aide de l'outillage Python:

$ git clone --branch py3 https://github.com/virtualabs/killerbee.git
$ cd killerbee
$ python3 setup.py sdist
$ sudo pip3 install dist/killerbee-2.7.1.tgz

Killerbee est installé et prêt à l'emploi, y compris le support de Bumblebee. Vous pouvez désormais utiliser tous les outils classiques de Killerbee avec cette clé USB !

Si vous trouvez des bugs, ou souhaitez des améliorations, n'hésitez pas à soumettre des issues ou des feature requests, et pourquoi pas des pull requests !

22
sept.
'16

Super Minitel: suite et fin

Publié le 22 septembre 2016

J'en parlais récemment, j'ai profité de mon temps libre de ces dernières semaines pour apporter la touche finale à mon Super Minitel. Le résultat est plutôt probant, bien qu'il y ait des améliorations à apporter, à mon humble avis.

Ajout d'un support pour Raspberry Pi

J'ai ressorti mon bon vieux OpenScad afin de concevoir un support pour tenir le Raspberry Pi et sa carte d'adaptation vidéo/clavier dans le Minitel. J'ai opté pour une fixation par collage sur le Minitel, avec un espace pour laisser passer le connecteur de clavier. Le Raspberry Pi est fixé avec un vis, tandis qu'un ergot vient se loger dans le second emplacement de vis et empêcher tout mouvement.

Je l'ai ensuite imprimé sur ma Prusa i3, puis testé à blanc avec le Raspberry Pi. J'ai enfin monté le tout dans le Minitel, en prenant soin de maintenir l'ensemble avec des pinces serrantes. C'est franchement pratique ces pinces, j'ai découvert leur utilité grâce à Babozor et ses conseils de la Grotte du Barbu !

Après une nuit de séchage, j'ai pu fixer le Raspberry Pi dessus et tester le bon fonctionnement du clavier rétractable (qui passe du coup en dessous du Rasp).

Intégration du son

Après avoir commandé tout un lot de composants pour ajouter un ampli audio dans le minitel et les avoir soudé, j'ai pu tester le rendu. C'est pas trop mal, mais il y a un shhh de fond qui est plutôt gênant, ça doit être du au fait que mon ampli n'intègre pas de filtre ... Ceci dit en ajustant correctement le volume, on ne l'entend quasimment plus.

Pour la fixation, même recette que précédemment: j'ai conçu un support adapté au PCB (avec une seule vis pour la fixation, j'ai été radin), je l'ai imprimé et collé dans le Minitel.

Le rendu son n'est pas merveilleux, mais ça donne un bon vieux son old school, j'aime bien :). Pour terminer, j'ai conçu et imprimé un guide de perçage afin de faire des petits trous sur le côté du Minitel à l'endroit où se trouve le haut-parleur afin de laisser le son se diffuser.

Je l'ai imprimé, et je m'en suis servi de guide pour percer les trous sur le Minitel. Le rendu est très propre, et n'a nécessité aucun tracé particulier, juste la fixation du guide avec une pince auto-serrante.

Déco finale

S'il y a bien un domaine dans lequel je suis une quiche, c'est la déco. Je suis une bille en peinture, pochoirs, dessin, etc. Mais je ne voyais qu'une seule manière de décorer ce super Minitel: repeindre la carcasse en blanc cassé, et peindre un sigle «Super Minitel» au pochoir.

J'ai donc commencé par concevoir un pochoir sur Inkscape. En reprenant des polices de Nintendo et en bidouillant un peu, j'ai réussi à imprimer un motif noir sur blanc sur du papier photo. Après un petit tour chez Cultura pour acheter de la peinture en bombe et à pochoir, quelques babioles et de la colle repositionnable en spray, j'ai entamé à la main la découpe des caractères. Un bon gros fail. Peu de précision malgré l'utilisation d'un cutter très fin, et l'encre bavait sur mes mains. Il fallait trouver autre chose.

Je me suis rabattu sur l'impression 3D: en effet, quoi de mieux que d'imprimer un pochoir en 3D et de s'en servir pour peindre le motif ! C'était sans compter deux éléments importants pour des pochoirs. Le premier, c'est que lorsque l'on crée des pochoirs, on ne peut pas raisonnablement réaliser de belles lettres possédant des vides, comme les lettres P ou R. On est obligé de laisser une liaison pour que la partie masquant l'intérieur "tienne". Le rendu en est forcément moins bon. Second point, il doit être assez fin pour masquer et tenir correctement sur le support. Avec l'imprimante 3D, imprimer fin c'est imprimer pour rien. Lorsque l'on décolle le motif imprimé, il se plie et généralement cette déformation reste. C'est du plastique (PLA dans mon cas), donc assez difficile à reformer, et la colle repositionnable n'y a rien fait. Il ne me restait qu'à tester mon pochoir épais (1mm) afin de voir si le rendu serait correct.

Ma dernière erreur avec les pochoirs a été de penser que la colle repositionnable c'était LA solution. En réalité, elle a créé des petits points de colle sous le pochoir, et l'encre s'est enfournée sous le pochoir à cause de l'irrégularité de celui-ci et de l'espace vacant laissé par la colle en spray. Merci les tutos Youtube, mais cette fois-ci ça ne m'a pas aidé. heureusement que j'avais fait des tests sur carton et papier avant de me lancer sur le Minitel...

J'étais pas loin d'abandonner quand j'ai eu une idée toute simple: pourquoi ne pas imprimer les lettres avec l'imprimante 3D et les coller de façon jolie sur la carcasse du Minitel ? De cette façon, on obtient un effet de relief et un beau contraste blanc cassé/noir qui est du plus bel effet (enfin je crois). J'ai donc modélisé les lettres en convertissant le modèle SVG en SCAD (merci paths2openscad !) et les ai imprimé à l'envers pour que le côté lisse corresponde à la partie visible (de face) et donne un rendu moins "imprimante 3D". Le résultat est très probant je trouve.

j'ai ensuite placé les lettres, les ai collé et ai attendu que cela sèche. J'ai fait l'erreur de marquer l'alignement au crayon papier, et cela se voit encore un peu de très près, c'est dommage. Je prendrais une équerre pour le prochain exemplaire et ne tracerai aucun trait, cela sera plus propre.

Résultat final

Au final, j'ai un Super Minitel qui ressemble exactement à ce que je voulais, qui accepte jusqu'à deux manettes Super NES en USB (pratique pour Street Fighter, mais on peut aussi jouer grâce au clavier), et qui attire la curiosité avec son aspect "presque" Super Nintendo.

Je vais le beta-tester à la maison afin de déceler de potentiels défauts de conception avant de le donner à un généreux soutien du projet OpenIt, et d'en faire deux autres pour les deux autres soutiens ayant choisi cette récompense.

Il me reste encore quelques Minitels un brin différents à la maison, certainement l'occasion de me faire la main sur la soudure CMS à air chaud ;). Il me faut absolument un exemplaire à la maison, et les minis-moi auront obligation d'y jouer (vous en conviendrez: Super Mario World, Street Fighter II, Bomberman 3 et Worms sont des jeux formidables o/).

Ah et si vous voulez tenter de reproduire ce hack, j'ai mis des ressources à disposition (majoritairement les PCBs, les fichiers de conception 3D ainsi que le software permettant d'interfacer le clavier). Il manque encore des éléments (comme la liste des composants pour les PCBs, mais ça viendra -- il y aura peut-être des modifications suite au beta-test).



Les contenus disponibles sur ce blog sont publiés sous licence Creative Commons BY-NC-SA.
Vous pouvez réutiliser tout ou partie de ces contenus à condition de citer l'auteur et l'origine, vous ne pouvez en faire une utilisation commerciale, et enfin vous devez partager tout travail ou œuvre dérivée sous les mêmes conditions — c'est-à-dire avec la même licence d'utilisation Creative Commons.