On a récemment acheté un agitateur magnétique chauffant contrôlable à distance grâce à un port RS232. Malheureusement le fabriquant a semble-t-il oublié de documenter le protocole de communication et quand on s'en est aperçu il était trop tard. Pas grave, c'est l'occasion idéale de vous montrer comment contourner le problème avec un Yocto-RS232.
Un agiteur chauffant magnétique est, en gros, une plaque chauffante capable de touiller toute seule à l'aide d'un aimant qu'elle fait tourner dans le récipient qu'elle chauffe.
L'agiteur fait tourner un aimant dans le liquide pour le mélanger.
L'agitateur en question est un AG802 vendu sous la marque LMR. Cependant, une rapide recherche sur internet permet d'établir qu'il s'agit en fait d'un modèle générique vendu sous différentes marques mais fabriqué par DragonLab instruments sous la référence MS-H-Pro.
L'agiteur MS-H-Pro de DragonLab, a.k.a. AG802
On a donc acheté cet agitateur bon marché pour son port RS232, Pas de chance, le mode d'emploi ne décrit pas le protocole utilisé pour contrôler l'agitateur et le revendeur a été incapable de nous aider. On a bien essayé de contacter DragonLab pour leur demander des précisions, mais ils n'ont pas daigné répondre. En revanche une application de contrôle, StirrerPC est fournie. C'est un bon point de départ pour essayer de comprendre comment fonctionne le protocole de contrôle à l'aide d'un Yocto-RS232.
Le soft de contrôle fourni par DragonLab
Yocto-RS232 et snooping mode
Il se trouve que le Yocto-RS232 dispose d'une petite fonctionnalité intéressante: il peut fonctionner en mode analyseur et afficher le contenu des communications qui transitent sur un câble série. Pour cela on intercale un petit adaptateur sur la connexion, on branche le Yocto-RS232 sur cet adaptateur. On configure le Yocto-RS232 en mode snopper et le tour est joué.
L'adaptateur pour analyser les communication RS232 avec un Yocto-RS232
L'adaptateur est question est vendu tout fait par Yoctopuce sous le nom RS232-Snooping-Adapter, mais vous pouvez aussi le fabriquer vous même: il ne contient pas d'électronique. Vous trouverez le schéma de câblage dans la doc du Yocto-RS232.
Le Yocto-RS232 peut analyser une communication RS232
Une fois le Yocto-RS232 connecté, il suffit de le configurer avec le VirtualHub. Contrairement à ce qu'annonce la doc du AG802, le protocole est du binaire à 9600 bauds, 8N1 et non pas 7N1. Ne pas oublier de mettre le Yocto-RS232 en mode Snooping.
Configuration du Yocto-Rs232 en mode snooper
Une fois que tout est configuré correctement, le Yocto-RS232 enregistre dans sa mémoire interne tout ce qui passe sur le cable série. Il est possible de consulter les données enregistrées à l'aide de l'API, mais le moyen le plus rapide consiste à utiliser le VirtualHub. L'URL http://127.0.0.1:4444/bySerial/serial/rxmsg.json?dir=2 permet d'afficher le contenu complet des buffers du Yocto-RS232. Par exemple si le numéro de série du Yocto-RS232 est RS232MK1-33E7F:
http://127.0.0.1:4444/bySerial/RS232MK1-33E7F/rxmsg.json?dir=2
Décodage du protocole
Une fois que tout est en place, il suffit d'effectuer quelques actions de base avec l'application fournie par DragonLab. En modifiant un seul paramètre à chaque fois et en observant comment les données transitant sur le câble en sont affectées, on peut essayer de comprendre ce qu'il se passe.
Consignes
Par exemple si on demande a l'application de lancer l'agitateur avec la consigne 63 °C et 255 tours par minute, on observe la communication suivante:
=>FE =>B1 =>00 =>FF =>00 =>B0 <=FDB1000000B1 =>FE =>B2 =>02 =>76 =>00 =>2A <=FDB2000000B2
On remarque que l'application envoie ses commandes sous la forme de paquets de 6 bytes. On a remarqué que ces bytes sont envoyé très lentement: environ un byte toutes le 50ms. On a découvert plus tard la raison: si on essaye de les envoyer plus vite, l'agitateur plante. Après quelques essais avec des valeurs de consigne différentes, on a déterminé que les paquets ont la forme suivantes:
offset | valeur | taille | signification |
---|---|---|---|
00 | 0xFE | 1 | entête de paquets |
01 | 0xB2 | 1 | commande |
02 | 0xXXXX | 2 | valeur de température en 1/10 de degrés encodé sur deux bytes,
par exemple: 63°C -> 630 -> 0x0276 -> 0x02,0x76 |
04 | 0x00 | 1 | inconnu, toujours zéro |
05 | 0xXX | 1 | checksum : LSB de la somme des bytes 1 à 4 |
Les paquets pour la consigne de vitesse d'agitation sont très similaire: la commande est 0xB1 et la vitesse est encodée directement, par exemple une vitesse de 255 t/min est encodée 0x00 0xFF. L'agitateur confirme chaque commande avec un paquet de six bytes.
offset | valeur | taille | signification |
---|---|---|---|
00 | 0xFD | 1 | entête de paquet |
01 | 0xB2 | 1 | commande |
02 | 00 | 1 | inconnu, toujours zéro |
03 | 00 | 1 | inconnu, toujours zéro |
04 | 00 | 1 | inconnu, toujours zéro |
06 | 0xXX | 1 | Checksum : somme des bytes 1 à 4 cad commande |
Apparemment , il n'y a pas de commande explicite pour arrêter l'agiteur: Lorsque qu'on clique sur le bouton stop: le soft de DragonLab se contente de répéter les dernière consignes et l'appareil s'arrête. Un choix de design un peu étrange.
Décodage des paquets de monitoring
On aussi découvert que l'application envoie à intervalle régulier des paquets qui servent à connaitre l'état de l'agitateur, ainsi on voit régulièrement passer le paquet suivant: 0xA2,0x00,0x00,0x00,0xA2 et la réponse a le format suivant:
offset | valeur | taille | signification |
---|---|---|---|
00 | 0xFD | 1 | entête de paquet |
01 | 0xA2 | 1 | commande |
02 | 0xXXXX | 2 | consigne de vitesse en rpm |
04 | 0xXXXX | 2 | vitesse réelle en rpm |
06 | 0xXXXX | 2 | consigne de température en dixièmes de degrés |
08 | 0xXXXX | 2 | température réelle en dixièmes de degrés |
0A | 0xXX | 2 | checksum : LSB de la somme des bytes 1 à 9 |
On a aussi observé le passage d'un autre paquet 0xA1,0x00,0x00,0x00,0xA1 qui permet de connaitre les paramètres de l'agitateur. La réponse a le format suivant:
offset | valeur | taille | signification |
---|---|---|---|
00 | 0xFD | 1 | entête de paquet |
01 | A1 | 1 | commande |
02 | 03 | 1 | mode : 0x01=A, 0x02=B , 0X03=C |
03 | 0xXX | 1 | stirring : 0x01=off 0x00=on |
04 | 0xXX | 1 | heating : 0x01= off 0x00=on |
05 | 0xXXXX | 2 | sécurité temperature résiduelle en dixièmes de degrés. |
07 | 0xXX | 1 | sécurité température résiduelle: 0x01=on, 0x00=off |
08 | 00 | 1 | inconnu, toujours zéro |
09 | 0xXX | 1 | sécurité barreau magnetique : 0x01=on, 0x00=off |
0A | 0xXX | 1 | checksum : LSB de la somme des bytes 1 à 9 |
Paquets d'initialisation
On a remarqué qu'au démarrage, l'application envoie 16 paquets, [0xFE,x0A3,0x00,0xXX,0x00,checksum] avec 0xXX prennat les valeurs 0x00 puis 0x10 à 0x1F. Apparemment cela sert à récupérer une chaine de caractères contenant le modèle d'agitateur. La transaction a le format suivant:
Paquet | Réponse | signification |
---|---|---|
FEA0000000A0 | FDA0000000A0 | \0 |
FEA3001000B3 | FDA34D0000F0 | M |
FEA3001100B4 | FDA3530000F6 | S |
FEA3001200B5 | FDA32D0000D0 | - |
FEA3001300B6 | FDA3480000EB | H |
FEA3001400B7 | FDA32D0000D0 | - |
FEA3001500B8 | FDA3500000F3 | P |
FEA3001600B9 | FDA372000015 | r |
FEA3001700BA | FDA36F000012 | o |
FEA3001800BB | FDA3000000A3 | \0 |
FEA3001900BC | FDA3000000A3 | \0 |
FEA3001A00BD | FDA3000000A3 | \0 |
FEA3001B00BE | FDA3000000A3 | \0 |
FEA3001C00BF | FDA3000000A3 | \0 |
FEA3001D00C0 | FDA3000000A3 | \0 |
FEA3001E00C1 | FDA3000000A3 | \0 |
FEA3001F00C2 | FDA3000000A3 | \0 |
Conclusion
Grâce au Yocto-RS232, et son mode snooping, on a pu "reverse-engineerer" le protocole série entre l'application fournie par DragonLab et l'agitateur. On va donc maintenant pouvoir écrire une petite librairie permettant de piloter l'agitateur avec un Yocto-RS232. Malgré l'absence de documentation, on a réussi à retomber sur nos pattes, mais on notera cependant que le reverse-engineering ne permet de reconstruire que les commandes que l'on peut voir passer sur le câble, il est probable que l'agitateur accepte d'autre commandes, mais il est impossible de les deviner.
Vous devez probablement vous demander ce que Yoctopuce compte faire avec un agitateur magnétique chauffant, mais ça vous le saurez la prochaine fois...