Labortagebuch - Arduino - Raspberry Pi
08.01.2020 - Das Funkmodul nRF24L01

Das Funkmodul mit integrierter Antenne
Das Sender-Empfänger-Modul nRF24L01 arbeitet auf einer Frequenz von 2,4GHz und ist mit zahlreichen nützlichen Features ausgestattet. Besonders interessant ist eine intelligente Paketverwaltung mit CRC-Prüfung, automatischer Empfangsbestätigung und erneuter automatischer Versendung des Paketes, falls die Empfangsbestätigung beim Sender ausbleibt. Damit sichergestellt ist, dass hierdurch beim Empfänger keine identischen Pakete ankommen, arbeiten die Module beim Versand mit einer internen Paket-ID und verwerfen identische Pakete automatisch. Ebenfalls für den Arduino Datenlogger mit Stockwaage für Imker sehr interessant, ist die Möglichkeit mit bis zu sechs Datenleitungen parallel zu arbeiten. Damit eignet sich dieses Modul auch optimal für ein beelogger-Netzwerk mit bis zu sechs Sendern, ausgestattet mit Sensoren, und einem Empfänger, welcher die Messwerte über einen Ethernet-Adapter an den Webserver sendet. Durch adressierbare Leitungen und die Möglichkeit, bis zu 127 Kanäle einzustellen, können mehrere Systeme auch parallel betrieben werden. 
Das Modul verwendet die SPI-Schnittstelle für die Verbindung zum Arduino. Zusätzlich werden noch zwei weitere Pins (CSN & CE) benötigt. Das Modul benötigt keine zusätzliche Stromversorgung, jedoch muss es an den 3,3 Volt Pin angeschlossen werden. Das Modul darf nicht mit 5 Volt betrieben werden!

Für die Programmierung benötigt man die NRF24 Library. Diese kann von folgender Seite heruntergeladen werden: NRF24 Library
Das Funkmodul Plus mit SMA Antenne
Die Anschlüsse am Funkmodul müssen an vorgegebene Eingänge am Arduino angeschlossen werden. Dabei gibt es unterschiedliche Pins, je nachdem ob es ein Arduino Uno / Arduino Nano oder ein Arduino Mega ist. Die beiden Anschlüssen CSN und CE können frei gewählt werden, da diese im Befehl RF24 radio (CE_Pin, CSN_Pin) vereinbart werden müssen.
NRF24L01 Arduino Uno/Nano Arduino Mega
IRQ
MISO
12
50
MOSI
11
51
SCK
13
52
CSN
8
8
CE
9
7
VCC
3,3 V
3,3 V
GND
GND
GND

Achtung: Sender und Empfänger werden gleich verkabelt. Der Unterschied besteht allein in der Programmierung.
Verkabelung des Funkmoduls
Programm-Code für den Sender

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
//create an RF24 object
RF24 radio(9, 8); // CE, CSN
//address through which two modules communicate.
const byte address[6] = "00001";
void setup(){
radio.begin(); //set the address
radio.openWritingPipe(address);
//Set module as transmitter
radio.stopListening();}
void loop(){ //Send message to receiver
const char text[] = "Hello World";
radio.write(&text, sizeof(text));
delay(1000);}
Programm-Code für den Empfänger

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
//create an RF24 object
RF24 radio(9, 8); // CE, CSN
//address through which two modules communicate.
const byte address[6] = "00001";
void setup(){
Serial.begin(9600);
radio.begin(); //set the address
radio.openReadingPipe(0, address);
//Set module as receiver
radio.startListening();}
void loop() { //Read the data if available in buffer
Serial.println("Anfang"); delay(1000);
if (radio.available())
{ char text[32] = {0};
radio.read(&text, sizeof(text));
Serial.println(text);}<´br> }

Ausgabe auf dem seriellen Monitor
In diesem Fall wird der Text Hello World übertragen.
Achtung: Der Empfänger-Arduino bleibt am PC, um den Monitor der Arduino-IDE aufrufen zu können. Der Sender-Arduino wird nach dem Aufspielen des Sketch vom PC getrennt und mit einer Batterie bzw. Akku verbunden. Hier ist darauf zu achten, dass die Spannung über 9 V liegt (es reichen dazu 6 Mignon-Batterien/Akkus = 9,6 V).
Die Übertragung ist nicht immer optimal. Manchmal klappt es sofort, das andere Mal muss die Antenne anders gestellt werden.
Mit diesem Sketch wird ein float-Wert übertragen

