Range Tester / Sending datas via Structure - nRF24L01 / nRF24L01 + PA + LNA

One project using nRF24L01 WiFi modules is already in my blog. I used them to create WiFi points for Capture Points / DOMINATION game mode. To remind the modules, they communicate at a frequency of 2.4 GHz and it is possible to use over 120 channels for transmission. It is possible to utilize communication with the transmitter to up to eight receivers through eight pipelines. Each nRF24L01 module supports up to 4 independent power modes - MIN, LOW, HIGH, MAX.

Each requires a specific resource. For HIGH / MAX mode, an external source is recommended. The power supply of the module is 3.3V, while the terminals have 5V tolerant, i. SPI bus data wires can also be connected to Arduina 5V pins. The most commonly used for HIGH / MAX power mode is traction battery and under module nRF24L01 additional adapter - YL-105, which contains 3.3V controller. Using the MAX Direct View Power Mode, the nRF24L01 + PA + LNA (with external antenna) can be used up to 1100 meters in an undisturbed environment.

A low data rate setting will also help to ensure transmission reliability and increase range. You can set the data rate to 250kbps, 1Mbps, 2Mbps. An important element in the implementation of a new project is to test communication over the nominal distance over which we want to use the project. That's why I created a simple program for the transmitter and receiver.

The transmitter always transmits values from 0 to 3 in a cycle. It uses a 200ms pause between the values it sends. In addition, the transmitter receives data from the receiver (if available), which responds back to the received data. Sends the value it received.

The receiver waits for data from the transmitter in a cycle. After receiving the data, it will send it back to the transmitter - two-way communication. If the receiver receives a value of 1, it sends a signal to the detector that sounds. This makes it possible to monitor, along with distance, whether the transmission is successful and whether the detector beeps regularly.
Transmitter Program - Range Measurement:

//Vyhotovil: martinius96
//Web: https://arduino.php5.sk
//Vysielač - meranie dosahu

#include <SPI.h>
#include "RF24.h"
// nastavení propojovacích pinů
#define CE 4
#define CS 3
// inicializace nRF s piny CE a CS
RF24 nRF(CE, CS);
// nastavení adres pro přijímač a vysílač,
// musí být nastaveny stejně v obou programech!
byte adresaPrijimac[]= "prijimac00";
byte adresaVysilac[]= "vysilac00";
void setup() {
  // komunikace přes sériovou linku rychlostí 9600 baud
  Serial.begin(9600);
  // zapnutí komunikace nRF modulu
  nRF.begin();
  nRF.setDataRate( RF24_250KBPS );
  // nastavení výkonu nRF modulu,
  // možnosti jsou RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH and RF24_PA_MAX,
  // pro HIGH a MAX je nutnýv externí 3,3V zdroj
  nRF.setPALevel(RF24_PA_LOW);
  // nastavení zapisovacího a čtecího kanálu
  nRF.openWritingPipe(adresaVysilac);
  nRF.openReadingPipe(1,adresaPrijimac);
  // začátek příjmu dat
  nRF.startListening();
}

void loop() {
  // for smyčka pro postupné odeslání
  // hodnot 0 až 3 pro načtení všech dat
  // z přijímače
  for (int i=0; i < 4; i++ ) {
    // ukončení příjmu dat
    nRF.stopListening();
    // vytisknutí aktuální volby po sériové lince
    Serial.print("Posilam volbu ");
    Serial.println(i);
    // uložení startovního času komunikace
    unsigned long casZacatek = micros();
    // odeslání aktuální volby, v případě selhání
    // vytištění chybové hlášky na sériovou linku
    if (!nRF.write( &i, sizeof(i) )){
       Serial.println("Chyba při odeslání!");
    }
    nRF.startListening();
    unsigned long casCekaniOdezvy = micros();
    boolean timeout = false;
    while ( ! nRF.available() ){
    if (micros() - casCekaniOdezvy > 200000 ){
          timeout = true;
          break;
      }      
    }
    if ( timeout ){
      Serial.println("Chyba při prijmu, vyprseni casu na odezvu!");
    }
    else{
     
        unsigned long prijataData;
        nRF.read( &prijataData, sizeof(prijataData) );
        unsigned long casKonec = micros();
        Serial.print("Odeslana volba: ");
        Serial.print(i);
        Serial.print(", prijata data: ");
        Serial.println(prijataData);
        Serial.print("Delka spojeni: ");
        Serial.print(casKonec - casZacatek);
        Serial.println(" mikrosekund.");
    }
    delay(200);
  }
}

Receiver Program - Range Measurement:

//Vyhotovil: martinius96
//Web: https://arduino.php5.sk
//Prijímač - meranie dosahu

