4. Drugi program – transmisja tablicy
Aby ta część kursu była jak najbardziej douczająca to wprowadzę tutaj coś, czego jeszcze nie było do tej pory czyli tablice. Z początku może brzmieć groźnie, ale wcale takie nie jest. Tablica- w tym rozpatrywanym przypadku -jest miejscem gdzie są zgromadzone różne zmienne. Można by wręcz powiedzieć, że jest to pewnego rodzaju „segregator” na zmienne. Wygląda on następująco:
1 2 |
int tablica[x]; // x- ilość zmiennych przechowywanych w tablicy |
Załóżmy, że chcemy w naszej tablicy trzymać trzy zmienne, więc piszemy:
1 |
int tablica[3]; |
Tutaj możesz się zastanawiać, jak powinny nazywać się zmienne, aby były przechowywane w tablicy. Tutaj nie ma innego wyjścia niż nazwać zmienne tak samo jak tablicę. Każda zmienna musi być numerowana. Tutaj ważna sprawa, o której się często zapomina. Zmienne zawarte w tablicy numerujemy od zera.
1 2 3 4 |
tablica[0] tablica[1] tablica[2] itd... |
Można to łatwo zapamiętać, ponieważ jakbyśmy numerowali od jedynki to by się okazało, że ostania zmienna ma taką samą nazwę jak tablica.
Tyle temat wstępu do tablic. Czas użyć je praktyce.
Schemat nadajnika:
Program nadajnika:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
#include <SPI.h> //dodaj obsługę biblioteki SPI #include <nRF24L01.h> //dodaj bibliotekę obsługującą moduł #include <RF24.h> //dodaj bibliotekę główną modułów RF24 const uint64_t pipe = 0x1CF8361637LL; //kod kanału int potencjometr = A0; //potencjometr podłączony do pinu A0 RF24 radio(9, 10); //tworzymy instancje komunikacji int pot[1]; //utwórz tablicę jednoelementową o nazwie pot void setup() { pinMode(potencjometr,INPUT); //ustaw potencjometr jako wejście radio.begin(); //uruchom moduł radio.setDataRate(RF24_2MBPS); //ustaw prędkość transmisji na 2Mb/s radio.setPALevel(RF24_PA_HIGH); //ustaw wzmocnienie modułu radiowego na wysokie radio.openWritingPipe(pipe); //rozpocznij transmisję } void loop() { pot[0]= analogRead(potencjometr) / 4; //przypisz pierwszemu elementowi tablicy (pierwszej zmiennej) wartość z ADC radio.write(pot, sizeof(pot)); //wyslij zmienną pot z odpowiadającą jej długością } |
Definiowanie modułu nic się nie różni od poprzedniego przykładu, tylko jak widać doszły nam jeszcze dwie linijki:
1 2 |
radio.setDataRate(RF24_2MBPS); //ustaw prędkość transmisji na 2Mb/s radio.setPALevel(RF24_PA_HIGH); //ustaw wzmocnienie modułu radiowego na wysokie |
W pierwszej linii definiujemy prędkość transmisji. Mamy do wyboru 3 prędkości:
1 2 3 |
radio.setDataRate(RF24_250KBPS); //ustaw prędkość transmisji na 250kb/s radio.setDataRate(RF24_1MBPS); //ustaw prędkość transmisji na 1Mb/s radio.setDataRate(RF24_2MBPS); //ustaw prędkość transmisji na 2Mb/s |
Można sukcesywnie korzystać z najwyższej prędkości, bez obaw o zerwanie transmisji, jakby to miało miejsce w tanich modułach RF. Nie mniej jednak przy transmisjach tego typu, gdzie przesyłamy nie więcej niż 4bitowe dane, nie ma odczuwalnej różnicy.
Druga linia decyduje wzmocnieniu modułu. Mamy do dyspozycji 4 poziomy wzmocnienia:
1 2 3 4 |
RF24_PA_MIN= -18dBm //wzmocnienie -18dBm RF24_PA_LOW= -12dBm //wzmocnienie -12dBm RF24_PA_MED= -6dBm //wzmocnienie -6dBm RF24_PA_HIGH= 0dBm //wzmocnienie 0dBm |
Wystarczy zamiast X wstawić, któreś z powyższych:
1 |
radio.setPALevel(X); |
Jeżeli korzystamy z tych opcji to musimy je wykorzystać zarówno w odbiorniku jak i nadajniku, aby nie było problemu z transmisją. Następnie przechodzimy do pętli głównej programu. Jak widać nie ma tutaj nic nadzwyczajnego. Do zmiennej pot[0] przypisujemy wartość odczytu ADC, gdzie podłączony jest potencjometr, a następnie podzieloną przez 4, aby w ostateczności uzyskać poziomy zbliżone do PWM. Tak przygotowane dane wysyłamy. Jak widać zamiast pisać typ zmiennej jako długość, możemy wpisać samą nazwę zmiennej jako długość, ale nie zawsze może działać poprawnie. Teraz można przejść do odbiornika.
Schemat odbiornika:
Program odbiornika:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
#include <SPI.h> //dodaj obsługę biblioteki SPI #include <nRF24L01.h> //dodaj bibliotekę obsługującą moduł #include <RF24.h> //dodaj bibliotekę główną modułów RF24 const uint64_t pipe = 0x1CF8361637LL; //kod kanału int dioda = 6; //dioda podłączona do pinu 5 Arduino RF24 radio(9, 10); //tworzymy instancje komunikacji int pwm[1]; //utwórz jednoelementową tablicę void setup() { pinMode(dioda,OUTPUT); //ustaw diodę jako wyjście delay(1000); //odczekaj 1s radio.begin(); //uruchom moduł radio.setDataRate(RF24_2MBPS); //ustaw prędkość transmisji na 2Mb/s radio.setPALevel(RF24_PA_HIGH); //ustaw wzmocnienie modułu radiowego na wysokie radio.openReadingPipe(1,pipe); //zacznij odczyt z kanału o danym kodzie radio.startListening(); //zacznij odczyt danych } void loop() { if ( radio.available() ) //jeżeli są jakieś dane do odczytu { radio.read( pwm, sizeof(pwm) ); //odczytaj dane i zapisz je do zmiennej pwm analogWrite(dioda,pwm[0]); //ustaw wartość PWM jako wartość zmiennej pwm[0] } } |
Przy definiowaniu odbiornika nic się nie zmieniło w porównaniu z poprzednim odbiornikiem, zatem wtrącę jeszcze parę słów odnośnie transmisji tablic. Przy transmisji tablicy z jednego układu do drugiego, kolejność zawartych w niej zmiennych się nie zmienia. Dlatego kolejność definiowania zmiennych z tablicy w odbiorniku powinna być taka sama tzn. jak korzystamy z dwóch potencjometrów to potrzebujemy zapisać dwie zmienne w tablicy np. pot[0] odpowiadający za pierwszy potencjometr i pot[1] odpowiadający za drugi. Zatem w odbiorniku, musimy również stworzyć tablicę, do której będą trafiać dane z nadajnika. Czyli jak będziemy chcieli skorzystać z danych pierwszego potencjometra to musimy dokonać odczytu ze zmiennej zakończonej [0], ponieważ kolejność rozpakowywania danych jest taka sama jak kolejność pakowania.
Wracając do programu. Funkcja warunkowa if() sprawdza czy są jakieś dane w buforze. Jeżeli tak, to dokonywany jest zapis do tablicy pwm, o długości takiej jaką posiada. Następnie przy pomocy funkcji analogWrite() przypisywana jest wartość diodzie z pierwszej zmiennej z tablicy pwm.
Tak wgrane program powinny dać taki efekt:
5. Podsumowanie
Jak widzimy obsługa modułów nRF24L01+ nie jest aż taka trudna, aczkolwiek sama biblioteka modułu jest momentami problematyczna, tzn. czasem, żeby wysłać jakieś dane, to trzeba napisać wysyłanie ich drogą na około niż bezpośrednio, ale nie są to jakieś problemy, z którymi nie można by sobie poradzić. Zawsze jak pokaże się jakiś błąd kompilacji, to warto go przeczytać, bo czasem znajduję się w nim odpowiedź rozwiązania problemu. To tyle, mamy nadzieję, że poradnik trochę rozjaśni Ci sposób obsługi tego modułu. Polecam zajrzeć do pełnej dokumentacji biblioteki, ponieważ tutaj poruszyliśmy tylko podstawy obsługi tego modułu, a żeby napisać kompletny kurs dla tego modułu to by powstała już dobra książeczka. ;)
Materiały do dzisiejszego kursu:
Jeżeli chcesz być informowany na bieżąco o nowych częściach kursu to kliknij „Lubię to!” bądź subskrybuj naszą stronę, aby otrzymywać na adres e-mail nowości ze strony. Jeżeli masz jakieś pytania to śmiało zadawaj je na forum ; )