Home

Modem NRF24L01

Łączność bezprzewodowa oparta na tytułowym module daje możliwość w łatwy sposób przesłać danych z jednego urządzenia do drugiego dbając tylko o to co chcemy przesłać, moduł automatycznie tworzy gotowe pakiety i je przesyła.
Taką transmisję możemy wykorzystać na przykład do zdalnego sterowania zabawkami, mini robotami, przesyłania danych ze stacji pogodowej itp.

Podstawowe dane techniczne:

Zasilanie - 1.9V - 3.6V
Pobór prądu (odbiór) - 13mA
Pobór prądu (transmisja) - 11mA
Pobór prądu w kompletnym uśpieniu - 900 nA
Częstotliwość pracy modułu - 2,4GHz
Prędkości transmisji - 250kbps, 1Mbps i 2Mbps
Zasięg około 100 m.

Podłączenie:

FR1

Podłączenie pinów w podstawowych modułach Arduino w oparciu o bibliotekę RF24

Funkcja

Arduino UNO

Arduino Nano

Arduino Wemos D1 mini

Arduino NodeMCU

GND

GND

GND

GND

GND

VCC 3.3V

3.3V

3.3V

3.3V

3.3V

CE

9

D8

D2

D4 GPIO 2

CSN

10

D7

D8

D8 GPIO 15

SCK

13

D13

D5

D5

MOSI

11

D11

D7

D7

MISO

12

D12

D6

D6

IRQ

2

 

 

 

RF24 Radio

 

(8, 7) CE, CSN

(4, 15) CE, CSN

(2, 15) CE 2, CSN 15

 

 

Arduino Nano

Wemos

NodeMCU

Biblitea RF24 GitHub:

Podstawowy program z komentarzami:

Nadajnik:

#include <SPI.h>                //biblioteka obsługi SPI
#include <nRF24L01.h>     //biblioteka do obsługi danego modułu
#include <RF24.h>             //bazowa biblioteka dla rodziny modułów RF24
                                          //kod kanału do transmisji danych
const uint64_t pipe = 0xYYYYYYYYYYLL  //zamiast Y wstawiamy dowolne znaki zgodne z system szesnastkowym czyli od 0-9 i od A-F
RF24 radio(CE_Pin, CS_Pin);  //tworzymy instancję komunikacji o nazwie radio i przypisujemy do modułu piny CE i CS
void setup()
radio.begin();                //uruchom moduł
radio.openWritingPipe(pipe);  //ustaw moduł w tryb wysyłania
void loop()
radio.write(zmienna , dlugosc_zmiennej);          //zmienna- tutaj podajemy nazwę zmiennej
//dlugosc_zmiennej- podajemy długość zmiennej np. jako długość tablicy, długość zmiennej boolowskiej itp.

Odbiornik:

#include <SPI.h>        //biblioteka obsługi SPI
#include <nRF24L01.h>   //biblioteka do obsługi danego modułu
#include <RF24.h>       //bazowa biblioteka dla rodziny modułów RF24
//kod kanału do transmisji danych
const uint64_t pipe = 0xYYYYYYYYYYLL  //zamiast Y wstawiamy dowolne znaki zgodne z system szesnastkowym czyli od 0-9 i od A-F
RF24 radio(CE_Pin, CS_Pin);  //tworzymy instancję komunikacji o nazwie radio i przypisujemy do modułu piny CE i CS

void setup():
radio.begin();                  //uruchom moduł
radio.openReadingPipe(1,pipe);  //zacznij odczyt z kanału pierwszego, przypisanego stałej 64bitowej pipe
radio.startListening();         //zacznij nasłuch (odbiór) danych
void loop()  

{
  if ( radio.available() )         // sprawdza czy są dane do odbioru,
  {
    char text[32] = {0};
    radio.read(&text, sizeof(text));
   
    Serial.println(text);                                           // jeżeli tak: radio.read(zmienna, dlugosc_zmiennej);  //odbierz dane i zapisz do zmiennej o długości..

}
}

Przykładowy podstawowy program do Arduino Nano

Nadajnik:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(7, 8);

const byte rxAddr[6] = "00001";

void setup()
{
  radio.begin();
  radio.setRetries(15, 15);
  radio.openWritingPipe(rxAddr);
 
  radio.stopListening();
}

void loop()
{
  const char text[] = "Hello World";
  radio.write(&text, sizeof(text));
 
  delay(1000);
}



Odbiornik:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(7, 8);

const byte rxAddr[6] = "00001";

void setup()
{
  while (Serial);
  Serial.begin(9600);
 
  radio.begin();
  radio.openReadingPipe(0, rxAddr);
 
  radio.startListening();
}

void loop()
{
  if (radio.available())
  {
    char text[32] = {0};
    radio.read(&text, sizeof(text));
   
    Serial.println(text);
  }
}
 


Moduł bliżniaczy z dedykowaną anteną o zasięgu około 1100 m.

NRF24L1+PA+LNA NRF24L01+PA+LNA+antena