Programm-Code für den Sender


#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
//Erzeugt ein RF24 Objekt
RF24 radio(9,8); // CE, CSN
//address through which two modules communicate.
const byte address[6] = "00001";
void setup(){
radio.begin(); //set the address
radio.openWritingPipe(address);
radio.setPALevel(RF24_PA_MAX);
//Set module as transmitter
radio.stopListening();}
void loop()
{ //Send message to receiver
float temperature = 12.9;
radio.write(&temperature, sizeof(float));
delay(1000);}
Programm-Code für den Empfänger

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 8); // CE, CSN
const byte address[6] = "00001";
void setup() {
Serial.begin(9600);
radio.begin(); //set the address
radio.openReadingPipe(0, address); //Set module as receiver
radio.setPALevel(RF24_PA_MAX);
radio.startListening();}
void loop() { //Read the data if available in buffer
Serial.println("Anfang"); delay(2000);
if (radio.available()) {
float temperature = 0.0;
radio.read(&temperature, sizeof(float));
Serial.print("Temperature : "); Serial.println(temperature);
delay(1000);}

Ausgabe auf dem seriellen Monitor
Mit diesem Sketch werden mehrere Werte unterschiedlichen Typs mit Hilfe von struct package übertragen
Programm-Code für den Sender

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 myRadio (9,8);
struct package{
int id=1;float temperature = 18.3;
char text[100] = "Text to be transmitted";};
typedef struct package Package;
Package data;

byte addresses[][6] = {"0"};

void setup(){
Serial.begin(115200);
delay(1000);
myRadio.begin();
myRadio.setChannel(115);
myRadio.setPALevel(RF24_PA_MAX);
myRadio.setDataRate( RF24_250KBPS ) ;
myRadio.openWritingPipe( addresses[0]);
delay(1000);}

void loop(){
myRadio.write(&data, sizeof(data));
Serial.print("\nPackage:");
Serial.print(data.id);
Serial.print("\n");
Serial.println(data.temperature);
Serial.println(data.text);
data.id = data.id + 1;
data.temperature = data.temperature+0.1;
delay(1000);}
Programm-Code für den Empfänger

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 myRadio (9,8);
struct package {
int id=0;float temperature = 0.0;
char text[100] ="empty";};
typedef struct package Package;
Package data;

byte addresses[][6] = {"0"};

void setup() {
Serial.begin(115200);
delay(1000);
myRadio.begin();
myRadio.setChannel(115);
myRadio.setPALevel(RF24_PA_MAX);
myRadio.setDataRate( RF24_250KBPS ) ;
myRadio.openReadingPipe(1, addresses[0]);
myRadio.startListening();}

void loop() {
if ( myRadio.available()) {
while (myRadio.available()){
myRadio.read( &data, sizeof(data) );}
Serial.print("\nPackage:");
Serial.print(data.id);
Serial.print("\n");
Serial.println(data.temperature);
Serial.println(data.text);}
}

Ausgabe auf dem seriellen Monitor
Infos und Tutorials im Netz
Im Netz findet man bzgl. dieses Funkmoduls etliche Seiten, die fast keine Wünsche offen lassen. Es werden sehr viele Möglichkeiten für den Einsatz des NRF24-Moduls dargestellt. Dabei gibt es Schaltskizzen des Moduls mit dem Arduino und auch die dazugehörigen Sketche. Besonders gut hat mir eine Seite gefallen, auf der die Erläuterungen und Beschreibungen sehr witzig und sehr informativ dargestellt werden. Der Autor nimmt kein Blatt vor den Mund und erklärt Dinge, die bei den meisten anderen Seiten als bekannt vorausgesetzt werden. Hier wird ein Link zu der Seite angegeben.
NRF24 Seite

Zusätzlich habe ich diese Seite heruntergeladen und dann in eine PDF-Datei umgewandelt. Diese ist hier erhältlich.
Download NRF24-Tutorial(1,9 MB)