LAKI PINGVINI<>
032017<><>

Arduino: Bežični modul nRF24L01+

Racionalni Skandinavac

U prošlom broju predstavili smo dva načina za bežični prenos podataka na daljinu. Imali smo priliku da vidimo kako funkcioniše prenos uz pomoć jednostavnog AM modula na 433 megaherca, kao i onog, sagrađenog na osnovu dobro poznate Bluetooth tehnologije. Kod prvog imali smo probleme sa daljinama prenosa bez antene, osetljivošću na šum i malom brzinom, dok je Bluetooth funkcionisao solidno, ali na daljinama do deset metara. U ovom nastavku idemo još dalje i obrađujemo praktično korišćenje modula koji omogućava uspostavljanje veze na daljinama koje znatno premašuju domet Bluetooth signala, i to sa pristojnim brzinama. Osim toga, njihova važna karakteristika odnosi se na racionalno korišćenje struje, pa je uz pravilan dizajn moguće obezbediti da sklop koji se napaja običnim baterijama (pa i onim „dugmastim”), ima autonomiju od preko godinu dana. Pri svemu tome, cena kompleta od dva modula je oko jedan i po evro, što ga preporučuje za najširi spektar primena.

 
Čip nRF24L01+ je unapređena verzija svog prethodnika bez znaka „+”, i donosi nešto bolji prijem signala, kao i novu brzinu rada od 250Kb/s. Osim toga, njemu nije potrebno eksplicitno zadavanje komande ACTIVATE+0x73 za početak rada. Deo naziva koji sadrži „RF24”, sugeriše nam da je reč o radio modulu koji radi na frekvenciji od 2,4 gigaherca, a to znači da uređaj koristi frekventni opseg poznat kao ISM (Industrial, Scientific, Medical), pa će potencijalno deliti fizički medijum za prenos podataka sa mnogim drugim uređajima (recimo, Wi-Fi infrastrukturom, bežičnim telefonima, mikrotalasnim pećima itd.). To se može negativno odraziti na daljinu i brzinu prenosa informacija.

Čip proizvođača Nordic Semiconductor ima dimenzije skromnih 4x4 milimetra, i dolazi upakovan u QFN kućište sa dvadeset nožica. Postoje i nelegalne dalekoistočne kopije ovog čipa, koje su nešto jeftinije od originala i koje je u najvećem broju slučajeva teško vizuelno prepoznati (glavna razlika je u litografskoj metodi, korišćenoj za izradu čipa). U suštini, korisnik neće osetiti funkcionalnu razliku ukoliko kupi modul sa kloniranim čipom.

 
Ukoliko vam je teoretski domet signala do 100 metara nedovoljan, postoje i moduli koji na sebi imaju priključak za antenu koja povećava radijus dejstva preko jednog kilometra pri brzini prenosa od 250KB/s. Njihova cena jeste nešto veća (pet do šest evra za komplet od dva modula sa pratećim antenama), ali je i dalje veoma konkurentna. Doduše, kod takvih modula, zbog povišene potrošnje struje, često dolazi do problema sa napajanjem preko Arduina, pa treba koristiti dodatni izvor električne energije.

Osam iglica konektora razvrstano je u dva reda, koji su previše blizu jedan drugome da bi mogli da se koriste na prototipskim pločama. Zato nam ostaje da iglice spajamo džamper kablovima, što je često mukotrpno. Situacija se donekle može popraviti nabavkom dodatne pločice(60-70 centi) koja pojednostavljuje povezivanje džamper kablova i, što je još važnije, nudi mogućnost korišćenja napajanja od pet volti, što može da bude od koristi prilikom rada modula sa povećanom potrošnjom, opisanih nekoliko redova uviše. Ostaje nejasno zašto niko nije ponudio model adaptera koji bi mogao da se jednostavno uključi u rupice prototipske pločice.