Uruchomienie:
Wydawać by się mogło że wszystko jest banalnie proste, niestety tak nie było.
Pobrałem dedykowane biblioteki.
Zmontowałem i zaprogramowałem  układy zgodnie z założeniami, niestety nic nie działało.
Wziąłem to na karb tego że mam niesprawne układy NRF.
Wiele miesięcy wcześniej przez pomyłkę wykorzystałem je jako układy ESP01 ponieważ,
są do siebie bardzo podobne.
Kiedy zorientowałem się o mojej pomyłce NRF przeszły proces nieprawidłowego podłączenia i napięć
których nie powinny przeżyć.
Wspominam o tym w tym miejscu ponieważ jak się później okazało układy te potrafią dużo znieść.
W związku z moim przeświadczeniem zamówiłem nowe modemy zaprogramowałem i podłączyłem
do Arduino Uno oraz Arduino Leonardo i klapa. Nic nie działa.
Zgodnie z sugestiami innych użytkowników zacząłem szukać przyczyny w złych bibliotekach, błędnie napisanym programie w niewydajnym zasilaniu, indywidualnym zasilaniu, dodatkowych kondensatorach zwieraniu pinu nr 7 do masy i nic.
W końcu trafiłem na wypowiedź jednego z jutuberów w której mówił o tych samych perypetiach co moje. Zasugerował że z niewiadomej przyczyny modemy z serii NRF24L01 nie za bardzo chcą działać z modułami typu Arduino Uno i Leonardo za to doskonale radzą sobie z Arduino Nano.
Eksperyment został wznowiony. Uzbroiłem i zaprogramowałem dwa moduły Nano i po chwili na odbiorniku
przy pomocy serial monitora zobaczyłem na ekranie mojego komputera napis Udało się! .
Modemy bardzo dobrze przesyłają dane na duże odległości pomimo barier typu beton.
Nie przeszkadzało im to że są zasilane bezpośrednio z portu USB komputera, że nie mają podłączonych dodatkowych kondensatorów w obwodzie zasilania. Że pin 7 nie jest zwarty do masy, że komputer
nie radzi sobie z obsługą serial portów i wielu innych przyczyn które wcześniej przetestowałem
a które nie dawały żadnych efektów.
Zauważyłem również że nie do końca aplikacja do programowania układów Arduino w najnowszej wersji
nie radzi sobie z niektórymi modułami rozszerzającymi możliwości Arduino.
Do nowych testów użyłem aplikacji w wersji 1.6.5 i wszystko zadziałało.
Na koniec dodam że bazując na moich doświadczeniach okazuje się że układy NRF24L01 potrafią
wiele znieść. Przetestowałem wszystkie w moich zbiorach i okazuje się że są sprawne.
Czeka mnie jeszcze sprawdzenie możliwość współpracy z modułami Wemos D1 mini o których doniosę
w późniejszym czasie w dalszej części artykułu.

Testy zostały przeprowadzone. Sprawdziłem współpracę NRF24L01 z Arduino Wemos D1 mini Arduino Nano oraz NodeMcu. Ze wszystkimi wspomnianymi układ pracuje poprawnie. Zasięg z teoretycznych 100 m w piętrowym domu spada do około 30 m. Nic nie daje dołożenie dodatkowej anteny.
Oczywiście żeby nie było za łatwo każdy z tych modułów ma indywidualny schemat połączenia oraz inną wartość dotyczącą parametru RF24 radio. Powyższe dane zawarłem w tabeli.
Dodatkowo załączam listing programu na Arduino Nano współpracujący z NRF24L1 oraz z czujnikiem DHT11. Zamieszczony przykład realizuje funkcję miernika temperatury i przesyłania wyniku do drugiego układu
pracującego jako odbiornik i wyświetlającego temperaturę na wyświetlaczu.

Nadajnik -  Arduino Nano

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include "DHT.h"
#include <stdio.h>
#define DHTPIN 2
#define DHTTYPE DHT11   // DHT 22  (AM2302), AM2321

DHT dht(DHTPIN, DHTTYPE);
RF24 radio(8,7);

const byte rxAddr[6] = "00001";

void setup()
{
  Serial.begin(9600);
  radio.begin();
  radio.setRetries(15, 15);
  radio.openWritingPipe(rxAddr);
 radio.setPALevel(RF24_PA_MIN);
  radio.stopListening();

  Serial.println("Pomiar Temperatury");
}

void loop()
{

  float h = dht.readHumidity();
 float temp = dht.readTemperature();
 
  char text [8];
  dtostrf(temp, 5, 2, text); // konwerter z float na char
  radio.write(text, sizeof(text));
 Serial.print("Nadawanie ");
 Serial.println(text);
}

Odbiornik - Arduino NodeMcu

//biblioteki ukladu NRF24L01
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

//biblioteki wyswietlacza LCD
#include <LiquidCrystal_I2C.h>
#include <Wire.h>

//Inicjacja radia oraz kod kanalu
RF24 radio(2, 15);
const byte rxAddr[6] = "00001";

//kod inicjujacy wyswietlacz
LiquidCrystal_I2C lcd(0x3F,16,2);
char stopien=0xDF;    //znak stopien cencjusza 0xDF
void setup()
//Uruchomienie radia
{
  while (Serial);
  Serial.begin(9600);
 
  radio.begin();
  radio.openReadingPipe(0, rxAddr);
 
  radio.startListening();


//Uruchomienie LCD

Wire.begin(D2, D1); // Piny konwertera I2C: NodeMcu - LCD D2 -  SDA , D1 - SCL
lcd.begin(16,2);
lcd.backlight();
lcd.setCursor(0,0);
lcd.print("STEROWNIK");
lcd.setCursor(0,1);
lcd.print("OGRZEWANIA");
delay(1500);
//wyswietlenie temp. na LCD
    lcd.setCursor(0,0);
    lcd.print("Nastawa: ");
    lcd.setCursor(0,1);
    lcd.print("Temp: ");
    lcd.setCursor(12,1);
    lcd.print(stopien);
    lcd.print("C");
}

void loop()
    {
   
    //odczyt temp. z radia
   
    if (radio.available())
    {
    char text[5] = {0};
    radio.read(text, sizeof(text));
    Serial.println(text);
    lcd.setCursor(6,1);
    lcd.print("     ");
    lcd.setCursor(6,1);
    lcd.print(text);
    delay(500);
    }
   
    lcd.setCursor(6,1);
    lcd.print("Blad ");
    }