[ Accueil ] [ CONTACT ] [ PLAN du Site ] [ RCNV ] [ Publications ] [ Chantiers Bateaux ] [ Technique Modélisme ] [ Electronique ] [ Radios Vintage ] [ Multi-Switch ] [ Vrac ] [ Astuces ] [ Liens ] [ Base ] [ Compteur ]
 

 

        ... rgl

 


 Le Transceiver nRF24L01+

Emetteur/Récepteur 2.4 Ghz



Contrôler le nRF24L01+ avec un Picaxe ou un AVR, programmés en BASIC

(c) Roger LEGAT jr

SOMMAIRE :

  1 -  Introduction - Présentation - Généralités

  2 -  Piloter le nRF24L01+ avec un MicroContôleur, en BASIC µC

  3 -  Les pins de contrôle du nRF24L01+

  4 -  Ecrire dans les registres du nRF24L01+

  5 -  Lire les registres du nRF24L01+

  6 -  Les RX "Pipes"

  7 -  Structure des Adresses_Pipes 

  8 -  Adressage multi-Pipes 

  9 -  Principes d'adressage TX / RX 

10 -  Dynamic Payload Length - DPL Mode

11 -  La gestion des IRQ (Interrupt Request)  par: IRQ Pin, CONFIG Reg. et STATUS Reg.

12 -  La Charge Utile (Payload)

13 -  Shockburst Enhanced Protocole 

14 -  Auto ACK et ajout d'une charge utile à l'ACK

15 -  Modes de fonctionnement

16 -  Emission d'une porteuse constante pour la phase de tests

17 -  Envoi et réception de messages Textes   

18 -  Les registres du nRF24L01+

19 -  Les FIFOs

20 -  Les Commandes du nRF24L01+

21 -  Programme TX.9 Complet Picaxe  (Transmission vers les 6 pipes du RX ayant des adresses personnalisées, Mode DPL, Message d'alarme et arrêt d'émission en cas de défaut récurrent de l'ACK,
                                                              Recherche et affichage d'un éventuel message joint par le RX à l'ACK, comptage des packets perdus, ...)

22 -  Programme RX.6 Complet Picaxe  (Réception dans les 6 pipes ayant des adresses personalisées, Mode DPL, adjonction d'un message à l'ACK retourné vers le TX, ...)

23 -  Canaux d'émission - Les interférences WiFi et Bluetooth

24 - Scanner le réseau WiFi   En cours ...

2x -  Tests et programmes de portée      A venir ...

2x -

2x -   

   Introduction - Présentation - Généralités

C'est avec grand intérêt que je me suis mis à étudier ce petit circuit impressionnant, durant plusieurs semaines, pour en comprendre les spécificités.
Il  s'agit donc d'un "transceiver", càd un module capable d'émettre mais aussi de recevoir des datas au format binaire avec la particularité que le récepteur dispose de 6 "Pipes" distincts.
Par "6 Pipes", il faut entendre 6 adresses de réception actives en même temps, par récepteur.  Ce circuit permet, entre-autres, la réalisation de réseaux en étoile constituées de plusieurs
Transceivers nRF24L01+
pouvant effectuer des relais de transmission pour en accroître les portées, par exemple.

Ce Transceiver peut envoyer, et recevoir, dans son registre RX_FIFO (First In, First Out), des données composées d'une charge utile (Payload) d'un maximum de 32 octets !
La notion de Payload (Charge utile) revient souvent dans la littérature du nRF24L01+ et représente, en fait, les datas que vous décidez d'envoyer au RX.
A ces datas, le nRF24L01+ va ajouter des bytes de contrôle: Adresse du RX_Pipe, Chaîne du CRC (Cyclic Redundancy Check), ...

Il gère un protocole d'ACK, incluant le CRC, permettant de s'assurer que les données transmises sont parfaitement arrivées dans le pipe du récepteur concerné.

Le nRF24L01+ travaille dans la gamme des 2,4Ghz et dispose de 128 canaux... dont seuls les 83 premiers sont légaux en Belgique.

On le trouve pour une pincée d'Euros sous diverses formes: depuis le petit module avec antenne gravée sur le PCB jusqu'à ceux disposant d'une antenne et même d'un ampli LNA
permettant une portée de l'ordre de 1.000m en terrain dégagé et une centaine de mètres en intérieur muré.

     

                                Modèle à antenne imprimée                                            Avec antenne de 11cm                      Module avec ampli RF LNA

Module avec ampli de 100mW - Portée dégagée annoncée: plus de  2000M - Ref: AS01-ML01DP5

                  

 
 

Radiocommande à nRF24L01  

Ce Transceiver me servira ensuite à l'étude et la réalisation d'un ensemble de radio-commande complexe pour
    mes grands modèles de bateaux navigants.
  Cette aventure sera bientôt présentée dans une autre page de ce site...

A noter que NORDIC Semiconductor produit également un module de la même famille (gestion de registres, ...) configurable en 433, 868 ou 915 Mhz !
Il s'agit du nRF905 !

Que choisir 433Mhz ou 2,4Ghz ?

Le 433 Mhz supporte mieux les réflexions, il est donc moins atténué par les obstacles. Sa bande passante est cependant réduite mais pour notre usage elle doit encore être plus que suffisante.
Ce ne serait pas le cas pour de la transmission audio et ... encore moins pour de la video.

A puissance égale, le 2,4Ghz a une meilleure portée et demande une antenne plus réduite.

Retenez surtout qu'en 2,4Ghz, pour établir une communication optimale, les ensembles TX et RX "doivent se voir" l'un et l'autre.
Traduisez qu'il ne faut pas d'obstacle physiques entre les modules émetteurs et récepteurs.
La fréquence 2,4Ghz est donc particulièrement bien adaptée pour nos modèles réduits que nous ne quittons jamais des yeux !

A l'occasion, je me pencherai, peut-être, sur le module nRF905 configurable en 433Mz ...

 

   Piloter le nRF24L01+ avec un MCU programmé en BASIC

    
      ARDUINO !    

Le Web regorge d'exemples et de programmes sources de ce module MAIS ... piloté par ... un MCU ARDUINO !
Le problème de ces sources ARDUINO
, outre le fait qu'elles sont écrites en C, est que ce MCU ARDUINO utilise des "bibliothèques", ne permettant pas,
en lisant le programme, de cerner clairement les opérations indispensables à effectuer sur le nRF24L01+ et ses registres.
En outre, ces bibliothèques généralement construites par la Communauté, ne sont pas toujours complètes et n'implémentent donc pas toujours l'ensemble des nombreuses et complexes possibilités du composant.
Enfin, la lecture du ou des fichiers "bibliothèque" n'est pas des plus aisée et nous laisse toujours à la merci d'un bug qu'il nous sera généralement difficile, voire impossible, de solutionner !

Pour ma part, je programme donc généralement mes MCU en "BASIC orienté µC" et je gère clairement chacun des paramètres indispensables.
La lecture d'un tel programme, structuré, qui ne fait appel à aucune bibliothèques externes permet ainsi à quiconque de comprendre, en détail, les diverses actions indispensables
et nécessaires pour configurer les nombreux registres du nRF24L01+, et gérer lisiblement les diverses commandes.
Vous en jugerez par vous-même à la lecture des programmes finalisés qui se trouvent tout en bas de cette page.

Après étude très complète du DataSheet, ma méthode me permet, en tous cas, de piloter le nRF24L01+ en pleine connaissance des effets attendus de ma programmation et
de rectifier immédiatement tout problème pouvant être constaté.

J'ai donc testé ce Transceiver sur deux plateformes différentes:
      - une plateforme PICAXE (Shield AXE401 de Picaxe équipée d'un Picaxe 28X2)
      - sur shield Arduino Uno et Nano, dont j'ai effacé le Boot-Loader de l'AVR. Je programme alors l'AVR ATMega-328P, nu, en "BASIC orienté µC" grâce au programme BASCOM et
         un programmateur AVR ISP MKII branché au connecteur ISP à 6 broches.
(Détails à venir)

Les résultats de contrôle issus des programmes d'émission et de réception sont lus sur l'écran du PC grâce à un "Emulateur de Terminal", du style Tera Term.
A noter que le programme Editeur de Picaxe intègre une option "Terminal" très complète.
Ce terminal affiche à l'écran de votre PC les données issues du port série du microContrôleur. Ceci est très pratique pour lire les message de DEBUG ou lire des informations données
à l'opérateur, par le système, durant le déroulement du programme. (Défaut ou fidélité de la transmission, Nombre de tentatives d'émission, ACK reçu ou non, nombre de bytes transmis/reçus/perdus, ...)

                        

Plateforme PICAXE 28X2 (AXE401 de chez Picaxe) à programmer en "BASIC MicroContrôleur"               Envers du shield compatible pour plateforme Picaxe ou Arduino (Nano ou Uno)
   A gauche, le shield du TX (Emetteur) et à droite le RX muni du câble de programmation
                                 et d'envoi des données vers le Terminal (écran du PC) 
      Derrière, on voit un support pour Arduino Nano dont j'effacerai le Boot-Loader pour
                     programmer l'AVR ATMega 328-P avec BASCOM, en "BASIC".
                            A l'arrière plan, les nRF24L01+ avec ampli RF LNA.

 

   Les pins de contrôle du nRF24L01+

Nous allons nous intéresser d'un peu plus près à ce fameux Transceiver nRF24L01+.

Il est pourvu d'un connecteur à 8 broches dont les spécificités sont reprises dans le tableau ci-dessous.

A remarquer que le nRF24L01+ est alimenté en 3,3V, bien que ses entrées acceptent, sans broncher, les signaux de 5V issus de nos microContrôleurs !

Une tension d'alimentation supérieure à 3,3V aura pour effet de faire sortir la quantité de fumée généralement stoquée dans chaque composant  ;)

Il faudra donc utiliser un petit adaptateur de tension comme celui représenté ci-dessous.

A noter aussi que si vous utilisez la broche 3,3V dont dispose le shield "type Arduino", il vous faudra placer un condensateur électrochimique de 10µF entre cette broche et la masse.
A défaut, d'aucun signalent des problèmes récurrents de transmission...

Il est ici largement recommandé d'utiliser une source d'alimentation de puissance suffisante, parfaitement stabilisée et correctement filtrée pour éviter tout parasite résiduel.

Enfin, vous aurez constaté que le protocole de transfert des données se fait sur un port SPI (Serial Peripheral Interface).

Par ce port, nous iront écrire, et lire, dans les nombreux registres du nRF24L01+.
Nous allons bientôt voir que cela n'a finalement rien de sorcier ...

    
Détail et fonctions des 8 pins du nRF24L01+

Convertisseur de tension 5V --> 3,3V

 

   Ecrire dans un registre du nRF24L01+

Le nRF24L01+ dispose donc de 26 registres nécessaires à sa configuration, sa gestion et ses contrôles.
Un TX_FIFO de 32 bytes et un RX_FIFO de 32 Bytes.
Il reconnait également 11 commandes spécifiques.
Le détail complet, comme l'utilité, de ces registres et commandes est édité un peu plus bas de cette page.

 1.   Ecrire des datas

Pour pouvoir envoyer des données avec le 24L01+ par le bus SPI, les choses doivent se faire dans l’ordre :

      -  CSN Low, et doit rester à l’état bas durant toute la durée de la transaction (Activation Bus SPI)

-             Envoyer l’octet de commande définissant la commande à exécuter (ici, Write Register = n°du registre +32)

-      Ajouter, dans cette même commande, le ou les octets à écrire dans le registre ciblé

-  CSN High (Désactivation Bus SPI)

 La commande  Write_Register , consiste à adresser le n° du registre en lui ajoutant la valeur 32 (décimal).

On fait ensuite suivre, dans la même commande Hspiout, le ou les octets à écrire dans le registre.

 

Exemple : envoi de 5 octets dans le registre TX_ADDR

 

Symbol Write_Tx_Addr = 48  'Address Reg= 16 +32 Dec

 

Low CSN  ' LSB First for RX_ADDR and all RX_ADDR_Pipes!

 Hspiout (Write_Tx_ADDR, Byte_0, Byte_1, Byte_2, Byte_3, Byte_4) '231, 194, 195, 196, 197

High CSN

 

Cette commande sera utilisée, notamment, en début de programme pour configurer les divers registres de fonction
  (Mode TX/RX, canal radio, puissance, adresse TX, ACK ou non, RX_ADDR_Pipes, …)

 

2.   Commandes d’écriture dédiées

 

Le nRF24L01+ dispose aussi de commandes d’écriture particulières qui ont une fonction spécifique.

 

2.1     W_TX_Payload

 

Ecriture, dans le TX_FIFO, des datas à transmettre

 

Symbol W_Tx_Fifo = 160    '%1010.0000   h.A0

 

'Write 5 bytes to TxFifo

Low CSN

 Hspiout (W_Tx_Fifo, TxByte1, TxByte2, TxByte3, TxByte4, TxByte5)

High CSN

 

 2.2     FLUSH_TX

 

Effacement des données du TX_FIFO (Mode TX)

 

Symbol Flush_TX = 225     '%1110.0001   h.E1

 

Low CSN

 Hspiout (Flush_TX)      'Only 1 command Byte

High CSN

 

 2.3     FLUSH_RX

 

Effacement des données du RX_FIFO (Mode RX)

 

Symbol Flush_RX = 226    '%1110.0010   h.E2

 

Low CSN

 Hspiout (Flush_RX)      'Only 1 command Byte

High CSN

 

 2.4     REUSE_TX_PL

 

Envoi de Packets aussi longtemps que CE est High (Mode TX)

 

Symbol R_TX_PL = 227 '%1110.0011   h.E3

 