Za funkcionisanje modula potreban je napon od 1,9 do 3,6 volti, koji dovodimo sa Arduino konektora za 3,3 volta, dok druge nožice možemo da povezujemo direktno, pošto su tolerantne na napon od pet volti. U slučaju da postoje ozbiljnije smetnje u prenosu podataka, savetuje se lemljenje dodatnog kondenzatora (kapaciteta 1-10 mikrofarada), koji bi spajao pinove 1 i 2 (katoda kondenzatora ide na pin 1). Ukoliko radimo sa prototipskom pločicom, isti efekat se postiže postavljanjem kondenzatora koji spaja Vcc i GND liniju na samoj prototipskoj ploči, bez lemljenja. Na ovaj način se u praksi povećava broj ispravno prenesenih paketa za 15-30 procenata, pa je pomenuta intervencija svakako preporučljiva.

Nakon što dovedemo napajanje na modul, on se automatski priključuje na bežičnu mrežu, ukoliko ona postoji. Za sve ostalo se brine Enhanced ShockBurst, hardverski podsistem ugrađen u čip. Enhanced ShockBurst je zadužen za sloj veze (po ISO/OSI modelu- data link layer), učestvuje u formiranju paketa sa podacima i u njihovoj vremenskoj sinhronizaciji. U procesu prenosa uzima podatke sa steka za slanje, priprema pakete i šalje ih na frekventno GFSK (Gaussian frequency-shift keying) moduliranje, dok prilikom prijema pretražuje demodulirani signal validne adrese. Ako je pronađe, uzima korisne podatke iz paketa, nakon čega kontroliše njihovu ispravnost. Ako je sve u redu, podaci se prosleđuju na FIFO (First In First Out) stek, namenjen prijemu (Rx) podataka. Priloženi dijagram čipa NRF24L01+ pokazuje mesto i ulogu Enhanced ShockBurst logike u poslovima slanja i prijema paketa.

 
Čip nRF24L01(+), uz pomoć CRC korekcije, automatski formira pakete podataka koji su zaštićeni od grešaka. Ukoliko sve protekne bez problema, šalje se informacija predajniku da je prenos uspešno završen. Elektronika oslobađa korisnika velikog dela posla vezanog za bežičnu komunikaciju, i od njega traži samo da se koncentriše na povezivanje sa uređajem koji dostavlja podatke. To je ponajviše zasluga pomenutog podsistema Enhanced ShockBurst, koji traži mali broj informacija da bi obavio prenos do željene destinacije. Korisnik može da odluči da li će se podaci prenositi u paketima fiksne dužine (izvorna varijanta), ili će se njihova dužina menjati dinamički.

Radni opseg je podeljen na 126 kanala od po jedan megaherc, i pri tome na kanalu može da funkcioniše po šest uređaja. U takvim slučajevima formira se mreža topologije zvezde, gde jedan uređaj ima funkciju prijemnika, dok su ostali u režimu predajnika. Drugim rečima, jedan modul može da posluži za prikupljanje informacija koje šalje šest drugih modula. Operacija se ostvaruje preko šest odvojenih kanala za podatke (ne moraju se svi koristiti), koji imaju sopstvene adrese i naziva se MultiCeiver. Nije moguće primati podatke sa svih uređaja istovremeno, već se čeka na završetak prenosa trenutnog paketa, pa se prelazi na drugi kanal. Ukoliko se koristi prenos brzine 2Mb/S, onda se koriste dva kanala istovremeno. Moduli rade u poludupleks režimu, što znači da uređaj, po potrebi, može da funkcioniše u modusu prijema podataka i, u slučaju da stigne određena poruka programskim putem, prebacuje se u modus predajnika i dostavlja podatke do nekog drugog prijemnika.

Modul nRF24L01+ ima konektor sa osam iglica koje imaju sledeće funkcije:

