Signal mètre pour nRF24L01

S mètre pour nRF24L01

Bonjour,

Voici un petit programme destiné à mesurer la qualité de réception d'un signal reçu par le nRF24L01.

Pourquoi:
il n'y a pas de S-mètre d'origine sur ce transmetteur. (Il y a bien un membre de la classe RF24 bool testRPD(void) sensée indiquer si le signal dépasse le seuil de -64dbm, mais il renvoie systématiquement false avec mes nRF24L01).

Comment:
Sur le nRF24L01 on peut faire varier la puissance d'émission de 0dbm à -18dbm par pas de 6db.
On vas envoyer des série de 4 trames, toutes les 100ms, à des puissances d'émission différentes et vérifier lesquelles on vas recevoir.
On allumera de 0 à 4 leds suivant la qualité de réception (chaque led correspond à une trame).
On obtiendra ainsi 5 solutions possibles allant de S0 (absence de signal) à S4 (réception des 4 trames) par pas de 6db.

Réalisation:
le montage est des plus simples. On prend 4 leds avec une résistance série dont la catode est reliée à la masse et l'anode aux broches choisies au début du programme avec la macro #define LED[X] [pin]. On peut rajouter une cinquième led rouge facultative (LED0) pour indiquer l'absence de signal (toutes les autres leds sont éteintes).

Test:
après vérification il s'est avéré que l'écart de puissance réel de mes nRF24L01 ne correspondait pas à celui indiqué dans le datasheet.
portée: S4 ~30m, S3 ~45m, S2-S1 ~60m, soit un écart d'environ 3db pour les puissances faibles et 0db pour les puissances fortes.
Il s'agit de nRF24L01 d'import à bas coût (clone?) .
Si quelqu'un peut confirmer si cette anomalie est également présente sur des modèles connus pour être d'origine.
Autre point: sur les cartes génériques, je recommande l'ajout d'un condensateur d'appoint de 47µF, pour épauler l'alimentation 3,3V de la carte, souvent insuffisante pour encaisser les pics de courants.

signal_tx.ino:

/*
 * Signal mètre pour nRF24L01 coté TX. Auteur Christophe JUILLET. Usage libre.
 * Pour plus d'info sur ce programme, voir le sujet "Signal mètre pour nRF24L01" sur la page: http://forum.arduino.cc/index.php?board=75.0
 */

#include <SPI.h>
#include <RF24.cpp> // URL des librairies: https://github.com/TMRh20/RF24
                    // Il faut installer les fichiers: RF24_config.h RF24.h RF24.cpp nRF24L01.h dans le répertoire "include" par défaut.
                    // Attention! Il existe plusieurs variantes de librairies du même nom qui ne sont pas toujours totalement compatibles entre-elles.
                    // pour plus d'info sur l'usage du nRF24L01 et le brochage voir la page: http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo

#define CE  9 // CE nRF24L01
#define CS 10 // CS nRF24L01

const byte canal = 120;      // choisir un canal d'émission radio (entre 100 et 125, au dessus des canaux wifi)
const byte pipe[5] = {0xE8,0xE8,0x12,0x34,0x56}; // choisir un canal logique unique (remplacer "123456" par des chiffres au hasard).

RF24 radio(CE, CS);

void setup() {
  radio.begin();
  radio.setChannel(canal);
  radio.setDataRate(RF24_250KBPS); // On réduit le débit pour doubler la portée. Attention! ne fonctionne qu'avec la version "+" du nRF24L01+. Sinon on met la ligne en commentaire.
  radio.openWritingPipe(pipe);
}

void loop() {
  static byte puissance[4] = { 0, 1, 2, 3};
  
  radio.setPALevel(RF24_PA_MAX); // RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX. On règle à la puissance maxi (1mW).
  radio.enableDynamicAck();
  radio.write(&puissance[0], 1, 1); // pas d'ACK
  delay(10);
  radio.setPALevel(RF24_PA_HIGH); // -6dbm
  radio.enableDynamicAck();
  radio.write(&puissance[1], 1, 1);
  delay(10);
  radio.setPALevel(RF24_PA_LOW); // -12dbm
  radio.enableDynamicAck();
  radio.write(&puissance[2], 1, 1);
  delay(10);
  radio.setPALevel(RF24_PA_MIN); // -18dbm
  radio.enableDynamicAck();
  radio.write(&puissance[3], 1, 1);
  delay(70);
}

signal_rx.ino:

