Archives par mot-clé : MRF24J40MA

IEEE 802.15.4 avec MRF24J40, ST Nucleo et NuttX

Et non Zigbee, qui est une stack de protocole complète!

Il y a longtemps que ce protocole radio basse consommation me plait. Le fait qu’il soit un standard m’attire car il garantit une certaine interopérabilité entre les fabricants de chips.

Je m’intéresse pour l’instant au 802.15.4, qui est un peu l’Ethernet du Zigbee.

Il y a longtemps (OH SHI– en dec 2012) j’avais acheté une paire de modules Microchip MRF24J40MA, et j’avais essayé de les faire fonctionner avec des PIC18. Sans grand succès. La relecture de l’article vous donnera des détails sur le protocole et la ou j’en étais resté.

Depuis, j’ai beaucoup joué avec les ARM Cortex, et j’ai gagné pas mal d’expérience en programmation système. Je travaille quotidiennement avec le RTOS NuttX qui permet de développer facilement des apps embarquées, avec un framework très complet de drivers.

En mélangeant tout cela, j’ai rapidement pu développer un driver NuttX pour le MRF24J40. Le chemin a été long:

-le bus SPI du STM32F411 ne fonctionnait pas; il perdait le LSB des transmissions a cause d’un mauvais réglage du slew-rate

-les datasheets du MRF24J40 sont écrites avec les pieds… un peu comme toutes les docs Microchip, quoi… Donc pour les fonctions basiques pas de problème, mais pour les détails, il faut passer du temps sur le web, les forums Microchip, les exemples de code… pour arriver a tout faire coller

Hier j’ai pu me procurer un module haute puissance (MRF24J40MC, avec antenne extérieure). Et rebelote… Pour arriver a faire fonctionner correctement les amplis RF du module, il m’a fallu une journée complète, avant de réaliser que la config des amplis doit être faite beaucoup plus souvent que prévu!

Enfin bref j’ai pu tout faire coller et maintenant, ma carte Nucleo se comporte maintenant comme un couteau suisse ieee.

La détection d’énergie (scan passif) fonctionne, le secret pour un bon affichage est de ne pas afficher la valeur recue, mais de mettre a jour l’affichage si on recoit une valeur supérieure a la valeur actuelle, et sinon de faire baisser le signal recu “artificiellement”, exactement comme sur un vu-mètre audio. La raison est simple: les paquets sont si courts qu’il est rare d’en voir passer suffisamment pendant une simple mesure.

nsh> i8 /dev/ieee0 scan
IEEE packet sniffer/dumper argc=3

11 : [ 58] #######
12 : [104] #############
11 : [ 57] ####### 
11 : [ 61] #######   
12 : [ 89] ########### 
13 : [ 80] ##########
14 : [ 61] ####### 
15 : [145] ##########################           
16 : [190] #######################          
17 : [102] ############    
18 : [111] #############       
19 : [111] #############   
20 : [  0]                                       
21 : [ 55] ###### 
22 : [ 66] ######## 
23 : [ 26] ###                                  
24 : [  0]                                 
25 : [ 12] #                                 
26 : [ 46] #####

Bon c’est bien rigolo ca, mais le scan actif est bien plus intéressant. Il s’agit d’envoyer, sur chaque canal, des “beacon requests”, puis d’attendre les “beacons”, des paquets qui informent sur la présence d’un noeud réseau. Voici un exemple de sortie:

chan=13 rssi=138 lqi=117 len= 11 [6942/0100 -> none] FFCF000046344752582F30
chan=15 rssi= 41 lqi=116 len= 19 [507C/0200 -> none] FF0F000000228C2DFD01E0C8B656BEFFFFFF00
chan=25 rssi=  0 lqi=117 len=  6 [C513/4DD5 -> none] FF4F0000CE01

Le RSSI est le niveau de puissance recue (arbitraire, 0-255), le LQI la qualité de réception (pas forcément liée à la puissance), entre crochets on a les champs d’adressage 802.15.4 (les beacons ont une adresse source mais pas d’adresse de destination car ce sont des broadcasts), puis la payload MAC:

“FF” -> réseau sans structure temporelle (superframe)
“CF” -> options
“00” -> Pas de Guaranteed Timeslot
“00” -> Pas de pending address
(pour ce charabia, voir la spec 802.15.4, elle est dispo en téléchargement gratuit)

Ce qui suit est le champ d’infos de la balise, il peut contenir n’importe quoi. Il y a un format spécial pour Zigbee, que je ne connais pas encore; c’est probablement ce qui est utilisé sur le paquet du canal 15.

Le canal 13 est celui que j’ai utilisé pour mon prototype de coordinateur, qui utilise une autre carte Nucleo. La payload est définie a “46344752582F30”, C’est a dire “F4GRX/0”, maniere d’être identifiable si on me décode, comme tout bon radio-amateur doit le faire.

Conclusion

Je me suis bien amusé avec ce protocole. Le projet a été suspendu pendant longtemps, mais la persévérance a payé: les couches basses fonctionnent.

Je peux maintenant passer au codage du coordinateur ‘en vrai’. Le coordinateur est un peu le “point d’accès wifi”. Il sert de plaque tournante a des périphériques ieee a intelligence (et conso) réduite.

Le code sera bientot intégré dans le code principal du RTOS NuttX. En attendant, le code est consultable dans mon fork de nuttx sur BitBucket, dans la branche ieee:
git clone https://bitbucket.org/slorquet/nuttx
git checkout ieee

La sauce secrète est ici: https://bitbucket.org/slorquet/nuttx/src/72ff5be3ee257b385751d5678901aa9edb45a1f9/drivers/ieee802154/mrf24j40.c?at=ieee

Ce a quoi il faut ajouter ce fork des apps de base NuttX:
git clone https://bitbucket.org/slorquet/apps
git checkout ieee

Allez un jour je vous expliquerai comment faire fonctionner NuttX. Sachez déja que ce sera sous Linux, parce que c’est trop galère sous Windows.