Kao što vidimo, modul preko SPI interfejsa komunicira sa uređajem koji ga koristi za bežični prenos podataka. Zanimljivo je da su istovremeno u upotrebi dva pina sa funkcijom izbora uređaja: prvi je klasični CE (Chip Enable), koji se koristi za kontrolu režima rada, dok je drugi CSN (Chip Select Not, gde "not" znači da je nožica invertovana). On se koristi za komunikaciju preko SPI interfejsa (ako je logička nula, SPI je aktivan). Pin pod nazivom IRQ je namenjen regulisanju obrade prekida (interapta) i početno stanje mu je logička nula. Postavljen je na logičku jedinicu kada su setovane vrednosti TX_DS IRQ, RX_DR IRQ ili MAX_RT IRQ unutar STATUS registra. Pin se resetuje kada mikrokontroler postavi IRQ source bit STATUS registra na 1. Ostali pinovi su naši stari znanci iz prethodnih brojeva.

 
Postoji nekoliko Arduino biblioteka koje omogućavaju korišćenje ovih modula bez velikog programerskog znanja. Glavna razlika među njima odnosi se na nivo komunikacije sa hardverom radio modula. Jedne se drže Arduino filozofije i sve što je potrebno da se uradi je veoma jednostavno, dok druge omogućavaju interakciju sa hardverskim registrima radio kontrolera. Prednost prvih je jednostavnost upotrebe, ali uz kompromis da onemogućava upravljanje logikom na niskom nivou, za šta je potrebno posedovati više znanja o funkcionisanju samog čipa. U našem primeru koristićemo „klasičnu” biblioteku, pod nazivom NRF24, koja nije fleksibilna, ali je jednostavna za korišćenje. Nju je po funkcionalnosti nasledila biblioteka pod nazivom RadioHead, koja, osim čipa nRF24L01+, podržava i veći broj drugih platformi za bežičnu komunikaciju.

Predajnik

Na konkretnom primeru vidimo kako funkcioniše rad sa ovim modulima. Demonstriramo vam slanje sa jednog Arduina na drugi. Kao što smo već rekli, nRF24L01+ za komunikaciju sa drugim uređajima koristi SPI (Serial Peripheral Interface) magistralu, koja se nalazi na digitalnim pinovima označenim brojevima 10-13.

#include <SPI.h> //podrska za SPI

#include <nRF24L01.h> //definicija konstanti

#include <RF24.h> //biblioteka za nRF24L01+

RF24 slanje(6, 7); //pinovi za CE i CSN

char bafer[20]; //niz karaktera poruke

char *poruka; //pokazivac na nas tekst

const byte adresa[6] = "Ard01"; //adresa prijemnika

void setup()

{

slanje.begin(); //pocetak radio veze

slanje.setRetries(8, 10); //ponavljanja

slanje.openWritingPipe(adresa); //prenosimo

slanje.stopListening(); //predji u modus predajnika

}

void loop()

{

for (int broj = 0; broj < 1000; broj++) {

poruka = dtostrf(broj, 3, 0, bafer); // pretvaramo broj u string

slanje.write(&poruka, sizeof(poruka)); //saljemo poruku

delay(500); //pauza od pola sekunde

}

}

Na početku, kao i obično, dodajemo biblioteke koje će biti neophodne za rad programa. Osim onih za rad sa SPI interfejsom, tu je i datoteka pod nazivom nRF24L01.h, koja definiše nazive konstanti korišćenih u komunikaciji sa modulom. U prethodnom kodu nismo koristili nikakve konstante, ali smo ga ostavili zbog toga što se one u praksi vrlo često koriste. Na kraju, tu je sama biblioteka RF24 sa svim funkcijama preko kojih ostvarujemo vezu. Zatim, naredbom:

RF24 slanje(6,7)

kreiramo objekat slanje kao instancu klase RF24, i ukazujemo na to koji pinovi Arduina će biti povezani sa pinovima CE i CSN na modulu. Dalje, pomoću:

char bafer[20]; //niz karaktera

char *poruka; //pokazivac na nas tekst

kreiramo niz, dužine dvadeset karaktera (treba da bude bar za jedan znak duži od teksta koji šaljemo), i pokazivač na karaktere koji predstavljaju našu poruku. Da ne ulazimo sada u detalje jezika C, samo ćemo reći da pokazivač sadrži adresu koja pokazuje (odatle i naziv) gde se naš tekst nalazi u memoriji.

Promenljiva adresa sadrži naziv modula sa kojim ćemo komunicirati. To može biti bilo koja vrednost dužine pet bajtova, uključujući i alfanumeričke karaktere.