/*
 * Signal mètre pour nRF24L01 coté RX. Auteur Christophe JUILLET. Usage libre.
 * Pour plus d'info sur ce programme, voir le sujet "Signal mètre pour nRF24L01" sur la page: http://forum.arduino.cc/index.php?board=75.0
 */

#include <SPI.h>
#include <RF24.cpp> // URL des librairies: https://github.com/TMRh20/RF24
                    // Il faut installer les fichiers: RF24_config.h RF24.h RF24.cpp nRF24L01.h dans le répertoire "include" par défaut.
                    // Attention! Il existe plusieurs variantes de librairies du même nom qui ne sont pas toujours totalement compatibles entre-elles.
                    // pour plus d'info sur l'usage du nRF24L01 et le brochage voir la page: http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo

#define CE        9
#define CS       10
#define LED0      3 //  led absence de signal (facultative)
#define LED1      7 //  led signal 1
#define LED2      6 //  led signal 2
#define LED3      5 //  led signal 3
#define LED4      4 //  led signal 4

const bool parler = true;    // true: retour console (pour contrôle), false: silencieux (plus rapide)
const byte canal = 120;      // prendre le même canal de réception radio que celui de l'émetteur (voir fichier signal_tx.ino)
const byte pipe[5] = {0xE8,0xE8,0x12,0x34,0x56}; // prendre le même canal logique que celui de l'émetteur (voir fichier signal_tx.ino)

RF24 radio(CE,CS);

void setup() {
  if (parler)
    Serial.begin(250000);
  pinMode(LED0, OUTPUT);
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  pinMode(LED4, OUTPUT);
  digitalWrite(LED0, HIGH);
  digitalWrite(LED1, LOW);
  digitalWrite(LED2, LOW);
  digitalWrite(LED3, LOW);
  digitalWrite(LED4, LOW);
  radio.begin();
  radio.setChannel(canal);
  radio.setDataRate(RF24_250KBPS); // On utilise le même débit que pour l'émetteur. Attention! ne fonctionne qu'avec la version "+" du nRF24L01+. Sinon on met la ligne en commentaire.
  radio.openReadingPipe(1,pipe);
  radio.startListening();
}

void loop() {
  static unsigned long t1 = millis(), t2, tempsMort; // tempsMort: temps entre deux trames 
  static byte RFdata = 0, RFsignal = 0;
  static bool maj = false, RFok = false;
  
  t2 = millis();
  tempsMort = t2 - t1;
  if (radio.available()) {
    radio.read(&RFdata, 1);
    t1 = t2;
    tempsMort = 0;
    maj = false;
    RFok = true;
    RFsignal |= 1 << RFdata;
  }
  if (tempsMort > 40 && RFsignal && !maj) {
    maj = true;
    if (parler) {
      Serial.print(RFsignal & 1 << 0 ? "Signal: 1 " : "Signal:   ");
      Serial.print(RFsignal & 1 << 1 ? "2 " : "  ");
      Serial.print(RFsignal & 1 << 2 ? "3 " : "  ");
      Serial.println(RFsignal & 1 << 3 ? "4 " : "  ");
    }
    digitalWrite(LED0, LOW);
    digitalWrite(LED1, RFsignal & 1 << 0 ? HIGH : LOW);
    digitalWrite(LED2, RFsignal & 1 << 1 ? HIGH : LOW);
    digitalWrite(LED3, RFsignal & 1 << 2 ? HIGH : LOW);
    digitalWrite(LED4, RFsignal & 1 << 3 ? HIGH : LOW);
    RFsignal = 0;
  }
  if (tempsMort > 120 && RFok) {
    RFok = false;
    if (parler)
      Serial.println("pas de signal");
    digitalWrite(LED0, HIGH);
    digitalWrite(LED1, LOW);
    digitalWrite(LED2, LOW);
    digitalWrite(LED3, LOW);
    digitalWrite(LED4, LOW);
  }
}

Les fichiers sont également en pièces jointes.

signal_tx.ino (1.93 KB)

signal_rx.ino (3.17 KB)

Bonjour
c'est bien intéressant pour faire du "deverminage"
Je n'ai pas trop le temps de tester avant qq jours, mais je le ferais

Pour répondre partiellement à ta question sur la dispersion de caractéristiques "des modules" , ça ne m’étonne pas outre mesure, j'ai eu l'occasion de tester pas mal de trucs/modules "cheap" 2.4 GHz avec du materiel de labo "éprouvé" , c'est un peu le n'importe quoi comme résultat.