Low CSN

 Hspiout (R_TX_PL 'Only 1 command Byte

High CSN

 2.5      W_ACK_PAYLOAD 

Commande particulière, et très intéressante, utilisée par un RX lui permettant de transmettre un paquet d'accusé de réception personnalisé au lieu des ACK de longueur nulle automatisés,
utilisés par défaut lorsque le bit EN_ACK_PAY du registre Feature est désactivé.
Le RX ajoute donc une charge utile au prochain ACK qui sera envoyé en réponse à un packet reçu sur le RX Pipe PPP (0 à 5).
Cette commande fonctionne de la même manière que W_TX_Payload sauf que vous devez spécifier le RX Pipe pour lequel vous voulez accuser réception avec cette fonction.

Notez que si EN_ACK_PAY est activé dans le registre Feature, TOUS les packets doivent être acquittés à l'aide de cette fonction.

Plus important encore:
Retenez que l'ACK Payload doit être préchargé AVANT que le TX n'envoie effectivement le Packet.
Conformément à la manière dont le SPI fonctionne, la procédure d'acquittement de la charge utile implique une transaction bi-directionelle dans laquelle les datas sont transmises
et reçues dans la même opération logique (
bien que la transmission de l'ACK PRX-> PTX survienne évidemment après la transmission de la charge utile PTX-> PRX).

 

Le message joint à l'ACK transmis par le RX pourrait être un message texte d'alerte, indiquant par exemple un problème de fonctionnement.
Dans le cas d'un système comprenant plusieurs TX/RX, ce genre d'information renvoyée vers le TX est particulièrement intéressant.
Un chapitre est consacré à la gestion des messages textes. (Voir ici)

 

  ATTENTION:  Le mode Dynamic Payload (DPL) doit être activé   --->(Voir Auto_ACK et ajout d'une charge utile à l'ACK)

 


EXEMPLE d'ajout d'un message texte à l'ACK du RX_Pipe2

 

Symbol W_ACK_Pld_P2 = 170  '%1010.1010   h.AA

 

Low CSN

 Hspiout (W_ACK_Pld_P2, "Ici RX Garage: Batteries faibles") '32 caractères Max !

High CSN

 

Ce message d'alerte sera émis par le RX, vers le TX qui vient d'émettre, dès que le RX_Pipe_2 recevra ses données.

Côté TX, on gèrera les drapeaux d'interruption du registre Status pour lancer une routine d'affichage de ce message ajouté à l'ACK reçu (RX_DR et TX_DS seront activés dans ce cas).
L'exemple de programme proposé plus bas reprend cette fonctionnalité.
Les bit1 et bit2 du registre Feature doivent être configurés.

 

 

2.6     W_TX_PAYLOAD_NOACK 

 

Désactivation de la demande d'ACK pour ce paquet transmis (Mode TX)

 

Symbol W_TX_PL_NOACK = 176 '%1011.0000   h.B0

 

Low CSN

 Hspiout (W_TX_PL_NOACK, TxByte1, TxByte2, TxByte3, TxByte4, TxByte5)

High CSN

Le bit0 du registre Feature doit être configuré.

 

   Lire dans un registre du nRF24L01+

Pour pouvoir recevoir des données avec le nRF24L01+ par le bus SPI, les choses doivent également se faire dans l’ordre :

 

      -  CSN Low, et doit rester à l’état bas durant toute la durée de la transaction (Activation Bus SPI)

-             Envoyer l’octet de commande définissant la commande à exécuter (ici, Read Register = n°du registre)

-      Récupérer le ou les octets du registre ciblé(s) dans une ou plusieurs variables

-  CSN High (Désactivation Bus SPI)

 

 

Dans le cas d’une lecture, la commande   R _REGISTER   consiste à simplement envoyer, sur le bus SPI, le numéro « pur » d’un des 26 registres du nRF24L01+ et d’ensuite récupérer
le ou les octets dans une ou plusieurs variables de traitement.;

 

 

Exemple : Lecture de 5 octets dans le registre RX_ADDR_P0

 

Symbol Rx_Addr_P0 = 10  'Address Reg= 10

 

Low CSN  ' LSB First for RX_ADDR and all RX_ADDR_Pipes!

 Hspiout (Rx-Addr_P0) 'Adressage du registre nr 10

 Hspiin  (Byte_4, Byte_3, Byte_2, Byte_1, Byte_0) ' Mise en variables des Bytes lus

High CSN

 

 

 1.   Commandes de lecture dédiées

 

1.1   R_RX_PAYLOAD

 

Lecture du contenu du buffer RX_FIFO (Mode RX)

 

Symbol R_Rx_Payload = 97   ‘%0110.0001   h.61

 

Low CE  'Receiver disconnected

Low CSN

 Hspiout (R_Rx_Payload)       ' Read Data in RX FIFO

 Hspiin (b10,b11,b12,b13,b14) ' Récupération de 5 octets dans 5 variables Byte

Low CSN

 

    1.2   NOP

 

Cette commande est un peu particulière car son envoi est utilisé pour ensuite lire le registre Status

 

Symbol NOP = 255         '%1111.1111   h.FF

 

Low CSN

 Hspiout (NOP)  'Only 1 command Byte

 Hspiin (b0)    'Récupération de l’Octet du Reg STATUS dans une variable Byte

High CSN

 

    Elle revient finalement à écrire :
 

b1 = 'STATUS

Low CSN
 Hspiout (b1)        'Adressage du registre à lire (1 Octet)

 Hspiin  (b0)        '1 Octet à récupérer

High CSN

 

1.3   R_RX_PL_WID 

 

Compte le nombre d'octes présents dans le RX_FIFO (Mode RX)

 

Symbol R_Rx_PL_WID =  96  ‘%0110.0000   h.60

 

Low CE  'Receiver disconnected

Low CSN

 Hspiout (R_Rx_PL_WID)  'Read number of Bytes in RX FIFO

 Hspiin (b1)            'Récupération dans une variable Byte

Low CSN 

 

   Adressage des RX_Pipes

      1.   Les RX_Pipes

On peut considérer que le nRF24L01+ dispose, côté récepteur, de 6 zones de réception adressables.

C'est un peut comme si le composant était constitué de 6 récepteurs distincts.

Chacune de ces 6 "zones" de réception sont appelées "Pipes".

Les  « Pipes » sont cependant une notion purement virtuelle puisqu’il n’existe réellement qu’un seul RX_Fifo de 32 Bytes et que l'émetteur n'utilise

qu'un même canal d'émission pour s'adresser aux 6 pipes !

 

L'émetteur s'identifiera grâce à sa TX_Adresse (qu'il faudra aussi donner à son RX_Pipe_0 pour les retours d'ACK qui lui seront envoyés par le RX).

 

Il ne faut donc pas confondre la TX_Adresse, qui est "l'identité" de l'émetteur,  et les RX_Pipes _Adresses qui sont les adresses des "6 zones de réception"

vers une desquelles le TX va envoyer ses données.

 

La gestion des RX_Adresses_Pipes est donc, en fait, purement affaire de software interne au nRF24L01+.

Les adresses seront ajoutées, par le nRF24L01+ du TX, en début du Payload transmis et seront « filtrées » et gérées par le nRF24L01+ du RX.

 

2.   Structure des ADDR_Pipes

La structure  du packet transmis par l'émetteur est la suivante:

 
             Packet transmis = Payload (charge utile) + Ajouts effectués par le nRF24L01+.

                 La charge utile représente les datas que vous avez décidé d'envoyer.
                 Les ajouts effectués par le nRF24L01+ sont : la TX_Adresse identifiant l'émetteur et précisant ainsi l'adresse à laquelle le RX devra lui renvoyer l'ACK,

                                                                                               l'adresse du RX_Pipe ciblé,  le résultat du calcul CRC, ... 

 

Initialement les 6 RX_ADDR_Pipes ont des adresses par défaut, identiques pour tous les nRF24L01+ produits par NORDIC Semiconductor.
On peut donc les utiliser sans devoir les préciser explicitement dans les programmes RX et TX si on se contente d'utiliser un seul TX et un seul RX dans un environnement "privé".

La largeur des RX_ADDR et la TX_ADDR doivent être identiques et peuvent être de 3, 4 ou 5 bytes, par configuration du Reg.nr.3 (SETUP_AW) Bits 0 et 1.

 

      Adresses par défaut, définies sur 5 bytes:

  


Nous allons voir un peu plus bas comment utiliser ces adresses dans les programmes du TX et du RX.

 

3.   Adressage « Multi-Pipes »

Le "multi-pipes" est le fait de ne pas se limiter à émettre vers un seul pipe du récepteur, comme cela se fait avec un ensemble de radio-commande classique.


En Mode RX (Récepteur) chaque «RX_Pipe» est donc une adresse sur laquelle vous pouvez recevoir des données qui ont été émises par un TX qui a évidemment précisé
cette adresse spécique de destination. Nous allons voir, juste ci-dessous, la manière de procéder.

Chaque circuit comportant 6 registres RX_ADDR_Pn, cela signifie qu’un seul nRF24L01+ peut se comporter, à tout instant, comme étant simultanément 6 récepteurs distincts !

Et si, par exemple, vous utilisez 3 nRF24L01+, vous disposerez de 18 adresses de destination différentes; chacune représentant un Pipe (zone de réception) distinct.


Quel intérêt penserez-vous ? Et bien, vous pourriez, par exemple, configurer un pipe pour recevoir un type de données spécifiques et un autre pour recevoir des data de contrôle, …

Vous pourriez également avoir un récepteur qui effectue plusieurs tâches différentes en fonction des données reçues dans l’un ou l’autre Pipe…
Les limites des possibilités sont juste celles de votre imagination.


Une utilisation prévue est aussi la réalisation de réseaux en étoile ou en arbre, permettant d’allonger les distances de communication par relais de transmission.


Vous pourriez aussi avoir une Pipe_Adresse identique dans chaque récepteur.
De cette façon, il sera possible de "parler" à tous les RX en même temps par l'envoi d'un seul message commun qui serait pratique pour, par exemple, un message d'alerte collectif
ou une synchronisation horaire, ... 

 

Il y a plusieurs choses à considérer lorsqu’on veut utiliser le mode «multi-pipes ».

 

-  Canal RF commun

Tout d'abord, tous les Pipes, (donc tous les TX et tous les RX du réseau radio) doivent utiliser le même canal RF qui est la fréquence définie dans le registre 5 (RF_CH).

Le nRF24L01+ dispose de 128 canaux de fréquence allant de 2,400Ghz à 2,41275 Ghz.

Chaque canal étant donc séparé de 1Mhz.

Attention cependant, qu’en Belgique (et aux States) seuls les canaux 00 à 83 sont légaux.

Pour les autres pays, veuillez-vous en assurer pour éviter de fâcheux problèmes avec les Autorités.

 

-  Définition des adresses des pipes de réception

Côté récepteur, les 6 RX_ADDR_Pipes sont à définir au début du programme RX (si on ne garde pas les valeurs par défaut, initialement toutes les mêmes pour chaque nRF24L01+)
par écriture dans les registres 10 à 15.

 

Notez queles RX_ADDR_P2 à P5 ne doivent être définis, dans le programme RX, que par leur seul LSB ! Leurs MSB sont implicitement issus du registre RX_ADDR_P1.

Si le programme du RX définit ces registres RX_ADDR_P2 à P5 avec le nombre d’octets défini dans le registre SETUP_AW, les données transmises n’arriveront jamais à destination !

 

-  Définition de la taille des adresses des pipes de réception

La taille des adresses des Pipes (AdressWidth) est à définir dans le registre n°3 « Setup_AW » aux bit0 et bit1.

Cette largeur d’adresse peut être de 3, 4 ou 5 Bytes.Elle doit être identique pour tous les TX et RX.

 

-  Mode Enhanced Schockburst

- Côté TX, si vous utilisez le mode Enhanced Shockburst (ACK),  TX_ADDR et RX_ADDR_P0, de l'émetteur, doivent être identiques
 
 pour
obtenir automatiquement les ACK (autorisations d'acquittement) envoyés par le RX concerné.

 

   Pensez alors que chaque fois que vous voulez envoyer des données dans un RX_Pipe différent, vous devez changer ces deux adresses dans le programme TX !

 

- En mode ACK, il faut que le reg.1,EN_AA (Enable Auto ACK), soit identique pour le(s) RX et le(s) TX.

 

- Il ne faut pas oublier d’activer la réception des pipes par le registre 2 (EN_RXADDR).

 

- Afin d’éviter d’éventuelles « collisions » entre les ACK émis par les divers TX d’un réseau, il est opportun de fixer des valeurs différentes au paramètre ARD (Auto Retransmitt Delay)
 
 du registre 4 (Setup_Retr).
  Le paramètre ARC de ce même registre précise le nombre de fois que le TX doit réémettre dans l’attente de son ACK.

 

- De manière générale, un traitement software des flags d’interruption (bits 4, 5 et 6 du registre STATUS) permettra de prendre l’une ou l’autre décision (message, bip alarm, arrêt du système, …)
   en cas de non réception de l’ACK au terme des tentatives de  transmission infructueuses (ARC).

 

-  Définition de la taille des RX_Payload

Les tailles des RX_Payload sont à définir dans les registres n°17 à 22 (RX_PW_P1 à 5).

Chaque canal (Pipe) peut être configuré pour recevoir jusqu’à un maximum de 32 octets de charge utile (Payload)

 

Si le mode Dynamic Payload Lenght (DPL) n’est pas activé, il faudra toujours envoyer le nombre exact de bytes défini dans ces registres, sinon, aucun ACK ne sera reçu,
signifiant que la réception ne s’est pas effectuée.

 

Si le mode DPL est activé, il faudra d’abord vérifier le nombre d’octets reçu dans le pipe.Cela se fait avec la commande  R_RX_PL_WID   (suivie de la récupération de la valeur dans une variable Byte).
Une fois cette valeur connue, de 1 à 32, nous irons lire autant de bytes dans le RX_Fifo.

 

En effet, si, côté RX, on lit plus de bytes que ceux envoyés, les bytes «excédentaires» seront la copie du dernier byte valide et ne seront pas égaux à zéro !

D’où la nécessité de savoir exactement combien de bytes il faudra réellement prendre en compte.


Exemple :

Le TX envoie 5 bytes vers le RX : Hspiout  (W_TX_Payload,11, 121, 141, 251, 111)

 ‘ W_TX_Payload = 160 ou 0x.A0

 

Si le RX veut lire plus que 5 bytes :

 

Hspiout  (Read_Rx_Payload)    ‘R_RX_Payload = 97 ou 0x.61

Hspiin (b11,b12,b13,b14,b15,b16,b17,b18)   'Read 8 bytes

 

Les variables b11 à b18 vaudront : 11, 121, 141, 251, 111, 111, 111, 111

                                                                                                      Les bytes « excédentaires » sont la recopie du dernier byte valide !

 


Retenez cependant que, dans tous les cas, un byte qui a été lu dans le RX_Fifo en est immédiatement et automatiquement supprimé.
On pourrait donc aussi lire le contenu du RX_FIFO par une boucle du type:

    DO

       < Lire le RX_FIFO >

    LOOP UNTIL RX_FIFO est Vide

 

Important:

Vérifiez toujours si la largeur du paquet reçu est de 32 octets ou moins quand vous utilisez la commande  R_RX_PL_WID . Si sa largeur est supérieure à 32 octets, le paquet
contient des erreurs et doit être supprimé. Supprimez le paquet en utilisant la commande Flush_RX.

 

Pour activer le DPL (Dynamic Payload Lenght), le bit EN_DPL du registre FEATURE doit être activé.

En mode RX, le registre DYNPD (nr 28) doit être réglé.

Un PTX qui transmet à un PRX avec DPL activé doit avoir le bit DPL_P0 défini dans DYNPD.

 

-  Débit de transfert

Le débit de transmission, TX et RX, est configurable par le registre 6 (RF_SETUP).

Il peut être 250kbps, 1Mbps ou 2Mbps.

L'utilisation d'un plus petit débit de donnéesdonne une meilleure sensibilité du récepteur qu'un débit de données élevé.

Notez cependant qu’un débit de transmission plus élevé entraîne une consommation de courant moyenne plus faible et une probabilité réduite de collisions des paquets de données
et autres ACK en circulation sur le réseau radio.

 

4.   Principes d'adressage  

 

Dès que nous allons vouloir nous affranchir des adresses par défaut, pour utiliser des adresses "personnelles", il va falloir être très attentif et organisé.

Dans un système à plusieurs TX et/ou RX, les RX_Adresses devront inévitablement être différentes pour tous les pipes.

On pourrait néanmoins avoir une adresse commune à tous les RX pour s'adresser en même temps à tous les RX par l'usage d'un messag unique.

On pourrait aussi imaginer un système simple à deux éléments mais dont chacun pourrait recevoir mais aussi émettre vers tous les pipes de l'autre module.

Il faudrait alors définir les RX_ADDR de ces deux modules.

Pour ma part, j'ai donc pris l'habitude d'indiquer des infos d'identification au début de mes programmes que je dirige vers les broches Serie du MCU (pour affichage sur un Terminal) ou

ou plus commodément pour les afficher sur le LCD du système au lancement ou au reset du programme.

Ces infos sont: le nom et la version du programme et les RX adresses "personnelles" choisies pour les 6 RX_Pipes.

Cela permet de toujours savoir quel programme est précisément chargé dans le MCU dès son lancement. 

 

Dans ce qui suit, nous partirons du principe que nous n'utilisons pas les adresses assignées par défaut et que nous choisissons donc des adresses "personnelles".

 

Préalablement à la définition de ces adresses nous allons devoir préciser la taille de ces adresses.

Elle est commune à tous les pipes du système (RX et TX !) et peut être de 3, 4 ou 5 Bytes à définir dans le registre SETUP_AW, reg.nr 3, bits 0 et 1.

Dans ce qui suit, nous aurons défini les adresses sur 5 bytes.

 

 Procédure côté Récepteur (Octets à définir dans le programme RX)

En Mode RX (Récepteur) chaque «RX_ADDR_Pipe» devra donc avoir une adresse différente.

Nous les indiquerons, en remarque, au début du programme RX et nous les définirons par configuration des registres RX_ADDR_Pn, registres 10 à 15.

 

      Exemple d'adresses "Personnelles" du RX, définies sur 5 Bytes:

 

 

 

Pour définir l'adresse RX_ADDR_P1, nous écrirons, pour un Picaxe, en BASIC :

Symbol W_RX_ADDR_P1 = 43  '43 = Reg.11 +32 (Write Commande)

Low CSN  'RX_ADDR_P1 has 5 Bytes

 Hspiout (W_RX_ADDR_P1, 241, 182, 181, 180, 179)  'RX_ADDR_P1  Reg.nr11 'PERSONAL Values RX_Addr Pipe_1, LSB First!

High CSN 

Et pour définir l'adresse RX_ADDR_P4, nous écrirons, pour un Picaxe, en BASIC :

Symbol W_RX_ADDR_P4 = 46  '46 = Reg.14 +32 (Write Commande)

Low CSN  'RX_ADDR_P1 must be defined with ONLY 1 Byte !!!

 Hspiout (W_RX_ADDR_P4, 15)  'RX_ADDR_P4  Reg.nr14 'PERSONAL Values RX_Addr Pipe_1, LSB ONLY!

High CSN

Bien que les RX_ADDR_P2 à P5 aient ici une longueur d'adresses commune de 5 bytes (définie dans le reg. SETUP_AW), il ne faut les adresser que par leur seul LSB !
Le nRF24L01+ se chargera de compléter leurs MSB en reprenant les valeurs des MSB correspondants de RX_ADDR_P1.

 

 

 

Procédure côté Emetteur (Octets à définir dans le programme TX)

 

Si nous considérons que le TX ne travaillera qu'en émetteur, il ne sera pas nécessaire de configurer les RX_ADDR_Pipes1 à 5 du TX.

 

Nous aurons juste besoin, pour chaque émission de :

       -1) Préciser l'adresse du RX_Pipe du récepteur ciblé. Elle se place dans le registre TX_ADDR du TX

       -2) Répéter cette adresse dans le RX_ADDR_P0 du TX pour y recevoir l'ACK en retour du RX.

 

En mode Enhanced Shockburst (Wait ACK), les registres/adresses TX_ADDR (Reg.16) et RX_ADDR_P0 (Reg.10) du TX doivent donc être identiques.

 

Pour transmettre des données vers un pipe d'un RX, avec attente de l'ACK (Enhanced ShockBurst Mode) les choses doivent se faire dans l’ordre :

 

      1)     Placer dans TX_ADDR, l’adresse du RX_Pipe destinataire.