U bloku setup() definišemo stvari koje su potrebne za izvršavanje koda iz programske petlje. Metod begin objekta slanje, inicijalizuje radio komunikaciju. Zatim, metodom setRetries govorimo našem programu nakon koliko vremena i koliko puta modul treba da ponovo šalje podatke, u slučaju da nije dobio potvrdu od modula sa ulogom prijemnika. Prvi argument predstavlja broj kojim množimo vremenski interval dužine 250 mikrosekundi. U našem slučaju, 250x8=2 milisekunde. Drugi argument predstavlja broj ponavljanja slanja. On kod nas iznosi 15, što je i maksimalna vrednost koju može imati. Sledeći metod, openWritingPipe, stvara svojevrsni kanal za komunikaciju sa uređajem čiju adresu prosleđujemo kao argument. Na kraju, metod stopListening govori modulu da napusti eventualno aktivni režim prijema i pređe u režim predajnika.

Nakon što smo stvorili uslove za obavljanje prenosa podataka, prelazimo na petlju preko koje ćemo taj prenos praktično i ostvariti. Mi, u svrhu demonstracije, koristimo jednostavnu For..Next petlju, koja kao rezultat daje brojeve od 0 do 999. Nakon što promenljivi broj dobije vrednost, tu brojnu vrednost moramo da pretvorimo u string. Za to postoji nekoliko načina, a mi ćemo koristiti funkciju pod imenom dtostrf, čiji je zadatak da vrednost formata double pretvori u string. Sama funkcija ima sledeći oblik:

dtostrf(vrednost, broj_karaktera, preciznost, bafer)

Vrednost je broj koji pretvaramo u string, broj karaktera označava dužinu našeg stringa, preciznost određuje broj znakova iza eventualne decimalne zapete, dok bafer lokacija označava gde se smešta rezultat, što je ujedno i povratna vrednost ove funkcije koju prosleđujemo promenljivoj poruka.

Slanje podataka obavljamo preko metoda write, koji za argumente ima referencu (znak &) na varijablu (poruka), koja sadrži memorijsku adresu našeg teksta, kao i dužinu tog teksta, dobijenu funkcijom sizeof. Nije nikakva tajna da početnici teško razumeju funkcionisanje pokazivača (pointer), ali nakon nekog vremena uviđaju da oni uopšte nisu tako komplikovani, kakvim se na prvi pogled čine, zato, samo hrabro napred.

Prijemnik

Za prijem su nam potrebni još po jedan Arduino i modul nRF24L01+. Ovaj put ćemo za konekciju preko SPI interfejsa, umesto digitalnih linija, koristiti pinove ICSP konektora na Arduinu. To je onih šest iglica koje se nalaze nedaleko od mikrokontrolera Atmega 328P, i glavna namena im je da služe za njegovo programiranje bez potrebe za vađenjem čipa iz podnožja. Takav metod programiranja se naziva ISP (In-system programming) ili, u slučaju Arduina, ICSP (In-Circuit Serial Programming), što su dva naziva za istu stvar. Da podsetimo, Arduino Uno R3 poseduje još jedan blok pinova pod nazivom ICSP, i on je namenjen programiranju čipa 16u2 koji služi kao most između UART i USB interfejsa. Na pratećoj ilustraciji su plavom bojom označeni kontakti koje možemo koristiti za SPI konekciju. Uz to je, kao i u prethodnom primeru, potrebno koristiti izlaze za povezivanje signala CE i CSN, a njih ćemo pomeriti na lokaciju digitalnih pinova 0 i 1 zbog jednostavnosti. Pošto su ICSP konektori, za razliku od standardnog Arduino SPI interfejsa, u vidu iglica, trebaće nam tri dodatna kabla sa ženskim konektorima sa obe strane. Neki od Arduino modela (Leonardo, Due, Yun) ne poseduju SPI izlaze na digitalnim portovima, tako da je upotreba ICSP interfejsa nezaobilazna.

#include <SPI.h>

#include <nRF24L01.h>

#include <RF24.h>