#include <SPI.h>
#include "RF24.h"
int prijem;
const int buzzer = 2;
#define CE 4
#define CS 3
RF24 nRF(CE, CS);
byte adresaPrijimac[] = "prijimac00";
byte adresaVysilac[] = "vysilac00";
void setup() {
  Serial.begin(9600);
  pinMode(buzzer, OUTPUT);
  nRF.begin();
  nRF.setDataRate( RF24_250KBPS );
  nRF.setPALevel(RF24_PA_LOW);
  nRF.openWritingPipe(adresaPrijimac);
  nRF.openReadingPipe(1, adresaVysilac);
  nRF.startListening();
}

void loop() {
  unsigned long odezva;
  if ( nRF.available()) {
    // čekání na příjem dat
    while (nRF.available()) {
      nRF.read( &prijem, sizeof(prijem) );
    }
    Serial.print("Prijata volba: ");
    Serial.print(prijem);
    switch ( prijem ) {
      case 1:

        odezva = millis();

        tone(buzzer, 50, 500);

        break;
      case 2:
        odezva = millis() / 1000;
        break;
      case 3:
        odezva = micros();
        break;
      default:
        odezva = 0;
        break;
    }
    nRF.stopListening();
    nRF.write( &odezva, sizeof(odezva) );
    nRF.startListening();
  }
}

Schematics (from another projects, but pinout fits):

The second point of the article is the possibility to use the structure for data transmission - again it is possible to use the connection according to the diagram above. As a result, it is possible to transmit several data in one data package - a "packet", which can be easily processed also on the receiver side. It is mainly used for sending data from sensors, such as temperature, humidity, pressure, digital inputs and other parameters that can be sent directly in one logical unit - structure. Thus, the same data structure can serve both to send and receive data. The transmitter and receiver must use the same data structure. The data structure uses 2 entries, an int entry and a float entry. The transmitter sends the value of the structure parameters - T = 100 and A = 3.14. The receiver transmits T = 200 and A = 6.28 in response to the transmitter.
Program Structure - Transmitter:

//Vyhotovil: martinius96
//Web: https://arduino.php5.sk
//Vysielač - prenos dát štruktúrou

#include <SPI.h>
#include "RF24.h"
#define CE 4
#define CS 3
RF24 nRF(CE, CS);

typedef struct {
int T;
float A;
} dataPacket;

byte adresaPrijimac[] = "prijimac00";
byte adresaVysilac[] = "vysilac00";
void setup() {
Serial.begin(9600);
nRF.begin();
nRF.setDataRate( RF24_250KBPS );
nRF.setPALevel(RF24_PA_LOW);
nRF.openWritingPipe(adresaVysilac);
nRF.openReadingPipe(1, adresaPrijimac);
nRF.startListening();
}

void loop() {
dataPacket packet;
packet.T = 100;
packet.A = 3.14;
nRF.stopListening();
nRF.write(&packet, sizeof(dataPacket));
nRF.startListening();
while (nRF.available()) {
nRF.read(&packet, sizeof(dataPacket));
Serial.print("Prijata hodnota T: ");
Serial.println(packet.T);
Serial.print("Prijata hodnota A: ");
Serial.println(packet.A);
}
delay(50);
}

Program Structure - Receiver:

//Vyhotovil: martinius96
//Web: https://arduino.php5.sk
//Prijímač - prenos dát štruktúrou

#include <SPI.h>
#include "RF24.h"
#define CE 4
#define CS 3
RF24 nRF(CE, CS);

typedef struct {
int T;
float A;
} dataPacket;

byte adresaPrijimac[] = "prijimac00";
byte adresaVysilac[] = "vysilac00";
void setup() {
Serial.begin(9600);
nRF.begin();
nRF.setDataRate( RF24_250KBPS );
nRF.setPALevel(RF24_PA_LOW);
nRF.openWritingPipe(adresaPrijimac);
nRF.openReadingPipe(1, adresaVysilac);
nRF.startListening();
}

void loop() {
dataPacket packet;
if ( nRF.available()) {
while (nRF.available()) {
nRF.read(&packet, sizeof(dataPacket));
Serial.print("Prijata hodnota T: ");
Serial.println(packet.T);
Serial.print("Prijata hodnota A: ");
Serial.println(packet.A);
}
nRF.stopListening();
packet.T = 200;
packet.A = 6.28;
nRF.write(&packet, sizeof(dataPacket));
nRF.startListening();
}
}

I also use data transfer in structure in one of my projects for Airsofts with WiFi points that communicate over 1 kilometer (Capture Points mode): https://arduino.php5.sk/airsoft-wifi.php?lang=en

martinius96:
One project using nRF24L01 WiFi modules is already in my blog.

nRF24 modules are NOT WiFi.

It is possible to utilize communication with the transmitter to up to eight receivers through eight pipelines.

I'm not sure what you mean by "pipelines" but {A} according to my copy of the nRF24L01+ datasheet the modules have 6 pipes and {B} using a single pipe it is possible communicate with dozens of other nRF24L01+ modules.

...R
Simple nRF24L01+ Tutorial