2)     Placer cette même adresse dans RX_ADDR_P0 du TX pour y recevoir l'ACK en retour du RX

3)    Charger le TX_FIFO avec les datas à transmettre (Commande W_TX_Payload)

4)    Envoyer les datas (High CE durant 10µsec, Low CE)

5)    Attendre l’ACK et traiter les flags d’interruptions (Dépassement du nombre de Retry, …)


 

Pour transmettre 5 bytes dans le RX_PIPE4 du RX, nous écrirons, pour un Picaxe, en BASIC :

Symbol Write_Tx_Addr = 48      'Address 16 DEC + 32 DEC  = "Write to TX_ADDR"

Symbol W_Rx_Addr_P0 = 42       'Write to Reg.nr10 (Write to RX_ADDR_P0) MUST be equal to RX_ADDR !

Symbol Write_Tx_Payload = 160   'Command

 

DO 'BOUCLE PRINCIPALE
 < Opérations diverses incombant au TX >

Low CSN 'LSB First !

 Hspiout (Write_Tx_Addr, 15, 182, 181, 180, 179) 'RX_ADDR_P4 of the concerned RX

High CSN

 

'Set SAME RX_ADDR_0 of TX to receive ACK

Low CSN 'LSB First !

 Hspiout (W_Rx_Addr_P0, 15, 182, 181, 180, 179)  'Same TX_ADDR

High CSN

 

'Write Data to TX FIFO

Low CSN

 Hspiout (Write_Tx_Payload, 55, 105, 215, 115, 235) 'Write 5 bytes to Tx FIFO (255 MAX per Byte !)

High CSN   

 

Pulsout CE,10  '10usec High/Low pulse to TRANSMIT   >>>>>>>>>>>>>>>>>>>>>>>>>>>>>

 < Attente de l'ACK ... >

 < Traitement des flags d'interruption à lire dans le reg.STATUS ... >

 < Suite du programme ... >

LOOP 

 

 

Remarques:

   -  Les adresses des RX_Pipes sont toutes précisées en 5 bytes, même les RX_ADDR_P1 à 5 ! (Reg.nr.3 - CONFIG_AW)

   -  Les datas transmises vers RX_ADDR_P4 ne peuvent dépasser 5 bytes car la largeur de la charge utile a été définie ainsi dans le Reg.nr.21 (RX_PW_P4)

   -  Si le nombre d'octets transmis est plus grand, ou plus petit, que cette valeur, il n'y aura pas d'ACK et le Packet sera perdu.

 

 

   Dynamic Payload Length  -  DPL Mode

 D’une manière générale, dans un système TX/RX « classique », le format de la trame émise est constant.

On détermine ainsi le nombre d’octets nécessaires et suffisants à transmettre pour une application donnée et on s’en tient à ce format.
 


 
Exemple de TX de 6 Octets :

Hspiout (W_Tx_Payload TX identification, Time, Data_B1, Data_B2, Data_B3, Data_B4 )

‘ Ecriture de 6 bytes dans le TX_Fifo

 

La largeur des Pipes, 6 bytes dans cet exemple, est à configurer dans les registres 17 à 22 (RX_PW_Pn).

Si le format émis ne correspond pas à cette valeur de 6 bytes, il n’y aura pas d’ACK en retour et la transmission sera perdue.

 

A cette trame, le nRF24L01+ se chargera d’y ajouter ses propres éléments de contrôle (Préambule, ACK attendu, CRC, …) qui ne rentreront pas dans le RX_Fifo.

 

Dans le cas d’un réseau ou d’un système à relais de transmission, il se pourrait cependant que chaque TX transmette des formats différents, se heurtant ainsi à un non retour d’ACK

pour faute de format correct… Il faudra alors activer le Mode DPL.

Comme son nom l’indique, le Mode Dynamic Payload Length ne fixe plus le format de la trame émise. Le nombre de bytes composant la charge utile (Payload) peut ainsi être variable.

 

Dans le Mode DPL, les registres 17 à 22 (RX_PL_WI) n’ont alors plus d’effet, même si une valeur y a été introduite. Ils sont «court-circuités» et ignorés.

 

Le nRF24L01+ gèrera donc les trames entrantes, quelles que soient leurs longueurs, et renverra un ACK si rien ne s’est perdu en route.
Pour ce faire, le RX effectuera la vérification CRC et si le résultat est correct, témoignant d'une réception intégrale du Payload, celui-ci sera alors placé dans le RX_Fifo et l'ACK sera transmis au TX.

 

Côté RX, la commande R_RX_PL_WID, à appeler après activation d’un IRQ de réception, permettra de connaître exactement le nombre de bytes utiles à traiter, présents dans le RX_Fifo.

 

Restera au programmeur à utiliser habilement cette valeur pour lire et traiter correctement le nombre exact de bytes reçus dans le RX_Fifo.

 

Prenez alors toujours la bonne habitude de vider le RX_Fifo après traitement (Flush_RX) même si le data-sheet indique qu’un byte lu dans le RX_Fifo y est automatiquement supprimé.

 

Le mode DPL se configure avec les registres 28 (DYNPD) pour le choix des Pipes concernés et 29 (FEATURE) pour activer le mode DPL.

 

 

   La gestion des IRQ   (Interrupt Request)

1. La broche IRQ     

          Le nRF24L01+ dispose d'une broche IRQ (Pin nr.8)
 Le programme devra prendre une décision dès que cette broche basculera à l'état Bas car elle indiquera alors que "quelque chose s'est passé".
 
Nous verrons, ci-après, comment gérer ces "Interrupt Request".

 La broche IRQ basculera donc à l'état Bas dans des conditions bien précises, paramétrables par un "des trois masques d'interruption" à configurer dans le registre CONFIG.
 Il n'est donc pas obligatoire de nécessairement activer les trois masques.

2. Initialiser les masques d'interruption dans le  Registre CONFIG

 

 

   Registre CONFIG - Bit 4 - MASK_RT
    Le bit 4 du reg.nr.0 (CONFIG), s'il est configuré égal à 0, fera basculer la pin IRQ à l'état Bas si le nombre maximal d'essais de retransmissions est atteint.
    Ce nombre d'essais est à indiquer dans le registre nr.4 (SETUP_RETR) Bits 0 à 3

 

 

   Registre CONFIG - Bit 5 - MASK_TX_DS
    Le bit 5 du reg.nr.0 (CONFIG), s'il est configuré égal à 0, fera basculer la pin IRQ à l'état Bas lorsque des données sont présentes dans le TX_FIFO

 

 

 

 

  
  Registre CONFIG - Bit 6 - MASK_RX_DR
    Le bit 6 du reg.nr.0 (CONFIG), s'il est configuré égal à 0, fera basculer la pin IRQ à l'état Bas lorsque des données sont présentes dans le RX_FIFO.

Si ces trois masques sont activés dans le registre CONFIG (en mettant à zéro le bit correspondant) et si l'une ou l'autre de ces trois conditions survient, faisant basculer IRQ à Low,
il faudra évidemment pouvoir déterminer laquelle de ces trois conditions a fait basculer IRQ pour orienter le programme en fonction de la raison de l'activation de l'IRQ.



3.  Drapeaux d'Interruption dans le  Registre STATUS 
   

         Pour déterminer ce qui a fait basculer la broche IRQ, il faudra aller lire le registre STATUS:
