Někteří prodejci (hlavně ti z číny) uvádí že to je wifi modul, ale pravda je taková, že se s tímhle k internetu prostě nepřipojíme. Označení wifi má jen kvůli pracovní frekvenci která je stejná jako má náš wifi router. V tomto pásmu funguje i většina dálkových ovladačů RC modelů.
Frekvence 2,4GHz je u nás volně k použití, takže nám odpadá starost s placením licencí, ale na druhou stranu to ssebou nese i nevýhody. Jak už jsem psala, stejnou frekvenci má kde co, takže ve městě se může vyskytnout velké rušení a tím se může snížit efektivní dosah modulů.
Dneska si ukážeme jak posílat různá data bezdrátově s tímhle levným modulem. NRF24L01+ se v číně dá sehnat už za nějakých 15 - 20Kč s integrovanou anténou komunikující běžně na desítky metrů a ve správných podmínkách až na stovky metrů. Anebo NRF24L01+PA+LNA s přídavnou anténou za padesátku s dosahem až 1km.
Stále se prodává i varianta NRF24L01, rozdíl na který jsem narazila je asi jen v rychlosti přenosu. NRF24L01 podporuje pouze 1 a 2 MBPS. NRF24L01+(PA+LNA) podporuje rychlosti 1 a 2MBPS a 250KBPS s o něco větším dosahem.
|
|
|
Nejdřív chci upozornit na pár věcí.
1. Vstupní napětí je pouze 1,9 - 3,6V ale vstupy jsou tolerantní na 5V logiku, takže nepotřebujeme převodník logických úrovní.
2. Problémy se stabilitou můžou způsobit proudové špičky, nebo rušení z okolí. Tím se arduino občas sekne a pak se můžeme divit proč to nejde. To se dá vyřešit elektrolitickým kondenzátorem s kapacitou např. 10uF mezi piny VCC a GND modulu NRF. Hodnota kondenzátorů je jen orientační, větší kapacita by neměla být na škodu. Taky se dá sehnat napájecí modul se vším potřebným z číny asi za desetikorunu. Na otestování na stole je OK, ale nedoporučuji ho na větší výkony ani dlouhodobý provoz.
![]() |
| Napájecí deska pro NRF24L01 |
Knihovnu RF24 od uživatele TMRh20 stáhneme v manažeru knihoven, nebo na GitHubu. Testováno s verzí knihovny 1.1.7.
Teď se už vrhneme na zapojení. Pozor, nákres pinů je zeshora dps, ale lišta s piny je směrem dolů. Poprvé jsem si to málem zapojila opačně.
| NRF24L01 | NANO/UNO | MEGA |
| GND | GND | GND |
| Vcc | 3,3V | 3,3V |
| CE | 9 | 9 |
| CS | 10 | 10 |
| MOSI | 11 | 51 |
| MISO | 12 | 50 |
| SCK | 13 | 52 |
Můžeme si otestovat jestli to máme správně zapojené tímto kódem
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9,10); // (CE, CS)
void setup(void)
{
Serial.begin(9600);
printf_begin();
radio.begin();
radio.printDetails();
}
void loop(void)
{
}
int serial_putc( char c, FILE * )
{
Serial.write( c );
return c;
}
void printf_begin(void)
{
fdevopen( &serial_putc, 0 );
}
Serial monitor:
![]() |
| Pokud máme zapojeno vše jak má být, uvidíme toto.. |
![]() |
| Něco podobného uvidíme když je modul zapojený špatně. |
Máme zapojené 2x Arduino s NRF.
Funkce je jednoduchá.
Vysílač odešle zprávu, přepne se do přijímacího módu a bude čekat na odpověď. Pokud v zadaný čas odpověď nepřijde, odešle další zprávu a bude zase čekat na odpověď.
Přijímač čeká na zprávu a když ji přijme, tak odpoví. Jednoduché.
Na pin 6 si můžeme připojit piezo pípák a po každé přijaté odpovědi arduino pípne.
Vysílač
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define BeepPin 6
#define CE 9
#define CS 10
//MOSI = 11
//MISO = 12
//SCK = 13
//VCC = 3,3V!
RF24 radio(CE, CS);
// nastavíme si adresy a kanál vysílání
const byte vysilac[] = "TX001";
const byte prijimac[] = "RX001";
int kanal = 120;
void setup(void) {
Serial.begin(9600);
radio.begin();
// nastavení rychlosti komunikace
// možnosti jsouRF24_250KBPS, RF24_1MBPS, RF24_2MBPS
radio.setDataRate(RF24_1MBPS);
//kanál na kterém budeme komunikovat
radio.setChannel(kanal);
// příjem
radio.openWritingPipe(prijimac);
radio.openReadingPipe(1, vysilac);
radio.startListening();
radio.printDetails();
// 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ý externí 3,3V zdroj
radio.setPALevel(RF24_PA_MIN);
pinMode(BeepPin, OUTPUT);
}
// něco proměnných
char MyCon[40];
char data[40];
int poradi = 1;
bool state = false;
int prvni = 0;
String druhy = "";
long startmillis;
long endmillis;
void loop(void) {
if (!state) {
Serial.println("odesilam");
startmillis = millis();
//vysílání
radio.openWritingPipe(vysilac);
radio.openReadingPipe(0, prijimac);
radio.stopListening();
sprintf(MyCon, "%i:%s:%i:", poradi, "kanal", kanal);
radio.write(&MyCon, sizeof(MyCon)); // odeslání zprávy
Serial.println(MyCon);//***
poradi++;
Serial.println("odeslano");
state = true;
Serial.println("cekam na odpoved");
// příjímání
radio.openWritingPipe(prijimac);
radio.openReadingPipe(1, vysilac);
radio.startListening();
}
while (state) {
if (radio.available()) {
//Serial.println("radio available"); // příjem
radio.read( &data, sizeof(data));
prvni = atoi(strtok(data, ":"));
druhy = strtok(NULL, ":");
Serial.print("mam odpoved: ");
Serial.print(prvni); Serial.print(", ");
Serial.println(druhy);
//Beep();
state = false;
}
// timeout
endmillis = millis() - startmillis;
if ((endmillis >= 1000) && (state)) {
Serial.println("timeout");
state = false;
}
}
Serial.print("delka komunikace je ");
Serial.print(endmillis);
Serial.println("ms");
delay(2000);
}
void Beep() {
int freq = 2800; //frekvence v Hz
int delka = 60; //délka pípnutí v ms
tone(BeepPin, freq, delka);
}
Přijímač
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define CE 9
#define CS 10
//MOSI = 11
//MISO = 12
//SCK = 13
//VCC = 3,3V!
RF24 radio(CE, CS);
// adresy a kanál
const byte vysilac[] = "TX001";
const byte prijimac[] = "RX001";
int kanal = 120;
void setup(void) {
Serial.begin(9600);
radio.begin();
// nastavení rychlosti komunikace
// možnosti jsouRF24_250KBPS, RF24_1MBPS, RF24_2MBPS
radio.setDataRate(RF24_1MBPS);
//kanál na kterém budeme komunikovat
radio.setChannel(kanal);
// příjem
radio.openWritingPipe(prijimac);
radio.openReadingPipe(1, vysilac);
radio.startListening();
//radio.printDetails();
// 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ý externí 3,3V zdroj
radio.setPALevel(RF24_PA_MIN);
Serial.println("ready");
}
// něco proměnných
char MyCon[40];
char data[40];
bool state = false;
int prvni = 0;
String druhy = "";
int treti = 0;
void loop(void) {
//Serial.print("state ");Serial.println(state);
if (!state) {
if (radio.available()) {
Serial.println("radio available");
while (radio.available()) {
radio.read( &data, sizeof(data) );
prvni = atoi(strtok(data, ":"));
String druhy = strtok(NULL, ":");
int treti = atoi(strtok(NULL, ":"));
Serial.print("mam zpravu: ");
Serial.print(prvni);Serial.print(", ");
Serial.print(druhy);Serial.print(": ");
Serial.println(treti);
state = true;
}
}
}
if (state) {
// vysílání
radio.openWritingPipe(vysilac);
radio.openReadingPipe(0, prijimac);
radio.stopListening();
delay(30);// pauza před odesláním
//aby se druhý modul stihl přepnout pro příjem
// odeslat odpoved
Serial.println("odpovidam");
sprintf(MyCon, "%i:%s:", prvni, "OK");
Serial.println(MyCon);
radio.write(&MyCon, strlen(MyCon));
state = false;
Serial.println("odpoved odeslana");
// a zase přepnout na příjem
radio.openWritingPipe(prijimac);
radio.openReadingPipe(1, vysilac);
radio.startListening();
}
}
Kanál na kterém moduly komunikují si můžeme nastavit na číslo v rozsahu 0 - 124. Při větších (a záporných) číslech se to chová jako jeden kanál. Kanály nad 108 jsou frekvencí nad většinou domácích wifi routerů.
Adresy pro vysílač a přijímač můžou být jakýkoliv řetězec znaků a čísel. Maximální délku jsem nezkoušela.
Pokud chceme aby nám komunikovalo víc modulů spolu ale nechceme-li aby všechny moduly chytaly zprávy určené jinému, stačí měnit jen kanál před každým vysíláním, nezapomeneme však nastavit stejný kanál i na druhém zařízení jinak se samozřejmně nedomluví.
// TX & Rx adresa pro příjem radio.openWritingPipe(prijimac); radio.openReadingPipe(1, vysilac); radio.setChannel(123); radio.startListening(); // TX & Rx adr pro vysílání radio.openWritingPipe(vysilac); radio.openReadingPipe(0, prijimac); radio.setChannel(123); radio.stopListening();
A na konec sketche ke stažení z google disku. Plus odkaz na můj e-shop, kde si vše potřebné můžete zakoupit







Díky,
OdpovědětVymazattoto mi pomohlo najít dlooho hledaný problém nespolehlivého přenosu:
delay(30);// pauza před odesláním
//aby se druhý modul stihl přepnout pro příjem
Mirek