const byte adresa[6] = "Ard01"; //naziv prijemnika

RF24 prijem(0,1); //pinovi za CE i CSN

void setup()

{

Serial.begin(9600); //inicijalizacija serijskog porta

prijem.begin(); //pocetak radio veze

prijem.openReadingPipe(0, adresa); //otvori kanal prijema

prijem.startListening(); //modus prijemnika

}

void loop()

{

if (prijem.available()) //ima li podataka na prijemu?

{ //ako ima, preuzimamo ih

char poruka[20] = {0}; //ocisti bafer

prijem.read(&poruka, sizeof(poruka)); //postavi u bafer

Serial.println(poruka); //ispisi sadrzaj bafera

}

}

Kod je vrlo sličan onome za predajnik. Ubacujemo identične biblioteke, zatim definišemo naziv modula i inicijalizujemo objekat prijem sa pinovima 0 i 1 za pomenute CE i CSN. Sledi inicijalizacija serijskog porta, pošto ćemo prispele podatke prikazivati u okviru serijskog monitora. U teorijskom delu smo spominjali da na jednom kanalu može postojati do šest uređaja koji komuniciraju sa predajnikom. Označavaju se brojevima od 0 do 5. U okviru metoda openReadingPipe postavljamo taj broj na 0 i dodeljujemo mu unapred definisano ime. Nakon toga modul zapuštamo u režimu prijemnika.

 
Funkcija loop prvo proverava da li ima podataka na prijemu. Ukoliko ima, prazni bafer od prethodne vrednosti, da ne bi došlo do mešanja podataka. Zatim se nova vrednost upisuje u bafer poruka, i na kraju tu vrednost ispisujemo preko serijskog monitora koji se nalazi u okviru menija Tools, radnog okruženja Arduino.

• • •

Prvobitno smo planirali da u okviru teksta obradimo i komunikaciju Arduina i računara Raspberry Pi, ali smo morali da odustanemo zbog ograničenog prostora. Suštinski je stvar veoma slična, samo je kod za Raspberry Pi nešto duži, zbog potrebe da se ukaže veći broj parametara vezanih za inicijalizaciju čipa nRF24L01+. Kada se u obzir uzme odnos cene i mogućnosti, u pitanju je jedan od najboljih načina za prenos podataka radio talasima. Čip nRF24L01+ ima sopstveni protokol prenosa podataka koji nas oslobađa velikog dela programiranja. Jedini nedostatak mu je to što ne podržava prenos informacija u punom dupleks režimu, već menjanje pravca prenosa moramo da ostvarujemo programskim putem. Ukratko: jednostavno za realizaciju, efektivno i vrlo jeftino.

Igor S. RUŽIĆ

 
PCLinuxOS 2017.02
Duplicati 2.0
Gufw 16.04.1
FriendlyARM NanoPC-T3
Arduino: Bežični modul nRF24L01+
Šta mislite o ovom tekstu?

Radni napon:
1,9-3,6 V (pinovi 5 V tolerantni)
Frekventni opseg:
2,4-2,527 GHz
Broj kanala:
126 x 1 MHz
Brzina prenosa:
250 Kbit/s, 1 Mbit/s, 2 Mbit/s
Domet:
Do 30 m u zatvorenom i 100 m na otvorenom
Maksimalna izlazna snaga:
+20 dBm
Koeficijent pojačanja antene:
2 dBi
Potrošnja struje:
11,3 mA slanje i 12,3 mA prijem (2 Mbit/s), 22 uA stand-by, 900 nA power down
Home / Novi brojArhiva • Opšte temeInternetTest driveTest runPD kutakCeDetekaWWW vodič • Svet igara
Svet kompjutera Copyright © 1984-2015. Politika a.d. • RedakcijaKontaktSaradnjaOglasiPretplata • Help • English
SKWeb 2.54
Opšte teme
Internet
Test Drive
Test Run
PD kutak
CeDeteka
WWW vodič
Svet igara



Naslovna stranaPrethodni brojeviOpšte informacijeKontaktOglašavanjePomoćInfo in English

Svet kompjutera