L'état des bits 4, 5 et 6 du registre STATUS est mis automatiquement à jour pendant la transition descendante de la broche IRQ .

 Il ne faut donc pas confondre les fonctions du registre CONFIG (dans lequel on précise les conditions de basculement à l'aide de "masques") et STATUS (qui indique l'événement qui à provoqué l'IRQ)  !
  Si le registre Status est lu juste pendant une transition descendante de la pin IRQ, les informations ne seront pas fiables !

 

 

  

 

 Registre STATUS - Bit 4 - MAX_RT
  Le bit 4 du reg.nr.7 (STATUS), passe à 1 si le nombre maximal d'essais de retransmissions est atteint.
  Ce nombre d'essais est à indiquer dans le registre nr.4 (SETUP_RETR) Bits 0 à 3.

Tant que ce bit restera alors à l'état haut, le TX ne pourra plus émettre aucun packet !
   Pour "effacer" ce bit, il suffira d'aller écrire... "1" au bit 7 du registre STATUS !
 Et oui, vous avez bien lu ! Ce n'est pas une faute de frappe ! C'est bien un "1" qu'il faut aller écrire... alors que sa valeur est déjà égale à 1 !!!?

 

 

 Registre STATUS - Bit 5 - TX_DS
  Le bit 5 du reg.nr.7 (STATUS) passe à "1" quand un Packet arrive dans le TX_FIFO.
  Si le Mode Auto-ACK est activé (Reg. EN_AA), ce bit ne passera à l'état Haut que lorsqu'il aura reçu l'ACK du RX.
     Ici aussi, pour effacer ce bit, il faudra aller y écrire un ... "1" !

  

 

 


 Registre STATUS - Bit 6 - RX_DR
  Le bit 6 du reg.nr.7 (STATUS) passe à "1" quand de nouvelles données arrivent dans le RX_FIFO.
    Et vous l'avez deviné...pour effacer ce bit... il faudra aller y écrire un ... "1" !

NOTE:  Si le RX a joint un message à son ACK, en utilisant la commande  W_ACK_PAYLOAD , le bit 5 = TX-DS (ACK reçu) et le bit 6 = RX-DR (Datas in RX Fifo, du TX)  du TX Status seront activés à la réception de l'ACK.



 4. La gestion des IRQ 


Il y a deux méthodes pour surveiller le basculement de la pin IRQ: par Interruption ou par Polling

 4.1 Traitement de l'IRQ par Interruption

Comme son nom l'indique une interruption interrompt le déroulement du programme principal.
Un peu à la manière d'un appel à une sous-routine, le MCU procèdera aux opérations stipulées dans la routine d'interruption.
Il est donc nécessaire d'écrire des routines d'interruption les plus courtes possibles !

Ce traitement par interruption est cependant bien plus délicat qu'un simple appel à une sous-routine pour plusieurs raisons:

- Tout d'abord, cette interruption peut survenir à tout moment, non déterminé, ni désiré, par le programme, donc à tout endroit de son déroulement,
    pouvant suspendre ou "geler" une opération en cours qui sera momentanément compromise.
    Imaginez, par exemple, que le programme était en train de commander l'ouverture d'une vanne, ...
- Si le programme n'est pas bien pensé, la routine d'interruption pourrait aussi modifier des variables ou des mémoires. Au retour dans le programme principal,
   ces modifications altéreront son bon déroulement. Evitez donc de modifier des mémoires au cours d'une routine d'interruption.
- Autre inconvénient, si une ou plusieurs autres Interruptions surviennent durant le traitement, toujours en cours d'une précédente, elles s'empileront dans une file d'attente.
   Outre le fait que leurs traitements successifs retarderont d'avantage le programme principal, il pourra y avoir risque de dépassement de la pile opérationelle du MCU.
   Cela implique que le retour dans le programme principal ne se fera plus nécessairement là où il a été quitté et interrompu. Notre vanne continue de couler !

Il faut donc être très prudent lorsqu'on utilise des routines d'interruption !
A noter que certains MCU permettent la désactivation temporaire des Interruptions pouvant survenir durant le traitement en cours d'une IRQ précédente.
C'est un bien et un mal car ces dernières risquent alors d'être totalement ignorées et donc jamais traitées à la reprise du programme principal !

4.2 Traitement de l'IRQ par "Polling"

Le polling pourrait être assimilé au mot "Scanning" et à la traduction "Scrutation".

Elle consiste à écrire le programme principal sous forme d'une boucle dite "infinie" et de lire, de haut en bas, au cours de cette boucle, l'état de la pin IRQ.
Les décisions et les opérations en découlant seront prises et seront traitées dans le corps de cette boucle constituant le seul programme principal, dit "structuré".

Son avantage est donc d'éviter les inconvénients des Interruptions, cités ci-dessus.

Exemple de traitement par INTerruption

< Définition des masques d’IRQ >

 

Setint %00000000, %00000100,B  'Picaxe 28x2 Interrupt Pin B.2 Low (Entree,Mask_IRQ,Port)

 

 ' Cette commande active la S/routine INTERRUPT: (GoSub implicite)

 ' IRQ est sur B.2

 ' Le 2eme parametre (Mask) ne verifie ici que l'entree 2 du port B (valeur =1 à la pin2)

 ' Le 1er parametre (Entree) dit que l'entree 2 doit etre =0 pour generer une interruption

 

Gosub Config_Registers  ‘ Initialisation des Registres

 

DO              ' BOUCLE PRINCIPALE

 

 < Opérations diverses incombant au RX >‘Celles-ci seront interrompues par l’interruption !

 

 High CE          ' RX prêt, en attente d’une réception (et donc d’une IRQ).

 

LOOP


‘ ...............................

‘ .     ROUTINES                .

‘ ...............................

 

INTerrupt : 'Routine implicite appelée par l'activation de l'Interruption

  < Lire le registre STATUS >

  < Isoler les bits « Drapeaux IRQ » >

  < Traiter de l’IRQ >

  < Effacement des bits « Drapeaux IRQ » >

  < Redéfinition des masques d’IRQ >

Return

Exemple de traitement par Polling

Gosub Config Registers  'Initialisation des registres

  

DO  'BOUCLE PRINCIPALE

 

 < Opérations diverses incombant au RX >

 

High CE             'RX prêt, en attente d’une réception (et donc d’une IRQ).

 

if IRQ = 0 then     'Vérification de l’état de la broche IRQ

  Gosub Lecture_RX  'Traitement de l’IRQ

  Gosub Clear_IRQ   'Effacement des bits 4,5,6 «drapeaux d’IRQ» dans le reg.STATUS

  High CE           'RX prêt, en attente prêt pour autre réception

End if

 

 <Suite Opérations diverses incombant au RX > 'Affichage, traitement …

 

LOOP

 

 

 

   Charge Utile (Payload)

La charge utile représente les octets réellement utiles. Ce sont donc ceux que vous avez décidé d'envoyer vers le système RX.
Nous verrons, ci-dessous,  que le nRF24L01+ y ajoutera des octets supplémentaires nécessaires à la gestion du protocole Enhanced Schockburst.

La charge utile peut compter jusqu'à 32 Octets de datas utiles.

En  mode statique, la longueur de la Payload doit être définie pour chaque Pipe de réception, dans les registres RX_PW_Pn.
Si vous n'envoyez pas le nombre d'octets ainsi définis, il n'y aura pas d'ACK et le packet sera perdu.

Il existe alors le mode Dynamic Payload Length permettant, comme nous l'avons vu ci-dessus, des longueurs variables de payloads.

 

     Enhanced ShockBurst™ 

  Cette fonctionnalité consiste en l'assemblage du paquet à émettre. Cet assemblage permet d'améliorer la fiabilité de la transmission tout en gardant une très faible consommation.

 

Les caractéristiques du mode « Enhanced ShockBurst™ » sont :

 - Charge utile dynamique « Dynamic Payload » de 0 à 32 octets.

Gestion automatique du paquet.

 - Transaction automatique sur le paquet avec :

-  ACK Automatique avec la charge utile.

-  Retransmission automatique

 Possibilité de créer un réseau en étoile 1RX / 6TX grâce au mode « MultiCeiver™ ».

 

Assemblage d'un paquet « Enhanced ShockBurst ».

 

Le paquet est composé des éléments suivants :



 Préambule : C'est un octet de synchronisation pour le récepteur. Si le premier bit de l'adresse est un 1, le préambule sera 10101010, sinon, il sera 01010101.

 Adresse : C'est l'adresse d'utilisation du système « MultiCeiver™ ». Sa taille est fixée par le registre « SETUP_AW », et est comprise entre 3 et 5 octets.

 

 Contrôle du paquet : C'est une combinaison de 9 bits, structurée comme suit :


Taille de la charge utile : C'est l'indication de la taille de la charge utile comprise entre 0 et 32 sur 6 bits.
      La valeur, utilisée en mode « taille dynamique », est comprise entre 0 (000000), utilisée pour un paquet ACK vide, et 32 (100000).
      La valeur 33 (100001) est utilisée pour indiquer de ne pas tenir compte de ce paramètre.

-  PID (Paquet IDentification) : Le champ est utilisé pour détecter si le paquet reçu est nouveau ou réémis. Cela évite au récepteur de présenter plusieurs fois le même paquet au µcontrôleur.
Du côté émetteur, le champs PID est incrémenté à chaque nouveau paquet reçu par le µcontrôleur. Grâce aux champs PID et CRC, le récepteur peut déterminer si le paquet qu'il reçoit est nouveau ou ré-émis.
Lorsque plusieurs paquets sont perdus, il est possible que le récepteur reçoive 2 fois le même paquet avec le même PID. Si un paquet a le même PID que le paquet précédent, le nRF24L01 + compare
les sommes CRC des deux paquets. Si les sommes CRC sont égaux, le dernier paquet reçu est considéré comme une copie du paquet précédemment reçu et mis au rebut.

-   N0_ACK : Lorsque ce bit est mis à 1, Le récepteur ne renverra pas de paquet ACK vers l'émetteur. Ce bit est activé dans l’émetteur par la commande « W_TX_PAYLOAD_NOACK ».
Cependant, la fonction doit d'abord être activé dans le registre « FEATURE » en activant le bit « EN_DYN_ACK ». Si cette fonction est utilisée, l'émetteur repasse directement en mode « Stanby I ».

 

 Charge Utile : Ce sont les octets réellement utiles. Leur nombre doit-être compris entre 0 et 32. La fonctionnalité « Enhanced ShockBurst™ » offre deux alternatives pour le traitement des longueurs
de charge utile : statique et dynamique.
La valeur par défaut est statique. Les paquets ont alors tous la même longueur, qui est définie dans le registre « RX_PW_Px ».
L'autre possibilité est la « Dynamic Payload Length (DPL) ». Les longueurs de paquets sont alors variables.
Les registre « RX_PW_Px » ne sont alors pas utilisés, et le récepteur décode la longueur de la charge utile lors de sa réception.
Le µcontrôleur peut alors connaître la longueur du paquet grâce à la commande « R_RX_PL_WID ». Attention que si la longueur du paquet est supérieure  32 octets, le paquet doit-être mis au rebut
 en utilisant la commande « FLUSH_RX ».
Pour activer le mode « DPL »,  le bit « EN_DPL » du registre « FEATURE » doit-être activé.
Du côté récepteur, le registre « DYNPD » doit-être mis à jour. Et du côté émetteur, le bit « DPL_P0 » de ce registre doit-être activé.

 

CRC : Le CRC est calculé à partir de tous les bits précédents dans le paquet. Sa taille, de un ou deux octets, est définie par le bit « CRCO » dans le registre « CONFIG ».

 

 

Compatibilité descendante :


Le circuit nRF24L01+, peut-être rendu compatible avec les circuits que Nordic a produit précédemment, comme les nRF24L01, nRF2401A, nRF2402, nRF24E1 et autre nRF24E2.

 

Débit de données :

Le nRF24L01+ est entièrement compatible avec le nRF24L01.

Pour une compatibilité avec les autres circuits, le débit de données de 2Mbps ne peut pas être utilisé. Il est donc obligatoire d'utiliser les modes 1Mbps ou 250kbps.

 
 

Compatibilité avec ShockBurst™ :

Pour une compatibilité descendante avec les circuits RF2401A, nRF2402, nRF24E1 et nRF24E2, vous devez désactiver le mode « Enhanced ShockBurst™ ».
Pour cela, il faut définir le registre « EN_AA » = $00 et le bit « ARC » = 0.

  

 

Format du paquet ShockBurst™ :

La figure ci dessous, montre la composition d'un paquet « ShockBurst™ ». Ce paquet est compatible avec les circuits nRF2401, nRF2402, nRF24E1 et nRF24E2.

 

   

Ce paquet est composé des champs: préambule, adresse, charge utile et CRC. Ces champs sont les mêmes que ceux décrit dans le mode « Enhanced ShockBurst™ ».

 

Les différences entre les modes « ShockBurst™ » et  « Enhanced ShockBurst™ » sont :

        Le champ de 9 bits « Contrôle du paquet » n'existe pas dans le paquet « ShockBurst™ ».

        Dans le paquet « ShockBurst™ », le CRC est facultatif. Ce paramètre est contrôlé par le bit « EN_CRC » du registre « CONFIG ».

 

 

Exemple de configuration et de communication

 

Transmission de la charge utile, en Mode Enhanced ShockBurst ™ 

1.    Réglez le bit de configuration PRIM_RX = Low.

 

2.    Lorsque l’application MCU (MicroContrôleur) a des données à transmettre, envoyez l'adresse du noeud de réception (TX_ADDR) et les données de la charge utile (TX_PLD) dans le nRF24L01+
par l'intermédiaire du SPI. La largeur de la charge utile TX est comptée à partir du nombre d'octets écrits dans le FIFO TX par le MCU.
TX_PLD doit être écrit en continu tout en maintenant CSN Low.
TX_ADDR n'a pas besoin d'être réécrit s'il est inchangé depuis la dernière transmission.
Si le dispositif PTX doit recevoir une confirmation, configurez le canal de données 0 pour recevoir le paquet ACK.
L'adresse RX du canal de données 0 (RX_ADDR_P0) doit être égale à l'adresse TX (TX_ADDR) dans le dispositif PTX.

 

3.    Une impulsion High sur CE déclenche la transmission. La largeur d'impulsion minimale sur CE est de 10 µs.

 

4.    nRF24L01 + ShockBurst ™:

•  La radio est mise sous tension.
  L'horloge interne de 16MHz est démarrée.
  Le paquet RF est complété par les ajouts effectués par le nRF24L01+ 
 (voir, ci-dessus, la description du paquet).
  Les données sont transmises à grande vitesse (1Mbps ou 2Mbps configuré par le MCU).

 

5.    Si l'acquittement automatique (ACK) est activé (ENAA_P0 = 1), la radio passe immédiatement en mode RX, à moins que le bit NO_ACK ne soit mis dans le paquet reçu.
Si un paquet valide est reçu dans la fenêtre de temps valide d'attente de l'ACK, la transmission est considérée comme un succès.

      Le bit TX_DS du registre STATUS passe à "1" et la charge utile est supprimée de TX FIFO.
Si un paquet ACK valide n'est pas reçu dans la fenêtre temporelle spécifiée, la charge utile est retransmise (si la retransmission automatique est activée).
Si le compteur de retransmission automatique (ARC_CNT) dépasse la limite maximale programmée (ARC), le bit du drapeau d'interruption MAX_RT du registre STATUS passe à l'état "1".

      La charge utile dans TX FIFO n'est pas supprimée.
La broche IRQ est active (Active Low !) lorsque MAX_RT ou TX_DS est High.
Pour désactiver la broche IRQ, réinitialisez la source d'interruption en écrivant dans le registre STATUS.
Si aucun paquet ACK n'est reçu pour un paquet après le nombre maximum de retransmissions,
aucun autre paquet ne pourra être transmis avant que l'interruption MAX_RT ne soit effacée.

Le compteur de perte de paquets (PLOS_CNT) est incrémenté à chaque interruption MAX_RT. Autrement dit, ARC_CNT compte le nombre de retransmissions nécessaires pour envoyer un seul paquet.
PLOS_CNT compte le nombre de paquets qui n'ont pas réussi à être correctement transmis après le nombre maximum de retransmissions.

 

6.    Le nRF24L01+ passe alors en mode StandBy-I si CE est Low. Sinon, la prochaine charge utile en TX FIFO est transmise.
Si TX FIFO est vide et CE est encore High, le nRF24L01+ passe en mode StandBy-II.

 

7.    Si le nRF24L01+ est en mode StandBy-II, il passe immédiatement en mode StandBy-I si CE = Low.  

 

Réception de la charge utile, en mode Enhanced ShockBurst ™

1. Activez le mode RX en plaçant le bit PRIM_RX du registre CONFIG à "1".
     Tous les data Pipe qui reçoivent des données doivent être activés (Registre EN_RXADDR).
     Activez aussi l'accusé de réception automatique (ACK)  pour tous les Pipes fonctionnant en mode EnhancedShockBurst ™ (registre EN_AA)
     Définissez les largeurs de charge utile correctes (registres RX_PW_Pn).
     Enfin, configurez les adresses des RX_Pipes comme décrit ci-dessus.


2. Démarrez le mode Active RX en basculant CE à l'état Haut.


3. Après 130µs, le nRF24L01+ surveille le trafic, en attente d'une communication entrante.


4. Lorsqu'un paquet valide est reçu (adresse correspondante et CRC correct), la charge utile est stockée dans le RX-FIFO, et le bit RX_DR du registre STATUS passe à "1".
    La broche IRQ est active lorsque  RX_DR est High.

    RX_P_NO du registre STATUS indique dans quel RX_Pipe la charge utile a été reçue.


5. Si l'accusé de réception automatique est activé, un paquet ACK est transmis en retour, vers le TX, à moins que le bit NO_ACK ne soit défini dans le paquet reçu.
     S'il existe une charge utile dans la FIFO TX_PLD, cette charge utile est ajoutée au paquet ACK.


6. Le MCU bascule la broche CE à l'état Bas pour passer en mode StandBy-I (mode courant bas).


7. Le MCU peut synchroniser les données de charge utile à un taux approprié à travers le SPI.


8. Le nRF24L01+ est maintenant prêt à entrer en mode TX ou RX ou en mode de mise hors tension.

  

   Auto ACK et ajout d'une charge utile à l'ACK

l'« Auto ACK » est une fonction qui émet automatiquement un paquet « ACK » vers l'émetteur après avoir reçu et validé un paquet.
Cette fonction réduit la charge du µcontrôleur et diminue le flux de communication SPI.
Cela permet de réduire la consommation moyenne du système. La fonction "Auto ACK" est activée en ajustant les valeurs du registre « EN_AA ».

 

Remarque: Si le paquet reçu a le drapeau « NO_ACK » activé, l'« Auto ACK » n'est pas exécuté.

 

Un paquet ACK peut éventuellement contenir une charge utile.
Pour pouvoir utiliser cette possibilité, il faut activer la fonction « Dynamic Payload Length (DPL) ».
Le µcontrôleur du côté récepteur doit alors charger son « TX_FIFO » en utilisant la commande « W_ACK_PAYLOAD ». (voir détail de cette commande)
La charge utile reste en attente dans le « TX_FIFO » du récepteur jusque la réception d'un nouveau paquet provenant de l'émetteur.
Le circuit nRF24L01+ peut accepter trois charges utiles en attente dans le « TX_FIFO ».

 

Lorsqu'une charge utile est chargée dans le « TX_FIFO » par la commande « W_ACK_PAYLOAD », l'adresse de l'émetteur est comparée avec celle du paquet reçu,
ce qui permet d'envoyer le paquet avec la même adresse au générateur « ACK ».

 

Si plusieurs paquets avec la même adresse se trouvent dans le « TX_FIFO » du récepteur, les charges utiles sont traitées selon le principe FIFO (premier entré, premier sorti).
Le « TX_FIFO » du récepteur peut se retrouver saturé, si toutes les charges utiles s'adressent à un émetteur qui se trouve hors connexion.
Il est alors possible de vider le buffer à l'aide de la commande « FLUSH_TX ».

 

Si la fonction "Auto_ACK" avec charge utile doit-être activée, il faut mettre le bit « EN_ACK_PAY » du registre « FEATURE » à "1."

 

     Modes de Fonctionnement

 

Mode « Power Down »
Dans le mode « Power Down », le nRF24L01+ est désactivé et consomme un minimum. Tous les registres sont maintenus et le SPI reste actif.
Ce mode est activé en mettant à zéro (0) le bit « PWR_UP » du registre « CONFIG ».
 

Mode « Standby-I »

Ce mode est activé en mettant à un (1) le bit « PWR_UP » du registre « CONFIG ». Ce mode, qui ne fait fonctionner que l'oscillateur, permet le passage rapide vers les modes actifs RX ou TX.
Le passage vers les modes RX ou TX se fait lorsque la broche CE est mise à un (1), et le retour au mode « Standby-I »se fait par mise à zéro de la broche CE.

 

Mode « Standby-II »

Ce mode consomme un peu plus que le mode « Standby-I », les buffers d'horloge étant actifs.

Il est activé lorsque en mode PTX,  la broche CE est mise à un (1), et que le buffer « TX FIFO » est vide. Cela permet d’émettre un paquet dès sa réception par le SPI (avec un délais de 130µs).

Dans les deux modes Standby, les registres sont maintenus, et le SPI est actif.

 

Mode « RX »

C'est le mode actif de réception. Pour activer ce mode, les bits « PWR_UP » et « PRIM_RX » doivent être mis à un (1), et la broche CE doit-être mise à l'état haut (1).

Dans ce mode, le circuit démodule en permanence le signal reçu, à la recherche d'un paquet valide.
Si un paquet valide (bonne adresse et CRC valide) est reçu, la « charge utile » est présentée à un slot libre du « RX FIFO ». Si les 3 slots sont occupés, le paquet est perdu.

Le mode RX est actif jusqu'à ce que les modes « Power Down » ou « Stanby-I » soient activés.

Toutefois, si le protocole « Enhanced ShockBurst™ » est activé, le circuit peut passer dans d'autres modes en vue de respecter les fonctions de ce protocole.

Dans le mode RX, un signal « RPD » ( Received Power Detector) est généré lors le niveau du signal radio  reçu est supérieur à -64dBm pendant au moins 64µs.

 

Mode « TX »

C'est le mode actif pour l'émission des paquets. Les conditions pour activer ce mode sont : « PWR_UP » à un (1), « Prim_RX » à zéro (0), données dans le « TX FIFO » et une impulsion supérieure à 10µs
sur la broche CE.

Le mode TX est maintenu jusqu'à la fin de la transmission du paquet. Ensuite, si CE = 0, le nRF24L01+ revient en mode « Standby-I ». Si CE = 1, l'état du TX FIFO détermine l'action suivante.
Si le TX FIFO n'est pas vide, le nRF24L01 + reste en mode TX et transmet le paquet suivant. Si le TX FIFO est vide, le nRF24L01 + passe en mode « Standby-II ». Le PLL nRF24L01+ fonctionnant en boucle
ouverte, il est important de ne jamais conserver le mode TX pendant plus de 4ms. Si le protocole « Enhanced ShockBurst™ » est activé, ce délais de 4ms sera toujours respecté.

 

L'organigramme ci-dessous, montre les différents modes de fonctionnement du circuit. 

         

             

 

 

 

 

     Emission d'une porteuse constante pour la phase de tests

 

La puissance de sortie d'une radio est un facteur critique pour atteindre la distance de communication souhaitée.
La puissance de sortie est aussi le premier critère d'essai nécessaire pour être en conformité avec toutes les réglementations de télécommunication en vigueur !

 

Configuration

 

1. Définissez PWR_UP = 1 et PRIM_TX = 0 dans le registre CONFIG.

 

2. Attendre 1,5ms  PWR_UP->StandBy.

 

3. Dans le registre RF_SETUP, configurez :

• CONT_WAVE = 1.
• PLL_LOCK = 1.
• RF_PWR.

 

4. Choisissez le canal RF souhaité. par le registre RF_CH

5. Placez CE à l'état haut.

 

6. Gardez CE haut aussi longtemps que la porteuse est nécessaire.


Remarque:

 

N'utilisez pas la commande REUSE_TX_PL conjointement à CONT_WAVE (bit7 du reg. RF_SETUP) = 1.
Lorsque ces deux registres sont réglés, le nRF24L01+ ne réagit pas lorsque CE  = Low.
Si toutefois, les deux registres sont réglés PWR_UP (bit1 du Reg. CONFIG) = 0, le mode TX est désactivé.

 

Le nRF24L01 + peut maintenant émettre une porteuse centrale non modulée.

 

 

   Envoi et réception de messages Textes

Nous avons vu que ce système de communication TX/RX permet l'envoi de données sous forme d'octets.
Ces octets peuvent représenter des valeurs numériques (températures, pressions, niveaux, tensions, ...) mais aussi des caractères de texte d
ans le cadre de l'envoi d'un message "en clair".

Ainsi, une charge utile pourra contenir un message texte pouvant compter jusqu'à 32 caractères.

Nous allons voir ici, succinctement, comment gérer un message du côté TX et RX .

Côté TX: Caractères to Octets

- 1)  On va charger le message dans le TX Fifo

