Jeden projekt s využitím WiFi modulov nRF24L01 sa už v mojom blogu nachádza. Využíval som ich pri tvorbe WiFi bodov pre herný mód Capture Points / DOMINATION. Aby sme si moduly pripomenuli, komunikujú na frekvencii 2,4 GHz pričom je možné využiť cez 120 kanálov pre prenos. Je možné využiť komunikáciu s vysielačom až k ôsmym prijímačom skrz osem "pipelines". Každý modul
nRF24L01 podporuje až 4 nezávislé módy výkonu - MIN, LOW, HIGH, MAX.Každý vyžaduje špecifický zdroj. Pre mód HIGH / MAX sa odporúča využiť externý zdroj. Napájanie modulu je na 3.3V, pričom vývody má 5V tolerantné, t.j. dátové vodiče SPI zbernice sa môžu napojiť aj na 5V piny Arduina. Najčastejšie sa pre HIGH / MAX výkonový mód používa trakčná batéria a pod modul nRF24L01 doplnkový adaptér - YL-105, ktorý obsahuje 3.3V regulátor. S využitím MAX napájacieho módu s priamou viditeľnosťou je možné použiť modul nRF24L01 + PA + LNA (s externou anténou) až na 1100 metrov v nezarušenom prostredí.
Ku spoľahlivosti prenosu a navýšeniu dosahu dopomôže aj nastavenie nízkej dátovej rýchlosti.
Nastaviť je možné dátovú rýchlosť 250kbps, 1Mbps, 2Mbps. Dôležitým prvkom pri realizácii nového projektu je vyskúšať komunikáciu na menovitú vzdialenosť, na ktorú chceme projekt používať. Preto som vytvoril jednoduchý program pre vysielač a prijímač.
Vysielač vysiela vždy v cykle hodnoty 0 až 3. Využíva 200ms pauzu medzi jednotlivými hodnotami, ktoré odosiela. Vysielač okrem toho prijíma dáta od prijímača (ak sú dostupné), ktorý spätne odpovedá na prijaté dáta. Odosiela hodnotu, ktorú prijal.
Prijímač čaká v cykle na dáta od vysielača. Po prijatí dát ich spätne odošle vysielaču - obojsmerná komunikácia. V prípade, že prijímač príjme hodnotu 1, pošle signál na hlásič, ktorý sa rozozvučí. Vďaka tomu je možné sledovať spolu so vzdialenosťou, či je prenos úspešný a či hlásič pravidelne pípa.
Program pre vysielač - meranie dosahu:Kód:
//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);
}
}
Program pre prijímač - meranie dosahu:Kód:
//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();
}
}
Schéma zapojenia pre vysielač a prijímač (z iného projektu), pinout pre nRF24L01 a buzzer sedí:
Druhým bodom článku je možnosť využitia štruktúry pre prenos dát - znova je možné použiť zapojenie podľa schémy vyššie. Vďaka tomu je možné v jednom dátovom balíku - "pakete" prenášať viacero dát, ktoré je možné jednoducho spracovať aj na strane prijímača. Využitie to má predovšetkým pre odosielanie dát zo senzorov, napríklad teplota, vlhkosť, tlak, digitálne vstupy a ďalšie parametre, ktoré môžu byť priamo v jednom logickou celku - štruktúre posielané. Rovnaká dátová štruktúra teda môže slúžiť pre odosielanie, ale aj príjem dát. U vysielača a prijímača je nutné, aby používali rovnakú dátovú štruktúru. Dátová štruktúra používa 2 položky, položku T typu int a položku A typu float.
Vysielač vysiela hodnotu parametrov štruktúry - T = 100 a A = 3.14. Prijímač vysiela ako odpoveď vysielaču na prijaté dáta hodnotu T = 200 a A = 6.28.Program pre vysielač:Kód:
//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 pre prijímač:Kód:
//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();
}
}
Prenos dát štruktúrou používam aj v jednom z mojich projektov pre Airsofťákov s WiFi bodmi, ktoré komunikujú na vzdialenosť cez 1 kilometer (Mód Capture Points):
https://arduino.php5.sk/airsoft-wifi.php