'Write Data to TX FIFO
Symbol Write_TX_Payload = 160  'See Command Table

Low CSN
 Hspiout (Write_TX_Payload,"Ici RX Garage: Batteries faibles")
'Write String, MAX 32 characters, to Tx FIFO (Automatiquement converti en Bytes)
High CSN
Pulsout CE,10   'TRANSMIT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>

Côté RX: Octets to Caractères

Côté récepteur, nous allons récupérer ce message, caractère par caractère, et nous allons les placer dans la ScratchPad Ram.

- 2) On va d'abord compter le nombre de caractères reçus dans le RX Fifo et le placer dans la variable Rx_W_Pld

'Read Width of RX_Payload with the R_RX_PL_WID Command. Command to use if Dynamic Payload Length is enabled!
 
  Symbol Read_Rx_Pld_W = 96 ' Read RX Fifo Command Byte (See Command Table in datasheet)

  Low CSN
   Hspiout (Read_Rx_Pld_W'Reading
   Hspiin (Rx_W_Pld) 'To Variable Byte
  High CSN

- 3) Le Picaxe ne gerant pas les variables indicées, on va utiliser la ScratchPad-Ram et son pointeur qui sera utilisé comme indiceur.

Symbol Read_Rx_Payload = %01100001 ' Read RX Fifo Command Byte %01100001=97=0x61 (See Command Table in datasheet)

i=1

Low CSN
 '  LECTURE DE RX_FIFO
 '-----------------------------
   Hspiout (Read_Rx_Payload) ' On doit lire dans le RX_FIFO le nombre exact de Bytes recus
    ptr = 1 'Pointeur de la ScratchPad
     For i = 1 to Rx_W_Pld 'On ECRIT, dans la ScratchPad, autant de bytes que RX_W_DPL (Un byte = 1 caractere)

      Hspiin (@ptrinc)
     Next i
  High CSN

  sertxd ("Nbre de Bytes recus dans RX FIFO: ", #Rx_W_Pld, cr,lf)

 

- 4) On va enfin afficher le message en clair

'  AFFICHAGE DES OCTETS RECUS
'-------------------------------

  Sertxd (" ATTENTION, Il y a un message = [")
  for ptr = 1 to Rx_W_Pld
   Sertxd (@ptr) 'On LIT, dans la ScratchPad, autant de bytes (autant de caracteres) que RX_W_Pld

  Next ptr
  Sertxd ("]",cr, lf)

 

Et le résultat final affiché à l'écran de la console terminale sera:   ATTENTION, Il y a un message = [Ici RX Garage: Batteries faibles]

Un tel message pourrait être celui d'un RX qui le joindrait, au besoin, à son ACK, lors d'un prochain envoi.

Voir la commande W_ACK_PAYLOAD.

   Les Registres du nRF24L01+

Les registres sont utilisés pour configurer les différents paramètres indispensables et les fonctions vitales du nRF24L01+.
Chaque registre (à l'exception des trois registres de charge utile) possède une adresse 5 bits qui est masquée dans les instructions R_REGISTER et W_REGISTER (voir ci-dessous), respectivement pour lire et écrire dans le registre.

Les registres suivants sont disponibles:
            
  
Vous trouverez, dans le tableau ci-dessous, le détail de configuration de tous les registres du nRF24L01+ , avec la fonction spécifique de chacun de leurs bits.    
  

 

     Les FIFOs

Le nRF24L01+ contient deux "files d'attentes de packets", appellées les FIFOs. (Registre de type "First In, First Out")
Il y en a un pour les packets reçus (RX Fifo) et un pour les packets à transmettre (TX Fifo).

Chaque FIFO peut contenir jusqu'à trois packets, il est donc dit "Registre à trois niveaux".
Retenez cependant qu'une charge utile ne peut dépasser le maximum de 32 octets.
Les registres FIFO peuvent donc stocker trois charges utiles complètes, en attente temporaire de leur traitement par le MCU.

Si une transmission échoue, le paquet n'est pas effacé du TX FIFO. Il devra être supprimé en utilisant l'instruction FLUSH_TX !

Le Rx FIFO ne doit pas être confondu avec les RX_pipes.
Un RX_Pipe représente l'une des 6 adresses distinctes que la radio possède, tandis que le Rx FIFO est la file d'attente de 3 paquets
dans laquelle les paquets reçus sont stockés jusqu'à ce que le MCU les lise dans le nRF24L01+.

TOUS les 6 RX_Pipes placent leurs Datas dans le même RX Fifo à trois niveaux.
Lorsque le RX FIFO est plein, les nouveaux paquets sont supprimés jusqu'à ce qu'un espace dans le FIFO devienne disponible.
On peut donc dire que le Rx FIFO se comporte comme une vraie file d'attente.

Par contre, lorsque le TX FIFO est complètement rempli, l'ajout de paquets poussera le(s) paquet(s) le(s) plus ancien(s) hors de la file d'attente.
Le Tx FIFO n'est donc pas vraiment une "réelle" file d'attente !

Si un récepteur utilise la fonction ACK Payload Feature, alors la charge utile ACK est stockée dans le TX FIFO.

De toute façon, la charge utile de l'ACK est seulement transmise dans un paquet ACK, même si il est en tête du FIFO durant une transmission.
Si la charge utile ACK n'est pas en tête du FIFO et qu'un paquet ACK est transmis, alors la charge utile ACK est supprimée peu importe le slot du FIFO qu'elle occupe.

 

 

   Les Commandes du nRF24L01+

 Vous trouverez, dans le tableau suivant, les commandes permettant d'accéder aux registres pour contrôler et piloter le nRF24L01.

 

    

     Programme TX.9

 

Ce programme explore toutes les possibilités du nRF24L01+:

  - Transmission vers les 6 pipes du RX ayant leurs adresses personnalisées
  - Arrêt de l'émission et message d'alerte en cas de défaut d'ACK récurrent
  - Recherche et affichage d'un éventuel message joint à l'ACK par le RX
  - Comptage des packets perdus
  - Activation du Mode Dynamic Payload Length
  - Activation des Payload avec ACK

Il est à combiner avec le programme RX.6, édité juste ci-dessous.

 

' TX_09

' Routine de test d'IRQ et non par Mask IRQ

' Message d'ALARME et STOP_TX en cas de non ACK reccurent !

' Enable all ACK

' Emission vers les 6pipe ayant leurs RX_Adresses = PERSONALS Values !

' Mode Dynamic Payload Length (DPL)

' Analyse du bit IRQ

' Recherche et affichage d'un éventuel message joint à l'ACK par le RX.

' Comptage des packets perdus

' Shield sur Picaxe Axe401

' A combiner avec RX6

' Roger LEGAT - Janvier 2017 - PICAXE Basic

 

'* Raccordement des modules                                               *

'* ------------------------                                               *

'* Le picaxe utilise est un 28X2/16Mhz sur carte AXE401 (Arduino Layout)  *

'* Le module nRF24L01+ y est raccorde avec un Arduino Proto Shield        *

'* On utilise un module d'adaptation tension (5V to 3,3v)                 *

'*                                                                        *

'*    AXE401    | 28X2              | Adapt | nRF24L01+        | Dir      *

'*    ----------+-------------------+-------+-------------------------    *

'*    S.2 (B.2) | Pin 23 - B.2      | Pin 6 | IRQ (10K Pullup) | In       *

'*    S.11(C.5) | Pin 16 - HSPI SDO | Pin 4 | MOSI             | Out      *

'*    S.13(C.3) | Pin 14 - HSPI SCK | Pin 3 | SCK              | Out      *

'*    S.12(C.4) | Pin 15 - HSPI SDI | Pin 5 | MISO             | In       *

'*    S.6 (B.6) | Pin 27 - B.6      | Pin 2 | CSN              | Out      *

'*    S.4 (B.1) | Pin 22 - B.1      | Pin 1 | CE               | Out      *

'*    ----------+-------------------+-------+--------------------------   *

'*    5V        | Pin 20 - +V       | VCC   | ->3V3            | Pwr+     *

'*    GND       | Pin 19 - 0V       | GND   | GND              | Pwr-     *

'*                                                                        *

'**************************************************************************

 

' RX_ADDR_Pipes defined in the RX program

'    PERSONALS Values !

'-------------+-----+-----+-----+-----+-----+     RX_ADDR_P0 DOIT etre egal a TX_ADDR

'             | B4  | B3  | B2  | B1  | LSB |     TXAB0 signifie TX Addresse Byte 0

'-------------+-----+-----+-----+-----+-----+--------------------------------------------------------

'  TX_ADDR    |TXAB4|TXAB3|TXAB2|TXAB1|TXAB0|---> TX to RX_ADDR_Pipe(0 to 5) defined in RX Program

' RX_ADDR_P0  |TXAB4|TXAB3|TXAB2|TXAB1|TXAB0|<--- ACK return (if ACK Enabled)

'=============+=====+=====+=====+=====+=====+========================================================

'RX_ADDR_Pipes of the TRX, defined in the RX Program

'    PERSONALS Values (NOT Defauklt Values !)

'-------------+-----+-----+-----+-----+-----+

' RX_ADDR_P1  | 179 | 180 | 181 | 182 | 241 |   The last 5 RX_ADDR_Pipe (Pipe 1 to 5)

' ------------+--v--+--v--+--v--+--v--+-----+    must be defined in this Program

' RX_ADDR_P2  |(179)|(180)|(181)|(182)| 205 |      if RX mode is used here !

' RX_ADDR_P3  |(179)|(180)|(181)|(182)| 163 |

' RX_ADDR_P4  |(179)|(180)|(181)|(182)|  15 |       This program only emitter data.

' RX_ADDR_P5  |(179)|(180)|(181)|(182)|   5 |  So defining these addresses is not necessary here.

'-------------+-----+-----+-----+-----+-----+

 

'   Mode Control nRF24L01+

'----------------------------

' Configure all registers correctly(ACK, Pipes Enable and Lenght Addr., Re-Transmit, Delay, RF Channel and Power, ...)

' Set Power On/Off and Tx/Rx Mode with the CONFIG Register

'

' CE in TX Mode: Always set to Low

'   To transmit 1) Load TX_FIFO Buffer

'               2) Set CE High during 10us and return set CE Low. (Pulsout 10us)

 

' CE in RX Mode: Always set to High for waiting data

'                 Offline if CE is Low (disconnected from the radio network !)

'

' CSN: Always set to High. Set Low to active SPI bus

 

'  COMMENTS

'------------------

' Un Flush_Tx est effectue en fin de chaque routine Wait_ACK

'

' Console: Set to 19200 Bauds

'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

 

#Picaxe 28X2

#No_Data

#No_Table

 

  Variables:

'--------------

{         

Symbol CONFIG =0'Address of Config Register   

Symbol STATUS =7'Address of Status Register

 

Symbol Write_TX_Payload =160' See Command Table

Symbol W_ACK_Payload_P0 =168' See Command Table

Symbol W_ACK_Payload_P1 =169' See Command Table

Symbol W_ACK_Payload_P2 =170' See Command Table

Symbol W_ACK_Payload_P3 =171' See Command Table

Symbol W_ACK_Payload_P4 =172' See Command Table

Symbol W_ACK_Payload_P5 =173' See Command Table

 

Symbol Write_Tx_Addr =48'Address 16 DEC + 32 DEC  = "Write to TX_ADDR"

Symbol W_RX_ADDR_P0  =42'Write to Reg.nr10 (Write to RX_ADDR_P0) MUST be equal to RX_ADDR !

 

Symbol CE =B.1'Chip Enable

Symbol CSN =B.6'Chip Select/Active low)

Symbol IRQ =pinB.2

 

Symbol Data1    =b0' Dynamic Variables

Symbol Addr     =b1

Symbol Retry    =b2' Nombre de retry de 100msec

Symbol TestACK  =b3' 0=BAD,1=OK

Symbol Count_Do =b4' Comptr de boucle Retry

Symbol TX_Pak   =b5'

Symbol LostPak  =b6' Comptr de packets persus "extrait" du Reg.08 OBSERVE_TX

LostPak =0

 

Symbol TimeOut  =b8' Comptr pour le "TimeOut" d'ACK

Symbol TestIRQ  =b9' Valeur "extraite" des IRQ

 

Symbol Flush_Tx =225'%1110 0001 Commande Flush_TX

Symbol Flush_Rx =226'%1110 0010 Commande Flush_RX

 

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Symbol Rx_W_Pld   =b10'Nombre de Bytes dans le RX_FIFO apres commande R_RX_PL_WID

Symbol i          =b11'Dynamic Var

Symbol Read_Rx_Payload =%01100001' Command Byte - See COMMANDs datasheet

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

 

 

}

Dirs:

'-----------------

{ 

Input C.4    'MISO In

Input B.2    'IRQ  In

Output C.5   'MOSI Out

Output C.3   'SCK  Out

Output B.1   'CE   Out

Output B.6   'CSN  Out

}

 

    Init:

'-------------

{

Setfreq m16

Hspisetup spimode00,spifast

High CSN     'Active low

Low CE

Gosub Efface_IRQ_Tx

 

Symbol Max_RT =16

Symbol Tx_DS =32

Symbol Rx_DR =64

 

Retry = 10' Nombre de boucles d'erreurs ACK avant d'arreter le systeme

 

Gosub Config_Registers

}

 

    MAIN:

'--------------

{

Gosub Power_On    'NRF24L01+  Power On

Pause 2000'Stab ON 

 

Sertxd (" +++ TX Data V.9 - All ACK - Polling_IRQ - TX to 6pipe - ALARM +++ Mode DPL + ACK_Pld ",cr,lf) 'Console Program identification

'Sertxd ( " +++ Mode Dynamic Payload Lenght Actived ! +++", cr, lf)

 

DO'Boucle Principal

Sertxd ("+++-+++++++++ Debut Boucle DO Principale +++++++++++++++++++++",cr,lf) 'DEBUG !

'----------------------------------------------------------------------------------------------

'Set Tx_address with the RX_Data Pipe to send data to:

' (Write-Tx-Addr = Reg.16 +32 =48  /  W_RX_ADDR_P0 = Reg.10 +32 =42)

'----------------------------------------------------------------------------------------------

     

#rem

Low CSN

 Hspiout (96) 'Commande Lecture R_RX_PL_WID

 Hspiin (Rx_W_Pld) 'in Var.b10

High CSN

sertxd (" TEST de d?but boucle: Nbre de Bytes eventuels dans RX FIFO: ", #Rx_W_Pld, cr,lf)     

#endrem

     

'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Count_Do =0

TX_Pak =0'To Pipe_0

DO' Boucle TX1

'Set Tx address with the RX_ADDR_Pipe_0 of the RX concerned

 

Low CSN 'LSB First !

Hspiout (Write_Tx_Addr,120,120,120,120,120) 'RX_ADDR_P0 of the concerned RX

High CSN

 

'Set same RX_ADDR_0 of TX (Reg.nr10) to receive ACK

Low csn 'LSB First !

Hspiout (W_RX_ADDR_P0,120,120,120,120,120)  ' idem TX_ADDR

High CSN

 

'Write Data to TX FIFO (Number of Byte must match with

Low CSN

Hspiout (Write_TX_Payload,11,221,231,241,171)    'Write 5 bytes to Tx FIFO (255 MAX per Byte !)

High CSN

 

Pulsout CE,10'TRANSMIT 1  >>>>>>>>>>>>>>>>>>>>>>>>>>>>>

'Sertxd("Transmit to RX_Pipe_0. Waiting ACK ...",cr,lf) 'DEBUG !

 

Gosub Wait_ACK

 

If TestACK = 1 then'TestACK=OK

EXIT

Else

Pause 500'Attente de "reparation"

Gosub Lost_Pak

Sertxd (" Retry/")

inc Count_Do

if Count_Do > Retry Then

Gosub Alarm_Msg   

Endif

Endif

 

LOOP'Boucle TX1

Count_Do = 0

'------------------------------------------------------------------------------------

 

TX_Pak = 1'To Pipe_1

DO' Boucle TX2

'Set TX_ADDR with the RX_ADDR_Pipe_1 of the RX concerned

 

Low CSN 'LSB First !

Hspiout (Write_Tx_Addr,241,182,181,180,179) 'RX_ADDR_P1 of the concerned RX

High CSN

 

'Set same RX_ADDR_0 of TX to receive ACK

Low CSN 'LSB First !

Hspiout (W_RX_ADDR_P0,241,182,181,180,179) ' idem TX_ADDR

High CSN

 

'Write Data to TX FIFO

Low CSN

Hspiout (Write_TX_Payload,22,192,232,172,142,2,12,22,32,42)    'Write 10 bytes to Tx FIFO (255 MAX per Byte !)

High CSN

 

Pulsout CE,10'TRANSMIT 2  >>>>>>>>>>>>>>>>>>>>>>>>>>>>>

'Sertxd("Transmit to RX_Pipe_1. Waiting ACK ...",cr,lf) 'DEBUG !

 

Gosub Wait_ACK

 

If TestACK = 1then'TestACK=OK

EXIT

Else

Pause 500'Attente de "reparation"

Gosub Lost_Pak

inc Count_Do

if Count_Do > Retry Then

Gosub Alarm_Msg

Else

Sertxd (" Retry/")     

Endif

Endif

LOOP'Boucle TX2

Count_Do =0

'------------------------------------------------------------------------------------

 

TX_Pak =2'To Pipe_2

DO' Boucle TX3

'Set TX_ADDR with the RX_ADDR_Pipe_2 of the RX concerned

 

Low CSN 'LSB First !

Hspiout (Write_Tx_Addr) :   Hspiout (205,182,181,180,179) 'RX_ADDR_P2 of the concerned RX

High CSN

 

'Set same RX_ADDR_0 of TX to receive ACK

Low CSN 'LSB First !

Hspiout (W_RX_ADDR_P0,205,182,181,180,179)  ' idem TX_ADDR

High CSN 

 

'Write Data to TX FIFO

Low CSN

Hspiout (Write_TX_Payload,33,173,193,183,143,3,13,23,33,43,53,63,73,83,93,103,113,123,133,143,33,43,53,63,73,83,93,103,113,123,133,143)    'Write 32 bytes to Tx FIFO (255 MAX per Byte !)

High CSN

 

Pulsout CE,10'TRANSMIT 3  >>>>>>>>>>>>>>>>>>>>>>>>>>>>>

'Sertxd("Transmit to RX_Pipe_2. Waiting ACK ...",cr,lf) 'DEBUG !

 

Gosub Wait_ACK

 

If TestACK = 1 then'TestACK=OK

'Sertxd (" EXIT TX1 - Je continue a emettre ...",cr,lf) 'DEBUG !

EXIT

Else

'Sertxd (" Attente de reparation ...",cr,lf) 'DEBUG !     

Pause 500'Attente de "reparation"

Gosub Lost_Pak

inc Count_Do

if Count_Do > Retry Then

Gosub Alarm_Msg

Else

Sertxd (" Retry/")     

Endif

Endif

LOOP'Boucle TX3

Count_Do =0

'------------------------------------------------------------------------------------

 

TX_Pak =3'To Pipe_3

DO' Boucle TX4

'Set TX_ADDR with the RX_ADDR_Pipe_3 of the RX concerned

 

Low CSN 'LSB First !

Hspiout (Write_Tx_Addr,163,182,181,180,179) 'RX_ADDR_P3 of the concerned RX

High CSN

 

'Set same RX_ADDR_0 of TX to receive ACK

Low CSN 'LSB First !

Hspiout (W_RX_ADDR_P0,163,182,181,180,179)  ' idem TX_ADDR

High CSN

 

'Write Data to TX FIFO

Low CSN

Hspiout (Write_TX_Payload,44,184,144,184,114,4,14,24,34,114)    'Write 10 bytes to Tx FIFO (255 MAX per Byte !)

High CSN  

 

Pulsout CE,10'TRANSMIT 4  >>>>>>>>>>>>>>>>>>>>>>>>>>>>>

'Sertxd("Transmit to RX_Pipe_3. Waiting ACK ...",cr,lf) 'DEBUG !

 

Gosub Wait_ACK

 

If TestACK = 1 then'TestACK=OK

EXIT

Else

Pause 500'Attente de "reparation"

Gosub Lost_Pak

inc Count_Do

if Count_Do > Retry Then

Gosub Alarm_Msg

Else

Sertxd (" Retry/")     

Endif

Endif

LOOP'Boucle TX4

Count_Do =0

'------------------------------------------------------------------------------------

 

TX_Pak = 4'To Pipe_4

DO' Boucle TX5

'Set TX_ADDR with the RX_ADDR_Pipe_4 of the RX concerned

 

Low CSN 'LSB First !

Hspiout (Write_Tx_Addr,15,182,181,180,179) 'RX_ADDR_P4 of the concerned RX

High CSN

 

'Set same RX_ADDR_0 of TX to receive ACK

Low CSN 'LSB First !

Hspiout (W_RX_ADDR_P0,15,182,181,180,179)  ' idem TX_ADDR

High CSN

 

'Write Data to TX FIFO

Low CSN

Hspiout (Write_TX_Payload,55,105,215,115,215,225,235,115) 'Write 8 bytes to Tx FIFO (255 MAX per Byte !)

'Hspiout (W_ACK_Payload_P4,55,105,215,115,215,225,235) 'Write 7 bytes to Tx FIFO (255 MAX per Byte !)

High CSN   

 

Pulsout CE,10'TRANSMIT 5  >>>>>>>>>>>>>>>>>>>>>>>>>>>>>

'Sertxd("Transmit to RX_Pipe_4. Waiting ACK ...",cr,lf) 'DEBUG !

 

Gosub Wait_ACK

 

If TestACK = 1 then'TestACK=OK

EXIT

Else

Pause500'Attente de "reparation"

Gosub Lost_Pak

inc Count_Do

if Count_Do > Retry Then

Gosub Alarm_Msg

Else

Sertxd (" Retry/")     

Endif

Endif

LOOP'Boucle TX5

Count_Do =0

'------------------------------------------------------------------------------------

 

TX_Pak = 5'To Pipe_5

DO' Boucle TX6

'Set TX_ADDR with the RX_ADDR_Pipe_5 of the RX concerned

 

Low CSN 'LSB First !

Hspiout (Write_Tx_Addr,5,182,181,180,179) 'RX_ADDR_P5 of the concerned RX

High CSN

 

'Set same RX_ADDR_0 of TX to receive ACK

Low CSN 'LSB First !

Hspiout (W_RX_ADDR_P0,5,182,181,180,179)  ' idem TX_ADDR

High CSN

 

'Write Data to TX FIFO

Low CSN

Hspiout (Write_TX_Payload,66,176,116,116,136,106,16,126,36,146,56,166)    'Write 12 bytes to Tx FIFO (255 MAX per Byte !)

High CSN 

 

Pulsout CE,10'TRANSMIT 6  >>>>>>>>>>>>>>>>>>>>>>>>>>>>>

'Sertxd("Transmit to RX_Pipe_5. Waiting ACK ...",cr,lf) 'DEBUG !

 

Gosub Wait_ACK

 

If TestACK = 1 then'TestACK=OK

EXIT

Else

Pause500'Attente de "reparation"

Gosub Lost_Pak

inc Count_Do

if Count_Do > Retry Then

Gosub Alarm_Msg

Else

Sertxd (" Retry/")     

Endif

Endif

LOOP'Boucle TX6

Count_Do =0

'------------------------------------------------------------------------------------

 

LOOP' Boucle Principale

}

'*************************************************************************************

'****   SUBROUTINES   ****************************************************************

'*************************************************************************************

 

Config_Registers:

{

'Write Register 0 -> CONFIG

'Enable PtX, Power Off, En_CRC/2Bytes,  Interrupts Unmasked

Low CSN                       

Hspiout (32,%00011100) '($20,%00001100)

High CSN

Pause1

 

;Write Register 1 -> EN_AA

Low CSN                        

Hspiout (33,%00111111)  ;Enable all ACK

High CSN

 

;Write register 2 -> EN_RXADDR

Low CSN                       

Hspiout (34,%00111111) '  Enable all Pipes

High CSN                  ' All Pipes can receive Data

Pause 1

 

;Write Register 3 -> SETUP_AW

Low CSN                       

Hspiout (35,%00000011) '  RX Address width = 5 bytes wide

High CSN

 

;Write Register 4 -> SETUP_RETR

Low CSN                        

'Hspiout ($24,%00010000) '//ARC Disbled/  ARDelay = 500u

'Hspiout ($24,%00100000) '//ARC Disbled/  ARDelay = 750u

'Hspiout ($24,%00011111) '//ARC Enabled 15x/  ARDelay = 500u

Hspiout (36,%00101111) '//ARC Enabled 15x/  ARDelay = 750u 

High CSN

 

'Write Register 5 -> RF_CH

Low CSN                        

Hspiout (37,%00000010) '// RF channel = 2  (illegal after 83 !)

High CSN                ' Receiver must match

 

 

'Write Register 6 -> RF_SETUP

Low CSN

Hspiout (38,%00000110)  'REG 6  Data Rate  1 mbps

High CSN

 

 

'Write Regiters 17 - 22    > RX_PW_P0 to P5  Payload Width 

for b0 = 49 to 54'Reg Address + 32 decimal to Write

Low CSN                    'Could also do this in hex  

Hspiout (b0,5)            'Pipe_0 - Pipe_5  Payload Width = 5

High CSN

next b0

 

'Reg 28 "DYNPD"

Low CSN                       

'Hspiout (60,%00000000) 'Default Values

Hspiout (60,%00111111) 'When enabled,

'Hspiout (60,%00000111)

High CSN

 

'Write Register 29 "Feature Register"     

Low CSN                        

Hspiout (61,%00000000) 'Default Values

'Hspiout (61,%00000001)

'Hspiout (61,%00000111)

Hspiout (61,%00000111)  '110

High CSN

 

Return

}

'------------------------------------------------------------------------------------

 

Wait_ACK:

{

' IRQ/ACK TESTs ---------------------

' Suivant le resultat du test ACK, on prendra la decision suivante:

' - Retry l'emission du paquet (Variable Retry). Au terme des Retry,afficher un message

'   d'alerte systeme et stopper le systeme. Cette situaton surviendait, par exemple,

'    en cas de defaillance permanente du RX cible (Never ACK received)

 

Pause 150

 

TestACK = 1' TestACK =1=OK  Reinit Var.

 

Timeout = 0' Remise a zero du compteur de "Time-Out" d'ACK

DO ' Boucle d'attente de l'ACK

If IRQ = 0 Then' Teste si la broche d'interruption est active

Gosub Lit_Status    ' lecture du registre "STATUS"

 

    Testirq = Data1 and %01110000' Extraction des 3 bits d'interruption. DAta1 = STATUS

Select Testirq      ' Test sur les differentes possibilites d'IRQ

 

Case Max_RT       ' Il s'agit de l'interruption "MAX_RT"

Sertxd (" /// Nbre max.d'essais d'emission de TX_",#TX_Pak, " atteint, Effacement TX Buffer :-(",CR,LF)

        TestACK = 0'Test=BAD

'Gosub Efface_Tx ' Effacement du buffer d'emission

      'Low CSN : Hspiout (Flush_tx) : High CSN

'Gosub Efface_IRQ_Tx ' Effacement de l'interuption "MAX_RT"

EXIT' Sortie de la boucle d'attente de l'ACK -----------------------------------> EXIT

 

      Case Tx_DS        ' Il s'agit de l'interruption "TX_DS" (ACK recu)

Sertxd ("---> Paquet TX_",#TX_Pak, " envoye et ACK recu, Time Out=",#timeout," :-))",CR,LF)

'Gosub Efface_IRQ_Tx ' Effacement de l'interruption "MAX_RT"

'TestACK=1 'Test=OK

      EXIT' Sortie de la boucle d'attente de l'ACK -----------------------------------> EXIT

 

Case 96' Il s'agit de l'interruption "TX_DS"(ACK recu)+ Data in RX_FIFO

Sertxd ("---> Paquet TX_",#TX_Pak, " envoye et ACK recu, Time Out=",#timeout," :-))",CR,LF)

      gosub ACKPLD

'Gosub Efface_IRQ_Tx ' Effacement de l'interruption "MAX_RT"

'TestACK=1 'Test=OK

      EXIT' Sortie de la boucle d'attente de l'ACK -----------------------------------> EXIT

 

 

Else' Il s'agit d'une autre interruption

Sertxd (" / Autre IRQ = ",#Testirq," pour TX_",#TX_Pak,CR,LF)

        TestACK = 0'Test=BAD

'Gosub Efface_Tx ' Effacement du buffer d'emission

      'Low CSN : Hspiout (Flush_tx) : High CSN

'Gosub Efface_IRQ_Tx ' Effacement de l'interruption "MAX_RT"

EndSelect' Fin du test des differentes possibilites d'IRQ

End If' Fin du test de la broche IRQ

 

Pause 1' Attente de 1ms pour activer le "Time Out" a 100msec

Inc Timeout           ' Incrementation du compteur de "Time Out"

 

' TimeOut Max = 255 (1 Byte !)

If Timeout = 100Then' Si le temps d'attente depasse 100ms

Sertxd (" ////// Pas d'ACK pour TX_",#TX_Pak, " venant du recepteur dans les 100ms :?((",CR,LF)

    TestACK =0'Test= BAD

            'Gosub Efface_IRQ_Tx ' Effacement de l'interruption "MAX_RT"

EXIT' Sortie de la boucle d'attente des 100ms ----------------------------------> EXIT

End If' Fin du test de "Time out"

LOOP' Fin de la boucle d'attente de l'ACK

 

 

Gosub Efface_IRQ_Tx

Low CSN : Hspiout (Flush_Tx) : High CSN

 

Pause 100

Return

}

'------------------------------------------------------------------------------------

 

ACKPLD:

 

' Lecture du RX FIFO pour voir message eventuellement joint par le RX ? son ACK ''''''''''''''''''''''''''''''''''''''''''''''''''''''

 

'Read Width of RX_Payload with the R_RXPL_WID Command. Command to use if Dynamic Payload Length is enabled!

Low CSN

Hspiout (96) 'Commande R_RX_PL_WID

Hspiin (Rx_W_Pld) 'in Var.b5

High CSN

 

'sertxd (" xxxxxxxxxx Nbre de Byte in RX FIFO: ", #Rx_W_DPL, cr,lf)

 

Low CE  'Receiver disconnected

 

'Le PICAXE ne gerant pas les variable indicee, on va utiliser la ScratchPadRAM et son pointeur sera utilise comme indiceur.

i = 1

 

Low CSN

'  LECTURE DE RX_FIFO !!!

'-----------------------------

Hspiout (Read_Rx_Payload) ' On doit lire dans le RX_FIFO le nombre exact de Bytes recus (b5 = RX_W_DPL)

Ptr = 1'Pointeur de la ScratchPad RAM

For i = 1 to Rx_W_Pld 'On ECRIT, dans la ScratchPadRAM, autant de bytes que RX_W_DPL

Hspiin (@ptrinc)

Next i

High CSN

 

'sertxd ("Nbre de Bytes recus dans RX FIFO: ", #Rx_W_Pld, cr,lf)

 

'  AFFICHAGE DES OCTETS RECUS

'-------------------------------

 

sertxd (" //////////// ATTENTION, Il y a un message joint a l'ACK recu = [")

for ptr = 1 to Rx_W_Pld'

sertxd (@ptr) 'renvoie les caract?res sur le port serie

nextptr

Sertxd ("]",cr, lf)

 

 

#rem

'TEST de nettoyage du RX FIFO

 

'Read Width of RX_Payload with the R_RXPL_WID Command. Command to use if Dynamic Payload Length is enabled!

Low CSN

 Hspiout (96) 'Commande R_RX_PL_WID

 Hspiin (Rx_W_Pld) 'in Var.b10

High CSN

sertxd (" Nbre de Bytes restant dans RX FIFO apres lecture: ", #Rx_W_Pld, cr,lf)

 

Low CSN : Hspiout (Flush_Rx) : High CSN  ' Flush_Rx

 

Low CSN

 Hspiout (96) 'Commande Lecture R_RX_PL_WID

 Hspiin (Rx_W_Pld) 'in Var.b10

High CSN

sertxd (" Nbre de Bytes restant dans RX FIFO APRES FLUSH RX: ", #Rx_W_Pld, cr,lf)

#endrem

 

 

'Low CSN : Hspiout (226) : High CSN  ' Flush_Rx ... qui en principe est vide de par sa lecture. Confirme ci-dessus ! Donc, Flush_RX inutile.

 

return

'------------------------------------------------------------------------------------ 

 

 

Alarm_Msg:

{

Sertxd(cr,lf,"   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", cr,lf,_

"   !           !!! FAIL ALARM - SYSTEM STOPPED !!!              !",cr,lf,_

            "   !            Aucun ACK pour l'envoi du TX_PAK_",#TX_Pak,"              !",cr,lf,_

            "   !               Verifiez votre installation ...              !",cr,lf,_

            "   !  >>>>>  Ou faites appel a un technicien competent   <<<<<  !",cr,lf,_

            "   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!",cr,lf)

Gosub Power_Off

STOP

return

}

'------------------------------------------------------------------------------------

 

Lost_Pak:

{

 

'Lecture de PLOS_CNT, bits 4 a 7 du registre OBSERVE_TX nr8

Low CSN

Hspiout(8) 'Read OBSERVE_TX Reg.nr 8

Hspiin (Data1) 'b0 = Data1

High Csn

 

' Extraction des 4 bits  de PLOS_CNT  

  LostPak = Data1 and%11110000

'Data1 = LostPak

  LostPak = LostPak /16'Decalage de 4 bits vers la droite

 

Sertxd ("      Count Lost Packets = ", #LostPak, cr,lf)

if LostPak = 15 then

sertxd ("       xxxxx RESET Lost Packets Counter !!! xxxxxx",cr,lf) ' by writing in RF_CH reg.5 !

Pause 3500' Visu Console

Low CSN                        

Hspiout (37,%00000010) '// RF channel = 2  (illegal after 83 !)

High CSN                ' Receiver must match

End if

Return

}

'------------------------------------------------------------------------------------ 

 

Power_On:

{

Addr = CONFIG

Low CSN

Hspiout (Addr)

Hspiin (Data1)

High CSN

 

Let Bit1 = 1

Addr = Config +32'Write

Low CSN

Hspiout (Addr,Data1)

High CSN

return

}    'Turn NRF24L01 Power On

'------------------------------------------------------------------------------------

 

Power_Off:

{

Addr = CONFIG

Low CSN

Hspiout (Addr)

Hspiin (Data1)

High CSN

 

Let Bit1 = 0

Addr = Config +32  'Write

Low CSN

Hspiout (Addr,Data1)

High CSN

return

}    'Turn NRF24L01 Power Off

'------------------------------------------------------------------------------------

 

 

Read_All: 'Not used - ONLY ON TEST PHASE

{

Sertxd (CR,LF,"Reg.values in dec.format",CR,LF)

for b1 = 0 to 09  'registers 0 - 9 (decimal)   

Low CSN

Hspiout (b1)

Hspiin (b0)

High CSN

Gosub Serial_Out1

next b1

 

for b1 = 10 to 16'Addresses with 5 byte registers

Low CSN

Hspiout (b1)

Hspiin (b4,b5,b6,b7,b8)

High csn

Sertxd ("Register ",#b1," = ", #b8,#b7,#b6,#b5,#b4,CR,LF)

next b1

 

for b1 = 17 to 22

Low CSN

Hspiout (b1)

Hspiin (b0)

High CSN

Sertxd ("Register ",#b1," = ", #b0,cr,lf)

next b1

 

Low CSN

b1 = 23

Low CSN

Hspiout (b1)

Hspiin (b0)

High CSN

Gosub Serial_Out1

 

Low CSN

b1 = 28

Hspiout (b1)

Hspiin (b0)

High CSN

Gosub Serial_Out1

 

inc b1'b1 = 29

Low CSN

Hspiout (b1)

Hspiin (b0)

High CSN

Gosub Serial_Out1

 

Sertxd ("---- END OF DUMP -------",cr,lf)

Return

}   'Read all NRF24L01 all registers and sertxd out

'------------------------------------------------------------------------------------

Serial_Out1:

{

Sertxd ("Register ",#b1," = ", #bit7,#bit6,#bit5,#bit4,#bit3,#bit2,#bit1,#bit0,CR,LF)

Return

} 'Used by Read_all 

'------------------------------------------------------------------------------------

 

Lit_Status:

{

Low CSN

Hspiout(STATUS)

Hspiin (Data1) 'b0 = Data1

High Csn

Return

}

'------------------------------------------------------------------------------------

 

Efface_IRQ_Tx:         ' Effacement des IRQs d'emission 

{                      ' --------------------------------

'Bit6: DataReady RX_FIFO IRQ

'Bit5: Data sent TX_FIFO IRQ

'Bit4: Max of TX retries IRQ

 

Low CSN

Hspiout(39,%01110000)  'hspiout(39,%00110000)???

High CSN

Return' Fin de la routine effacement des IRQs TX

}

'-------------------------------------------------------------------------------------------------

 

       Programme RX.6

 

Ce programme explore toutes les possibilités du nRF24L01+:

  - Réception dans les 6 pipes ayant des adresses personnalisées
  - Affichage des octets reçus
  - Adjonction d'un message à l'ACK retourné vers le TX
  - Activation du Mode Dynamic Payload Length
  - Activation des Payload avec ACK

Il est à combiner avec le programme TX.9, édité juste ci-dessus. 

' RX_06

' RX_ADDR avec PERSONALS Values

' RX par scan IRQ (No Mask_IRQ)

' Enable All ACK

' Reception dans les 6 pipes

' Mode Dynamic Payload Length (DPL)

' Adjonction d'un message à l'ACK transmis vers le TX

' Shield sur Picaxe Axe401

' A combiner avec TX9 (All ACK, ...)

' Roger LEGAT - Janvier 2017 - PICAXE Basic

 

'* Raccordement des modules                                               *

'* ------------------------                                               *

'* Le picaxe utilise est un 28X2/16Mhz sur carte AXE401 (Arduino Layout)  *

'* Le module nRF24L01+ y est raccorde avec un Arduino Proto Shield        *

'* On utilise un module d'adaptation tension (5V to 3,3v)                 *

'*                                                                        *

'*    AXE401    | 28X2              | Adapt | nRF24L01+        | Dir      *

'*    ----------+-------------------+-------+-------------------------    *

'*    S.2 (B.2) | Pin 23 - B.2      | Pin 6 | IRQ (10K Pullup) | In       *

'*    S.11(C.5) | Pin 16 - HSPI SDO | Pin 4 | MOSI             | Out      *

'*    S.13(C.3) | Pin 14 - HSPI SCK | Pin 3 | SCK              | Out      *

'*    S.12(C.4) | Pin 15 - HSPI SDI | Pin 5 | MISO             | In       *

'*    S.6 (B.6) | Pin 27 - B.6      | Pin 2 | CSN              | Out      *

'*    S.4 (B.1) | Pin 22 - B.1      | Pin 1 | CE               | Out      *

'*    ----------+-------------------+-------+--------------------------   *

'*    5V        | Pin 20 - +V       | VCC   | ->3V3            | Pwr+     *

'*    GND       | Pin 19 - 0V       | GND   | GND              | Pwr-     *

'*                                                                        *

'**************************************************************************

 

'  RX_ADDR_Pipes -  PERSONALS Values (NO Default Values !)

'-------------+-----+-----+-----+-----+-----+

'             | B4  | B3  | B2  | B1  | LSB |

'-------------+-----+-----+-----+-----+-----+

'  TX_ADDR    |  -  |  -  |  -  |  -  |  -  | (For TX Mode !)

'=============+=====+=====+=====+=====+=====+==============================

' RX_ADDR_P0  | 120 | 120 | 120 | 120 | 120 |

'-------------+-----+-----+-----+-----+-----+   Addresses of the 6 pipes

' RX_ADDR_P1  | 179 | 180 | 181 | 182 | 241 |

'-------------+--v--+--v--+--v--+--v--+-----+       of this RX

' RX_ADDR_P2  |                       | 205 |

' RX_ADDR_P3  | NEVER set these bytes | 163 |

' RX_ADDR_P4  |    in RX Program !    |  15 |

' RX_ADDR_P5  |                       |   5 |

'-------------+-----+-----+-----+-----+-----+

 

'   Mode Control nRF24L01+

'----------------------------

' Configure all registers correctly(ACK, Pipes Enable and Lenght Addr., Re-Transmit, Delay, RF Channel and Power, ...)

' Set Power On/Off and Tx/Rx Mode with the CONFIG Register

'

' CE in TX Mode: Always set to Low

'   To transmit 1) Load TX_FIFO Buffer

'               2) Set CE High during 10us and return set CE Low. (Pulsout 10us)

 

' CE in RX Mode: Always set to High for waiting data

'                 Offline if CE is Low (disconnected from the radio network !)

'

' CSN: Always set to High. Set Low to active SPI bus

'

'

' Console: Set to 19200 Bauds

'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'

 

 

#Picaxe 28x2

#No_Table

#No_Data

 

   Variables:

'-----------------

{         

Symbol Config =0  'Address of CONFIG Register 

Symbol Status =7'Address of STATUS Register

 

 

Symbol W_RX_ADDR_P0 =42'Pour la Configuration des Adresses des RX_Pipes Reg.10 a 15

Symbol W_RX_ADDR_P1 =43'43 = Reg.11 +32 (Write Commande)

Symbol W_RX_ADDR_P2 =44

Symbol W_RX_ADDR_P3 =45

Symbol W_RX_ADDR_P4 =46

Symbol W_RX_ADDR_P5 =47

 

Symbol W_ACK_Pld_P0 =168

 

Symbol Data1      =b0 'Dynamic Var

Symbol Addr       =b1 'Pour l'adressage du registre [Hspiout (ADDR)]

Symbol R_RX_Pld_W =b2 'Read RX_Payload Width avec la commande R_RX_PLWID (=96)

Symbol Reg        =b3 'Pour adressage des registres 17 a 22 (RX_PW_P0 a 5)

Symbol RX_W       =b4 'Nombre de Bytes dans le RX_FIFO apres lecture des Reg.17 a 22

Symbol Rx_W_DPL   =b5 'Nombre de Bytes dans le RX_FIFO apres commande R_RX_PL_WID

Symbol i          =b6 'Dynamic Var

 

 

Symbol CE B.1 'Chip Enable

Symbol CSN = B.6 'Chip Select Active low

Symbol IRQ = pinB.2

 

Symbol Read_Rx_Payload =%01100001  'Command Byte - See COMMANDs datasheet

}

 

Dirs:

'-----------------

{ 

Input  C.4   'MISO In

Input  B.2   'IRQ  In

Output C.5   'MOSI Out

Output C.3   'SCK  Out

Output B.1   'CE   Out

Output B.6   'CSN  Out

}

 

   Init:

'-----------

{

Setfreq m16

Hspisetup spimode00,spifast

High CSN     'Active low

Low CE

 

Gosub Config_RX_ADDRS  'RX_ADDR_Pipes Definitions

Gosub Config_Registers

}

 

Pause 1000

 

    MAIN:

'-------------

 

Low CSN

Hspiout (%00100000,%00001111)    'Write to config register'  EN PRX + Power ON

High CSN

 

Sertxd (" +++ RX Data V.6 - 6pipes - Polling_IRQ - All_ACK - Def.RX_ADDR +++ Mode DPL + ACK_Pld ",cr,lf) 'Console Programm identification

'Sertxd ( " +++ Mode Dynamic Payload Lenght Actived ! +++", cr, lf)

Gosub RX_ADDR_List ' Listing Consol of the RX_ADDR_Pipes of this RX

 

'Gosub Read_All   'Dump Registers if needed, for debugging

Gosub Clear_Interrupts

 

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Low CSN

Hspiout (W_ACK_Pld_P0, "From RX Garage")

High CSN

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

 

DO

     

High CE ' RECEIVER ENABLED and waiting for interrupt

Pause 2

'sertxd ("Waiting IRQ ...",cr,lf) 'DEBUG !

 

if IRQ = 0 then

 

      sertxd ("-IRQ Actived ! --->  Data1 = ", #Data1, "  ---> ")  'DEBUG !

      Low CE

      'DO 'Jusqu'a ce que la valeur du bit RX_EMPTY soit = 1 (RX_Empty = bit

      Gosub Lecture_RX

'LOOP Until bit0=1 'Bit0 ---> bit0 de la variable b0 ---> Au debut de la boucle DO valeur a prendre en compte), il vaut ???????

 

'Sertxd (" Sortie de la boucle DO_LOOP/UNTIL ...",cr,lf)  'DEBUG

 

Gosub Clear_Interrupts

 

High CE ' RECEIVER re-ENABLED and waiting for interrupt

Pause 2

Else

'sertxd ("IRQ Not Actived !",cr,lf) 'DEBUG !

End if

LOOP

 

END

'STOP

 

'*********************************************************************

'****  SUBROUTINES  **************************************************

'*********************************************************************

 

Config_RX_ADDRS:

{

' RX_ADDR_PIPES: (PERSONALS Values: See Table above)

'-----------------------------------------------------

 

Low CSN  'RX_ADDR_P0 has 5 Bytes

Hspiout (W_RX_ADDR_P0,120,120,120,120,120)  'RX_ADDR_P0  Reg.nr10 'PERSONAL Values RX_Addr Pipe_0, LSB First!

High CSN : Pause1

 

Low CSN  'RX_ADDR_P1 has 5 Bytes

Hspiout (W_RX_ADDR_P1,241,182,181,180,179)  'RX_ADDR_P1  Reg.nr11 'PERSONAL Values RX_Addr Pipe_1, LSB First!

High CSN : Pause1

 

Low CSN  'RX_ADDR_P2 has only 1 LSB-Byte !

Hspiout (W_RX_ADDR_P2,205)                  'RX_ADDR_P2  Reg.nr12 'PERSONAL Valuest RX_Addr Pipe_2, LSB ONLY !!

High CSN : Pause1

 

Low CSN  'RX_ADDR_P3 has only 1 LSB-Byte !

Hspiout (W_RX_ADDR_P3,163)                  'RX_ADDR_P3  Reg.nr13 'PERSONAL Values RX_Addr Pipe_3, LSB ONLY !!

High CSN : Pause1

 

Low CSN  'RX_ADDR_P4 has only 1 LSB-Byte !

Hspiout (W_RX_ADDR_P4,15)                   'RX_ADDR_P4  Reg.nr14 'PERSONAL Values RX_Addr Pipe_4, LSB ONLY !!

High CSN : Pause1

 

Low CSN  'RX_ADDR_P5 has only 1 LSB-Byte !

Hspiout (W_RX_ADDR_P5,5)                    'RX_ADDR_P5  Reg.nr15 'PERSONAL Values RX_Addr Pipe_5, LSB ONLY !!

High CSN : Pause1

 

Return

}

'--------------------------------------------------------------------------------------------------

 

 

RX_ADDR_List:  ' To Console Identification

{

Sertxd("-----------------------------------------------------------",cr,lf,_

"     RX_ADDR_Pipes Listing - (Personal Values) ",cr,lf,_

"-----------------------------------------------------------",cr,lf)

for b1 = 10 to 11'RX_ADDR_Pipes

Low CSN

Hspiout (b1)

Hspiin (b4,b5,b6,b7,b8)

High CSN

Sertxd ("  Register ",#b1," =    ", #b8," / ",#b7," / ",#b6," / ",#b5," / ",#b4,CR,lf)

next b1

 

for b1 = 12 to 15'RX_ADDR_Pipes

Low CSN

Hspiout (b1)

Hspiin (b4,b5,b6,b7,b8)

High CSN

Sertxd ("  Register ",#b1," =  ( ", #b8," / ",#b7," / ",#b6," / ",#b5," ) ",#b4,CR,lf)

next b1

 

Sertxd ("-----------------------------------------------------------",cr,LF)

Return

}

'--------------------------------------------------------------------------------------------------

 

Lecture_RX: 'Called when IRQ pin = 0

{

'Low CSN

 

Data1 = 0

Addr = STATUS 

Low CSN

Hspiout (Addr)   'b1 (Var.ADDR)

Hspiin (Data1)   'b0 (Var.Data1) = Status  Bit 1,2,3 = Data pipe number for the payload available for reading from RX_FIFO

High CSN

 

b1 = 0

Let bit8  = bit1

Let bit9  = bit2

Let bit10 = bit3' Now, b1(Var.ADDR) = RX_Payload number (0 to 5)

 

'Read Width of RX_Payload by adressing Reg.nr 17 to 22. Normaly, NO CARE if Dynamic Payload length is actived !

Low CSN

Reg = Addr +17'because Reg. RX_ADDR_P0 = 17

Hspiout (Reg) ' Reg = Var.b3 Adressing Reg.nr 17 to 22

Hspiin (Rx_W) ' in Var.b4 ----> toujours egal a 5 qui est la valeur indiquee dans la config des reg.17 a 22 !!!

High CSN

 

'Read Width of RX_Payload with the R_RXPL_WID Command. Command to use if Dynamic Payload Length is enabled!

Low CSN

Hspiout (96) 'Commande R_RX_PL_WID

Hspiin (Rx_W_DPL) 'in Var.b5

High CSN

 

' Ici, on  connait le nr de pipe qui a recu des datas (b1=ADDR) et

' le nombre de bytes a traiter (b4 = RX_W  ou  b5 = RX_W_DPL)

 

 

Sertxd ("Data in Pipe_", #b1,"    - Bytes received= ", #b5, " / ", #b4, cr,lf) ' !!!! 2 x b4 !!!!!!!!!!!!!!! ERROR

 

Low CE  'Receiver disconnected

 

'Le PICAXE ne gerant pas les variable indicee, on va utiliser la ScratchPadRAM et son pointeur sera utilise comme indiceur.

i = 1

 

Low CSN

'  LECTURE DE RX_FIFO !!!

'-----------------------------

Hspiout (Read_Rx_Payload) ' On doit lire dans le RX_FIFO le nombre exact de Bytes recus (b5 = RX_W_DPL)

Ptr = 1'Pointeur de la ScratchPad RAM

For i = 1 to Rx_W_DPL 'On ECRIT, dans la ScratchPadRAM, autant de bytes que RX_W_DPL

Hspiin (@ptrinc)

Next i

High CSN

 

 

'  AFFICHAGE DES OCTETS RECUS

'-------------------------------

Ptr = 1

i = Ptr

Sertxd ("In RX_Pipe_",#ADDR," :  ---> / ")

For i = 1 to Rx_W_DPL     'On LIT, dans la ScratchPadRAM, autant de bytes que RX_W_DPL

Sertxd (#@ptrinc, " / ")

Next i

Sertxd (cr,lf)

 

Low CSN : Hspiout (226) : High CSN  ' Flush_Rx ... qui en principe est vide de par sa lecture. Confirme ci-dessus ! Donc, Flush_RX inutile.

 

'   VERIFICATION for TEST Phase

'------------------------------------

' !!! En principe, RX_FIFO devrait etre vide apres lecture complete...

' Read Width of RX_Payload with the R_RXPL_WID Command. Command to use if Dynamic Payload Length is enabled!

Low CSN

Hspiout (96) 'Commande R_RX_PL_WID

Hspiin (Rx_W_DPL) 'in Var.b5

High CSN

sertxd (" ---> Etat du RX_FIFO apres lecture ! = ",#b5,cr,lf)

' MAIS il ne donne pas la valeur ZERO !???? Meme apres un Flush_RX !???

 

'Low CSN : Hspiout (226) : High CSN  ' Flush_Rx ... qui en principe est vide de par sa lecture. Voir ci-dessus ! Donc, Flush_RX inutile ?

 

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Low CSN

Hspiout (W_ACK_Pld_P0, "From RX Hangar")

High CSN

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

 

Return

}

'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

Config_Registers:

{

'Write register 0 -> CONFIG

'Enable Rx, Power Off, En_CRC/2Bytes,  Interrupts Unmasked

Low CSN                       

Hspiout (32,%00001101) 'nrReg +32, data

High CSN

Pause1

 

;Write register 1 -> EN_AA

Low CSN

'Hspiout (33,%00000000)   ;shockburst OFF (No ACK)

Hspiout (33,%00111111)   ;Enable all ACK

High CSN                          ;MUST be set same in PTX   

 

;Write register 2 -> EN_RXADDR  Enable Pipes 0 - 5 (all)

Low CSN

Hspiout (34,%00111111) 'Enable all pipe ($22,%00111111)

High CSN                        ' All Pipes can receive Data

 

;write register 3 -> SETUP_AW

Low CSN                       

Hspiout (35,%0000011) '  Pipe ID Address = 5 bytes wide

High CSN                       '  Default is 5 bytes wide     

Pause1

 

;Write register 4 -> SETUP_RETR

Low CSN                       

Hspiout (36,%00101111) '//ARC Enabled 15x/  ARDelay = 750u

'  Hspiout ($24,%00100000) '//ARC Disabled/  ARDelay = 750u

High CSN                ' See Datasheet 

 

'Write register 5 -> RF_CH

Low CSN                        

Hspiout (37,%00000010) '// RF channel = 2 

High CSN                ' Receiver must match

 

;Write register 6 -> RF_SETUP

Low CSN

Hspiout (38,%00000110)   ' REG 6  (Data Rate = 1 mbps)

High CSN

 

'Write Regiters 17 - 22 > RX_PW_P0 to P5  Payload Width 

for b0 = 49 to 54'Reg Address + 32 decimal to Write

Low CSN                    'Could also do this in hex  

Hspiout (b0,5)             'Pipe_0 - Pipe_5  Payload Width = 5 Byte

High CSN

next b0

 

 

'Reg 28 "DYNPD"

Low CSN                        

'Hspiout (60,%00000000) 'Default Values

Hspiout (60,%00111111) 'When enabled,

'Hspiout (60,%00000111)

High CSN

 

'Reg 29 "Feature Register"     

Low CSN                       

'Hspiout (61,%00000000) 'Default Values

'Hspiout (61,%00000001)

'Hspiout (61,%00000111)

Hspiout (61,%00000110)  '110

High CSN

Return

}  'Configure registers & set RX mode

'-----------------------------------------------------------------------------------

 

Clear_Interrupts:

{

'==========================================

'This function clears all NRF24L01 interrupts

'by clearing bits 4, 5, & 6 of register 7.

' while leaving the other bits unchanged &

'intact

'==========================================

Addr = STATUS      

Low CSN             

Hspiout (addr)  

Hspiin (data1)    'Read Status Register into B0 (data_1)   

High CSN

Let bit4 =1   'Max_RT  Max of retransm. Interrupt

Let bit5 =1   'TX_DS   Data Send TX Fifo Interrupt    

Let bit6 =1   'RX_DR   Data Ready RX Fifo Interrupt

'Pause 20'0

 

Addr = STATUS +32 'Write

low CSN

Hspiout (addr,data1)  'Write New Value of B0 to Status register)

High CSN

Return

 

} 'Clear NRF24L01 Interrupts

'-----------------------------------------------------------------------------------

 

 

Read_All:

{

sertxd (CR,LF,"Register values are in decimal format",CR,LF)

for b1 = 0 to 09'registers 0 - 9 (decimal)   

low CSN

hspiout (b1)

hspiin (b0)

high CSN

gosub serial_out1

next b1

 

for b1 = 10 to 16'Addresses with 5 byte registers

low CSN

hspiout (b1,1,2,3,4,5)

hspiin (b4,b5,b6,b7,b8)

high CSN

sertxd ("Register ",#b1," = ", #b4,#b5,#b6,#b7,#b8,CR,LF)

next b1

 

for b1 =17 to 22

low CSN

hspiout (b1)

hspiin (b0)

high CSN

sertxd ("Register ",#b1," = ", #b0,cr,lf)

next b1

 

low CSN

b1 = 23

low CSN

hspiout (b1)

hspiin (b0)

high CSN

gosub serial_out1

 

low CSN

b1 = 28

hspiout (b1)

hspiin (b0)

high CSN

gosub serial_out1

inc b1

low CSN

hspiout (b1)

hspiin (b0)

high CSN

gosub serial_out1

sertxd ("---- END OF DUMP -------",cr,lf)

return

}     'Read all NRF24L01 all registers and sertxd out

'-----------------------------------------------------------------------------------

 

Serial_Out1:

{

sertxd ("Register ",#b1," = ", #bit7,#bit6,#bit5,#bit4,#bit3,#bit2,#bit1,#bit0,CR,LF)

Return

}   'Used with read_all

'-----------------------------------------------------------------------------------

'===================================================================================

 

 

     Canaux d'émission - Les interférences WiFi et Bluetooth

Le nRF24L01p émet dans la plage de fréquence des 2,4Ghz en utilisant 128 canaux espacés de 1Mhz.
Il couvre ainsi les fréquences centrales de 2,400 Ghz à 2,527 Ghz, soit un spectre de 2,4000 Ghz à 2,5275 Ghz.

Il est important de savoir que cette gamme de fréquence est aussi celle utilisée par les canaux des réseaux WiFi et par ... les fours à micro-ondes (2,5Ghz)

Cette constatations peut expliquer les mauvaises performances de portée, dues à des interférences, en fonction des canaux utilisés.

Il pourra donc être très utile de préalablement scanner la plage de ces fréquences afin de choisir un canal "libre".

Les numéros par lesquels nous identifions les canaux Wifi ne correspondent cependant pas aux numéros de canaux utilisés par le nRF24L01p. 

Pour le comprendre aisément, prenons connaissance du spectre des canaux Wifi usuels ::


Nous remarquons d'emblée qu'il y a énormément de chevauchement possible entre les divers canaux WiFi.

Comme le protocole WiFi requiert une séparation de canal de 16, 25 à 22 MHz , les canaux adjacents se chevauchent et interfèrent fortement les uns avec les autres.
En mode Wifi, il est ainsi recommandé de laisser trois ou quatre canaux libres entre les canaux utilisés pour éviter les interférences. 

L'espacement exact requis dépend du protocole et du débit de données sélectionnés, ainsi que de l'environnement électromagnétique dans lequel l'équipement est utilisé.

Il est donc toujours fortement  conseillé de scanner son environnement afin de caler nos appareils wifi sur un canal le moins encombré possible.
A cette fin, de multiples applications sont désormais disponibles sur tablettes et smarphones (Wifi Analyzer, ...)

Remarquons que le canal WiFi 14 s'étend jusqu'à 2495 Mhz mais que le canal n°127 du nRF24L01p permet de monter jusqu'à 2527,5 Mhz .

Les canaux 96 à 127 du nRF24L01+ semblent donc exempts d'interférences WiFi...

Mais légalement, il faudra se limiter à la fréquence centrale du canal 83 du nRF24L01p, soit 2483 Mhz !

Enfin retenez aussi que le protocoole Bluetooth utilise les fréquences de 2400 Mhz à 2483,5 Mhz , soit les canaux 00 à 83 de notre nRF24L01+ !

 

Mais à quoi correspondent les 128 canaux du nRF24L01+ en regard des 14 canaux officiels du réseau WiFi ?

Les fréquences centrales des canaux WiFi sont espacées de 5 Mhz tandis que celles du nRF24L01p le sont de 1Mhz.

Les numéros de canaux utilisés par le nRF24L01p ont alors un rapport facile à la fréquence.

Pour le nRF24L01+, on calcule la fréquence centrale, en MHz, en ajoutant simplement 2400 au numéro de canal.

Le canal 27, par exemple, a ainsi une fréquence centrale de 2400 + 27 = 2427 MHz. soit  2,427 Ghz.
Il correspond alors à la fréquence centrale du canal WiFi n° 4.

La bande passante à 250 kbps et 1 Mbps est d'environ 320 kHz, avec un espacement sans chevauchement de 1 MHz.

À 2 Mbps, cela passe à 640 kHz, avec un espacement sans chevauchement de 2 MHz.

Enfin, nous remarquons que pour le canal 27, pris ici en exemple, la fréquence de 2427 MHz est encombrée par les canaux Wifi 2, 3, 4 et 5 !
De même, le canal Wifi n°6, occupant de 2426 à  2448 MHz, pourrait affecter défavorablement un nRF24L01 + fonctionnant sur n’importe quel canal entre 26 et 48 !

Nous mettrons donc au point un petit programme "scanner" qui nous permettra de déterminer le canal le moins encombré pour nos applications.

Il sera étudié juste après sur cette page.

 

     Scanner du réseau WiFi

        En cours ...

La détection d'une porteuse s'effecue par le registre CD, n° 0x.09 (Carrier Detect)
 Si l'état de ce bit = 0 ==> No Trafic
 Si l'état de ce bit = 1 ==> Trafic Detected

Le canal à scanner est configuré par le registre RF_CH, n° 0x.05 ( Frequency Channel) qui variera de 0 à 127 pour un scan complet (bien que légalement on ne peut pas aller au delà du canal 93 !)

Attention, certains internautes ayant testé les clones nRF24L01+ chinois signalent que cette fonction CD ne fonctionnerait qu'en mode TX et jamais en mode RX !!!
Ce qui n'est pas conforme aux prescriptions techniques ... et qui anéantirait notre projet de scanner en mode RX ! ( www.avrfreaks.net/forum/nrf24l01-range )

xxx


 

 


 

     Tests de Portée 

          A venir ...

Comme nous venons de le voir, la portée dépendra de nombreux facteurs :
   Matériel adapté : Composant non piraté et entièrement fonctionnel, bonne alimentation, bonne antenne accordée, blindage de la partie HF, ...
   Pas d'obstacles entre le RX et le TX
   Canal de communication dégagé et exempt d'émissions parasites (WiFi, micro-ondes, Bluetooth, ...)
   Transfert de données à faible débit, protocole choisi
   Puissance d'émission
     etc ...

 


   

 

 

   

   Trafic Visiteurs:  

 
[ Electronique ]
Copyright © Roger LEGAT - 2008 - Tous Droits réservés - (Thds V2)