Witajcie,
jestem tu nowy, więc na początku się przedstawię. Mam na imię Mateusz, mam 14 lat i interesuję się elektroniką, informatyką i majsterkowaniem.
Temat artykułu brzmi “Jak zacząć z RF?” więc chciałbym pokazać Wam jak bawić się komunikacją bezprzewodową :D
Potrzebne części:
- 2x Arduino (w moim przypadku Leonardo i Uno)
- nadajnik RF (433 mHz lub 315 mHz)
- odbiornik RF (o takich samych częstotliwościach jak nadajnik)
- płytka stykowa + kabelki
- komputer z zainstalowanym Arduino IDE i ściągniętą biblioteką VirtualWire
Jak to ma działać?
Pierwsze Arduino (nadajnik) ma wysyłać jakieś informacje (np. wilgotność) do drugiego Arduino (odbiornik), które z tych danych będzie korzystać(np. wyświetlać na LCD).
Najpierw podłączmy moduły i sprawdźmy czy działają poprawnie ;)
Tak wygląda nadajnik (bazowa część do dalszej pracy):
Jest to po prostu podpięty nadajnik RF pod pin 10 Arduino.
Na początku zacznijmy od czegoś “standardowego” w podczas nauki programowania, oczywiście chodzi mi o HELLO WORLD!
To jest właśnie ten kod wysyłający HELLO WORLD :
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 |
#include <VirtualWire.h> // definiujemy piny #define led_pin 11 #define transmit_pin 10 void setup() { // przygotowujemy potrzebne informacje dla biblioteki vw_set_tx_pin(transmit_pin); vw_setup(2000); pinMode(led_pin, OUTPUT); } void loop() { String toSend = ("hello world"); // tekst wiadomości char msg[23]; // tworzymy tablicę typu char toSend.toCharArray(msg, toSend.length() + 1); // konwertujemy nasz tekst do tablicy char'ów digitalWrite(led_pin, HIGH); // zapalamy LED vw_send((uint8_t *)msg, strlen(msg));// wysyłamy vw_wait_tx(); digitalWrite(led_pin, LOW); // gasimy LED delay(1000); // czekamy 1 sekundę } |
Mam nadzieję że kod jest zrozumiały dzięki komentarzom.
Teraz przejdźmy do odbiornika. Podpinamy odbiornik RF pod pin 11 naszego Arduino
i kod odbierający :
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 37 38 39 40 |
#include <VirtualWire.h> #define led_pin 13 #define receive_pin 11 void setup() { Serial.begin(9600); Serial.println("setup"); // przygotowujemy potrzebne informacje dla biblioteki vw_set_rx_pin(receive_pin); vw_setup(2000); vw_rx_start(); // startujemy odbieranie danych (uruchamiamy) pinMode(led_pin, OUTPUT); } void loop() { // częśc wymagana do poprawnego działania biblioteki uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN; if (vw_get_message(buf, &buflen)) // jeśli odbierzemy dane { int i; digitalWrite(led_pin, HIGH); //zapalamy LED Serial.println("Got: "); // piszemy Got: for (i = 0; i < buflen; i++) // w pętli zczytujemy dane z odbiornika { Serial.print(buf[i], HEX); // i wypisujemy dane na Serial'u Serial.print(' '); } Serial.println(); digitalWrite(led_pin, LOW); // gasimy LED } } |
w void loop’ie wystąpił taki zapis:
1 2 |
for (i = 0; i < buflen; i++) Serial.print(buf[i], HEX); |
dlaczego?
Odbiornik przekazuje dane do Arduino po znaku, a nasz mikrokontroler po prostu musi to jakoś przetworzyć, więc wypisuje na Serial znak, po znaku. Działa to podobnie do zapisywania w tablicy znaków.
Po wgraniu kodu do obydwóch urządzeń, podłączamy je do komputera i otwieramy Serial monitor dla odbiornika. Po chwili ukazuje się nam coś takiego:
czyżby to był jakiś błąd?
Nie! to po prostu nasze hello world w postaci heksadecymalnej. Skopiujmy sobie taki jeden ciąg znaków i wklejmy do rubryki Hexadecimal na tej stronie, potem kliknijmy convert. Dzięki temu zyskaliśmy nasz napis w “ludzkiej postaci” (rubryka Text (ASCII/ANSI))
Nasz pierwszy bezprzewodowy układ działa. Teraz zmodyfikujmy trochę kody do naszych mikrokontrolerów. Pamiętacie hello world z LCD? Tam było też odliczanie czasu. Ciekawa Sprawa! Spróbujmy coś pokombinować.
W kodzie nadajnika dodałem zmienną (która się powiększa o 1 co sekundę) i wstawiłem ją do String’a tym zapisem:
1 |
String toSend = ("hello world " + String(sec, DEC)); // tekst wiadomości |
a oto cały kod dla tych, którzy chcą pójść na łatwiznę
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 |
#include <VirtualWire.h> // definiujemy piny #define led_pin 11 #define transmit_pin 10 int sec = 1; void setup() { // przygotowujemy potrzebne informacje dla biblioteki vw_set_tx_pin(transmit_pin); vw_setup(2000); pinMode(led_pin, OUTPUT); } void loop() { String toSend = ("hello world " + String(sec, DEC)); // tekst wiadomości char msg[23]; // tworzymy tablicę typu char toSend.toCharArray(msg, toSend.length() + 1); // konwertujemy nasz tekst do tablicy charów digitalWrite(led_pin, HIGH); // zapalamy LED vw_send((uint8_t *)msg, strlen(msg));// wysyłamy vw_wait_tx(); digitalWrite(led_pin, LOW); // gasimy LED sec++; delay(1000); // czekamy 1 sekundę } |
Teraz pewnie zastanawiacie się czy jest jakiś sposób na wyświetlanie otrzymanych informacji na Serial’u w sposób przystępny dla człowieka.
Tak jest i to nawet bardzo prosty, oto rozwiązanie problemu do odbiornika:
1 |
wiadomosc +=char(buf[i]); |
Do String’u dodawane są po kolei znaki, które otrzymujemy od odbiornika.
Więc w taki sposób będzie wyglądał cały kod do 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 37 38 39 |
#include <VirtualWire.h> #define led_pin 13 #define receive_pin 11 void setup() { Serial.begin(9600); Serial.println("setup"); // przygotowujemy potrzebne informacje dla biblioteki vw_set_rx_pin(receive_pin); vw_setup(2000); vw_rx_start(); // startujemy odbieranie danych (uruchamiamy) pinMode(led_pin, OUTPUT); } void loop() { // częśc wymagana do poprawnego działania biblioteki uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN; if (vw_get_message(buf, &buflen)) // jeśli odbierzemy dane { int i; String wiadomosc; digitalWrite(led_pin, HIGH); //zapalamy LED for (i = 0; i < buflen; i++) // w pętli zczytujemy dane z odbiornika { wiadomosc+=char(buf[i]); } Serial.println(wiadomosc); digitalWrite(led_pin, LOW); // gasimy LED } } |
teraz zamiast wyświetlać na Serial’u wiadomości znaku, po znaku wyświetlamy od razu wszystko, gdyż znak, po znaku jest zapisywany do zmiennej, która później ląduje na wyświetlaczu. Teraz wygląda to tak:
Hmm na LCD liczba jest wyświetlana w drugiej linijce, a tu mając ciąg znaków w zmiennej, nie damy rady tego tak, zrobić. Trzeba by dodać drugą zmienną odpowiedzialną za liczbę, więc będzie to wyglądać tak:
1 2 3 4 5 6 7 8 9 10 |
for (i = 0; i < 12; i++) { wiadomosc+=char(buf[i]); // wiadomość last = i; } for (i = last; i < buflen; i++) { liczba+=char(buf[i]); // liczba } |
W pierwszej pętli odczytujemy pierwsze 12 znaków (od 0 do 11). W drugiej pętli odczytujemy znaki od 11 do końca wiadomości.
A tu jest cały kod:
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 37 38 39 40 41 42 43 44 45 46 |
#include <VirtualWire.h> #define led_pin 13 #define receive_pin 11 void setup() { Serial.begin(9600); Serial.println("setup"); // przygotowujemy potrzebne informacje dla biblioteki vw_set_rx_pin(receive_pin); vw_setup(2000); vw_rx_start(); // startujemy odbieranie danych (uruchamiamy) pinMode(led_pin, OUTPUT); } void loop() { // częśc wymagana do poprawnego działania biblioteki uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN; if (vw_get_message(buf, &buflen)) // jeśli odbierzemy dane { int i,last; String wiadomosc, liczba; digitalWrite(led_pin, HIGH); //zapalamy LED // w pętli zczytujemy dane z odbiornika for (i = 0; i < 12; i++) { wiadomosc+=char(buf[i]); // wiadomość last = i; } for (i = last; i < buflen; i++) { liczba+=char(buf[i]); // liczba } Serial.println(wiadomosc); Serial.println (liczba); digitalWrite(led_pin, LOW); // gasimy LED } } |
Mamy już oddzielnie liczbę. Ale jest jeden mały problem. To co jest w string’u jest ciągiem znaków, na którym nie da się wykonywać działań matematycznych. Trzeba przekonwertować go do zmiennej typu int. Robi się to tak:
1 |
int = String.toInt(); |
a w praktyce będzie to wyglądać tak:
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 37 38 39 40 41 42 43 44 45 46 |
#include <VirtualWire.h> #define led_pin 13 #define receive_pin 11 void setup() { Serial.begin(9600); Serial.println("setup"); // przygotowujemy potrzebne informacje dla biblioteki vw_set_rx_pin(receive_pin); vw_setup(2000); vw_rx_start(); // startujemy odbieranie danych (uruchamiamy) pinMode(led_pin, OUTPUT); } void loop() { // częśc wymagana do poprawnego działania biblioteki uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN; if (vw_get_message(buf, &buflen)) // jeśli odbierzemy dane { int i,last, liczbaOut; String wiadomosc, liczba; digitalWrite(led_pin, HIGH); //zapalamy LED // w pętli zczytujemy dane z odbiornika for (i = 0; i < 12; i++) { wiadomosc+=char(buf[i]); // wiadomość last = i; } for (i = last; i < buflen; i++) { liczba+=char(buf[i]); // liczba } liczbaOut = liczba.toInt(); Serial.println(wiadomosc); Serial.println(liczbaOut); digitalWrite(led_pin, LOW); // gasimy LED } } |
Teraz zajmijmy się czymś trudniejszym. Niech to będzie zdalne sterowanie jasnością diody LED. Na początku dodajmy do nadajnika potencjometr. Podpinamy go pod pin A0.
Kod do niego jest taki:
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 |
#include <VirtualWire.h> // definiujemy piny #define led_pin 11 #define transmit_pin 10 #define pot_pin A0 void setup() { // przygotowujemy potrzebne informacje dla biblioteki vw_set_tx_pin(transmit_pin); vw_setup(2000); pinMode(led_pin, OUTPUT); } void loop() { int pot = analogRead(pot_pin); String toSend = (String(pot, DEC)); // tekst wiadomości char msg[23]; // tworzymy tablicę typu char toSend.toCharArray(msg, toSend.length() + 1); // konwertujemy nasz tekst do tablicy charów digitalWrite(led_pin, HIGH); // zapalamy LED vw_send((uint8_t *)msg, strlen(msg));// wysyłamy vw_wait_tx(); digitalWrite(led_pin, LOW); // gasimy LED delay(1000); // czekamy 1 sekundę } |
Do odbiornika dodajmy diodę LED pod pin PWM np. 3. Pamiętajcie o odpowiednim rezystorze (można go obliczyć tu). Więc nasz układ będzie tak wyglądał:
To teraz przydał by się kod.
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 37 38 39 40 41 42 43 44 45 46 |
#include <VirtualWire.h> #define led_pin 13 #define receive_pin 11 #define pwm_pin 3 void setup() { Serial.begin(9600); Serial.println("setup"); // przygotowujemy potrzebne informacje dla biblioteki vw_set_rx_pin(receive_pin); vw_setup(2000); vw_rx_start(); // startujemy odbieranie danych (uruchamiamy) pinMode(led_pin, OUTPUT); pinMode(pwm_pin, OUTPUT); } void loop() { // częśc wymagana do poprawnego działania biblioteki uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN; if (vw_get_message(buf, &buflen)) // jeśli odbierzemy dane { int i,pwm,wartosc; String liczba; digitalWrite(led_pin, HIGH); //zapalamy LED // w pętli zczytujemy dane z odbiornika for (i = 0; i < buflen; i++) { liczba+=char(buf[i]); // wiadomość } wartosc = liczba.toInt(); pwm = map(wartosc,0,1023,0,255); Serial.print(wartosc);// Debug Serial.print(" "); Serial.println (pwm); analogWrite(pwm_pin, pwm); digitalWrite(led_pin, LOW); // gasimy LED } } |
w kodzie zostało zastosowane takie coś:
1 |
xyz = map(abc,0,1023,0,255); |
oznacza to że zmienna xyz (która może mieć wartości 0-255) ma odpowiednie proporcje względem zmiennej abc (która może mieć wartości 0-1023)
A oto efekt :D
Hmm… to było proste. Zróbmy coś trudniejszego np przesyłanie temperatury i wilgotności. Podłączmy czujnik DHT11 i wgrajmy nowego skecz’a
Uwaga, przy podłączaniu czujnika DHT 11 należy zmienić w kodzie to
1 2 |
#define idDHT11pin 2 #define idDHT11intNumber 0 |
w zależności od posiadanej płytki i pinu do którego jest podpięty czujnik.
Board int.0 int.1 int.2 int.3 int.4 int.5
Uno, Ethernet 2 3
Mega2560 2 3 21 20 19 18
Leonardo 3 2 0 1
więcej info na: http://arduino.cc/en/Reference/AttachInterrupt
Tu rodzi się nam problem, ponieważ mamy dwie zmienne ,które mogą mieć różną długość. Jak więc odbiornik ma wykryć gdzie kończy się jedna, a gdzie zaczyna się druga. Dlatego zastosowałem pomiędzy nimi znak $. Wtedy odbiornik gdy wykryje $, przejdzie do drugiej zmiennej.
1 |
toSend= String(temp, DEC) + "$" + String(hum, DEC) + "$" |
a tak wygląda cały kod
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 37 38 39 40 41 42 43 44 45 46 47 |
#include <idDHT11.h> #include <VirtualWire.h> #define led_pin 11 #define transmit_pin 10 #define idDHT11pin 2 #define idDHT11intNumber 0 void dht11_wrapper(); idDHT11 DHT11(idDHT11pin,idDHT11intNumber,dht11_wrapper); String toSend=""; void setup() { vw_setup(2000); vw_set_tx_pin(transmit_pin); } void dht11_wrapper() { DHT11.isrCallback(); } void loop() { DHT11.acquire(); while (DHT11.acquiring()); int result = DHT11.getStatus(); switch (result) { case IDDHTLIB_OK: break; } int temp = DHT11.getCelsius(); int hum = DHT11.getHumidity(); toSend= String(temp, DEC) + "$"+ String(hum, DEC) + "$"; char msg[15]; //char array to copy the String into toSend.toCharArray(msg, toSend.length() + 1); //Copy the string (+1 is to hold the terminating null char) Serial.println(msg); digitalWrite(led_pin, HIGH); vw_send((uint8_t *)msg, strlen(msg)); vw_wait_tx(); digitalWrite(led_pin, LOW); delay(500); } |
odbiornik:
i kod:
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 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
#include <VirtualWire.h> #define led_pin 13 #define receive_pin 11 void setup() { Serial.begin(9600); Serial.println("setup"); // przygotowujemy potrzebne informacje dla biblioteki vw_set_rx_pin(receive_pin); vw_setup(2000); vw_rx_start(); // startujemy odbieranie danych (uruchamiamy) pinMode(led_pin, OUTPUT); } void loop() { // częśc wymagana do poprawnego działania biblioteki uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN; if (vw_get_message(buf, &buflen)) // jeśli odbierzemy dane { int i,last,hum,temp; String hum1, temp1; digitalWrite(led_pin, HIGH); //zapalamy LED for (i = 0; i < buflen; i++) { if (char(buf[i]) != '$') // jeśli otrzymanym znakiem nie jest $ temp1+=char(buf[i]); else // w innym wypadku (jeśli otrzymanym znakiem jests $) { i++; // dodajemy 1 do i last = i; break; // kończymy pętlę } } for (i = last; i < buflen; i++) { if (char(buf[i]) != '$') // jeśli otrzymanym znakiem nie jest $ hum1+=char(buf[i]); else // w innym wypadku (jeśli otrzymanym znakiem jests $) break; // przerywamy pętlę } // konwertujemy Stringi do Intów hum = hum1.toInt(); temp = temp1.toInt(); // wypisujemy je na Serial Serial.println(hum); Serial.println(temp); digitalWrite(led_pin, LOW); // gasimy LED } } |
Szukanie przyczyny problemu:
- Jeżeli spotkaliśmy problem przy pierwszym podłączeniu modułów jest jedno proste rozwiązanie za pomocą, którego można spróbować znaleźć źródło problemu. Należy odłączyć modułu RF i połączyć pin nadajnika (w pierwszym Arduino) z pinem odbiornika w drugim za pomocą kabelka i uwspólnić masę. Jeżeli nadal nie będzie działać to znaczy że mamy gdzieś błąd w kodzie.
- Gdy metodą pierwszą wszystko działa, ale po podłączeniu modułów przestaje przyczyną problemu zapewne jest za duża odległość pomiędzy nadajnikiem, a odbiornikiem. Spróbuj zmniejszyć odległość między nimi i (lub) dolutować im antenki.
Na sam koniec chciałbym pokazać Wam fajną metodę na zrobienie antenek.
25 zwojów jest przystosowanie do częstotliwości 433 MHz.
Dzięki za przeczytanie :D
Mam nadzieję że pomogłem jak by ktoś miał jakieś problemy to pytajcie się w komentarzach lub na forum :D
Artykuł pierwsza klasa.
Będę czepialski – MHz, a nie mHz – Mega, a nie mili.
poprawione :D
Mam pytanie czy da się zestawić klika nadajników z jednym odbiornikiem?
W kodzie nie widzę informacji o parowaniu 2 urządzeń ze sobą?
jak najbardziej – to właściwie są tylko modulator i demodulator, więc tryb broadcastowania (1 do wielu) działa tak samo.
Przy kilku nadajnikach (wiele do 1) w tym samym paśmie należałoby pomyśleć o potencjalnych kolizjach oraz czy i jak je rozwiązać, np. WDM odpada, TDM/CDM to kwestia softu/bibliotek.
Na takim etapie można myśleć już od razu o adresowaniu, żeby możliwe było wysyłanie do konkretnego odbiornika (1 do 1).
Stosuje kilka par takich odbiorników, i tu najlepszym pomysłem aby transmisje się nie zakłócały jest ustawienie różnych prędkości dla różnych par.
Te moduły są bardzo proste (żeby nie powiedzieć prostackie ;) ) tu nie ma żadnego parowania. Po prostu wszystkie moduły muszą działać na tej samej częstotliwości. Dodatkowo (o ile potrzeba) w treści pasuje zawrzeć różne ID dla każdego z nadajników, żeby odbiornik wiedział z którego przyszły dane.
Przerabiałem te nadajniki, ale ze względu na ich zawodność, mierny zasięg, pobór energii, brak możliwości sprawdzenia poprawności nadanej wiadomości ( i czy w ogóle dotarła) przesiadłem się na RFM69H/RFM69HW
Sprzętowo nie, ale można zastosować metodę TDM. http://www.cse.iitk.ac.in/users/dheeraj/cs425/lec04.html
W skrócie – jedno urządzenie jest jakoby masterem a pozostałe nasłuchują. Master każdemu nowemu urządzeniu podaje czas kiedy może nadawać i zsynchronizowane w ten sposób urządzenia nadają po kolei (każde z nich czeka określoną ilość czasu żeby nie zakłócać innych).
Bardzo dobry artykuł, od siebie mogę dodać, że ilość znaków do wysłania, znacząco wpływa na zasięg transmisji, pomaga także zmniejszenie prędkości transmisji vw_setup.
Z doświadczenia dodam jeszcze, że o ile nadajnik jest bardzo odporny na wyższe niż 5V napięcie, i zmianę biegunów, to odbiornik już takich rzeczy nie przeżyje. Co do anten polecam na początek zastosować zwykły kawałek drutu (np, skrętki) o długości 17cm lub 69cm (jest to dipol prosty) łatwiej wykonać taką antenę niż zaprezentowaną cewkę
Jak już w temacie przesyłania bezprzewodowego, warto rozważyć także moduły NRF24L01+ lub ESP8266.
pomyślę, na razie takie miałem w domu ;)
A zna ktoś dobry artykuł o sterowaniu tak jak w przykładzie z diodą i potencjometrem ale po przez ESP8266??
Witam, też mam 14 lat i jestem pod wrażeniem twoich umiejętności :) Też interesuję się elektroniką ale w pisaniu programów miałem problem, a ten artykuł mi wszystko wyjaśnił. Artykuł bardzo przydatny i prosty w zrozumieniu. Pozdrawiam, Karol :)
w końcu mogę pomagać innym w tym w czym jestem dobry :D
A ja dodam, że częstotliwość 433MHz jest często wykorzystywana w “bezprzewodowych gniazdkach”, co np. ja z powodzeniem wykorzystywałem przy projekcie zapalania i gaszenia świateł przez internet (Arduino + moduł ethernet + nadajnik RF 433MHz).
Przykładowa biblioteka do tego celu to RCswitch: https://code.google.com/p/rc-switch/
W jaki sposób wysłać zmienną float i potem odebrać ją i móc wyświetlić na np LCD / serial princie
możesz pomnożyć ją *100 i moją metodą, a potem na odbiorniku podzielić /100
Jak wyglądałby kod na nadajniku i odbiorniku, gdybyśmy chcieli zrobić most dla portu szeregowego, czyli to co wchodzi po szeregowym do 1arduino wychodzi na szeregowym 2arduino?
Cześć, jest jakaś możliwość, odczytywania “mocy sygnału”?
Tak, i jest to bardzo proste zwłaszcza, że w Bascom masz gotowy projekt #167 Animal Tracker
Pingback: O hai let me wanna-be! pe Trilema - Un blog de Mircea Popescu.
Brakuje skąd ściągnąc virtual wire.
Ludzie, litości. Jak czytam i widzę takie rzeczy jak w tym projekcie, to nóż mi się w kieszeni otwiera. Pierwsza sprawa moduły z projektu nie służą do transmisji danych po RS232. To już pierwszy błąd, mające wpływ na poprawność odczytu danych. Po drugie nadajnik ten WYMAGA zasilania 12V i podobnej amplitudy sygnału z procesora. Para ta będzie znacznie lepiej działać jeśli wykorzystamy np protokół RC5 a od procesora do nadajnika dodamy konwerter sygnału z 5V na 12V. Wówczas zasięg wyniesie kilkaset metrów, a nie kilka cm. Można też opracować własny protokół z CRC, wówczas zyskamy na poprawności odczytywanych danych. I jeszcze jedno. Maksymalna prędkość dla tych modułów nie powinna być wyższa niż 2400 bodów. Moduły te często stosowane są w pilotach do bram, kontaktów i podobnych. Wówczas jako koder/dekoder stosuje się pary PT2262/2272. Zwykle zasięg działania wynosi od 50 do 5000m w zależności od modelu i zastosowanej anteny.
No to masz fajny temat na nowy post :)
Po zlutowania antenek zasięg wynosi od mojego domu do działki około 200m na 5v a na 12v koło 1km. Nadajnik umieściłem sobie na altance a odbiornik mam w domu. Dobrym pomysłem by było zastosowanie bardzo dobrych anten.
Witam. A jak zwiększyć zasięg stosując te moduły z ukłądami HT12E i HT12D ?? gdzie zwiekszyć napięcie ?
Może zamiastych modułów tx433 pobawić się ESP8266, z jednej strony Android po drugiej stronie AVR, jest to fajniejsza zabawa, lepsze zasiegi i przyszlosciowa.
Owszem, tylko wadą ESP8266 jest jego bardzo duży pobór prądu praktycznie uniemożliwiający zasilanie bateryjne, chyba że wysyłasz dane bardzo rzadko, np co 30 minut. O ile transmisję na TX433 bardzo łatwo zrobić tak, że pobiera prąd tylko podczas nadawania, a samo nadawanie może trwac raptem kilka ms, to w ESP8266 po każdym wybudzeniu musisz się połączyć z siecią Wifi, a to trwa SEKUNDY i kosztuje pokaźne ilości energii. ESP8266 potrafi spokojnie wziąć 150 mA podczas transmisji. Ktoś gdzieś w Internecie liczył, że przy wysyłaniu co 10 sekund żywotność takiego układu przy zasilaniu baterią 2000 mAh to zaledwie kilka dni i to tylko jak się człowiek postara odpowiednio wprowadzać ESP8266 w deep sleep.
Mam pytanie bo posiadam wyświetlacz 4×20 z konwerterem I2C. Czy dało by radę wyświetlić te dane na wyświetlaczu zamiast serial monitorze. Wdzięczny bym był za kod :)
Witam, chciałbym kupić dwa takie przekaźniki RF jak poniżej:
http://www.aliexpress.com/item/Free-shipping-Wholesale-DC-12v-10A-relay-1CH-wireless-RF-Remote-Control-Switch-Transmitter-Receiver-Case/2044116658.html
czy jest możliwe skalibrowanie ich z nadajnikiem rf opisanym w tym artykule i kierować nimi z Arduino lub Raspberry pi ?
Oczywiście, że tak. Właśniedo takich zastosowań służy zestaw z projektu. Kodowanie interesujących cię modułów jest opisane w pt2262. W Bascom i arduino służy do tego rozkaz pulsein, pulseout. Zastosowanie kodowania manchester jakie zastosował autor projektu jest całkowicie nietrafione. Najlepsze kodowanie podwieloma względami to X10 RF, lub własne z długim bitem Stop. Do zestawu z projektu polecam pilota Medion X10, xa parę groszy z obsługą 100 przycisków.
Ostatnio straszny wysyp 13 i 14-latków z wiedzą przerastającą przeciętnego studenta. Nie sądzę że to prawda.
Chyba przesadzasz, ten projekt i podobne jemu świadczą, za 13,14 latkowie Nie czytają dokumentacji technicznej, niepotrafią zrozumieć podstaw elektroniki. Bazują na gotowych klockach z gotowymi aplikacjami. To droga do nikąd. Za taki projekt jak ten lub choćby próbę podjęcia dyskusji o zastosowaniu Manchesteru do transmisji radiowej, student mógłby Nie zaliczyć roku, albo stać się posmiewiskiem dla kolegów z roku.
Przeceniasz studentów. Oczywiście, jest bardzo wielu 12-14 latków, którzy nie rozumieją podstaw i budują z gotowych klocków metodą prób i błędów “a nuż zadziała”, ale z wieloma studentami jest podobnie, albo gorzej, bo potrafią zlecać komuś projekty. Wiem, bo uczyłem :) Taki 12-latek zajmujący się elektroniką robi to przynajmniej z pasji i wcześniej czy później te podstawy pozna i jeśli będzie kontynuował zabawę przez kilka lat, to na pierwszym roku będzie trzaskał kolegom zadania ze wzmacniaczy. Natomiast wśród studentów jest dużo osób, które poszły na studia bo słyszały, że po tym jest niezła kasa (zwłaszcza dotyczy informatyki) albo bo trzeba było na jakieś studia pójść, bo każdy musi teraz mieć papier.
no proszę… jestem pod ogromnym wrażeniem. doskonały art jak na 14 lat! i pomyśleć, że ja (nieco ponad 30 wiosen na karku) będę się uczył od takiego 14-latka ;)
pozdrawiam!!
Witam.
Wiesz może jak zmienić kod z potencjometrem tak żeby dołożyć przycisk, i zapalać led na odbiorniku? To znaczy regulować sobie tym potencjometrem pwm na jednym wyjściu, a przy okazji przyciskiem zapalać i gasić led w odbiorniku na innym wejściu.
Pozdrawiam.
Odbiorniku czyli Arduino, a wejście pomyliłem, miało być wyjście. Np. pwm na pinie 5, a zapalanie led na np. pinie 2 lub 3. Trzeba by chyba zastosować przerwania dla przycisku.
Mam pytanko. Mam moduł nadajnika i odbiornika rf 433 do arduino a czy można zrobić z tego włącznik/wyłącznik bezprzewodowy, nie używając do tego arduino? Jestem całkiem zielony w tych sprawach ale może ktoś mi podpowie da namiary na jakiś schemat, coś….. co można podpiąć pod te moduły i zrobić z nich bezprzewodowy wł/wył.?Z góry dzięki.
A da rade jednocześnie sterować np. dwoma diodami przez dwa potencjometry?
Skopiowałem kody z najprostszego przykładu “hello world” i nic się kompletnie nie dzieje nawet jak uwspulnie mase i po odpieciu modułów połacze piny. dodam że używam atmegi 328 przy użyciu USBasp oraz klona Arduino UNO
I nie dziw się,że ten 14 latek Ci nie odpowie. On sam zbudował to z gotowych elementów i przypadkiem skopiował kod z innej strony i mu się udało. Proponuje powoli zacząć się uczyć programowania AVR a nie bazować na tym artykule.
Kiedyś potrzebowałem rejestrator danych z wejść analogowych, użyłem do tego Virtual Wire i magnetofonu kasetowego commodore. Ja wiem, że są lepsze i mniejsze nośniki pamięci, dlatego podaję to jako ciekawostkę. Trzeba tylko pamiętać, aby prędkość transmisji zmienić na 4000, przy mniejszej prędkości występują błędy a sygnał odczytu odwrócić przy pomocy tranzystora. Jeśli podczas odczytu danych mają być przerwy, np. po to aby je przeanalizować i silnik magnetofonu jest zatrzymywany to podczas zapisu kolejnych danych też muszą być przerwy co najmniej jednosekundowe, silnik magnetofonu musi się rozpędzić przed odczytem.
Howdy pleasant web site! Person kembali coast samal. Exceptional. Awesome. I’m going to save your website along with take the for on top of that? My business is happy to search out so many valuable data here in the actual posting, we wish acquire far more techniques during this respect, thanks for sharing.
Hej. Próbuję uruchomić ten moduł “na sucho” tzn., bez użycia mikrokontrolera.
Chciałbym uzyskać taki efekt, że gdy dam stan wysoki na pin DATA w nadajniku, to również dostanę stan wysoki na odbiorniku (na pinie DATA). Niestety, takie coś nie działa. Czy powinno ? Czy ta para modułów właśnie tak działa, że gdy dam stan wysoki na nadajniku, to powinienem otrzymać stan wysoki na odbiorniku ? Czy może trzeba jakieś specjalne sekwencje podać, żeby to zadziałało ?
Jak dołożyć kolejną i kolejną zmienną ?
//zmienna 1
for (i = 0; i < buflen; i++)
{
if (char(buf[i]) != '$') // jeśli otrzymanym znakiem nie jest $
hum1+=char(buf[i]);
else // w innym wypadku (jeśli otrzymanym znakiem jests $)
{
i++; // dodajemy 1 do i
last = i;
break; // kończymy pętlę
}
}
//zmienna 2
for (i = last; i < buflen; i++)
{
if (char(buf[i]) != '$') // jeśli otrzymanym znakiem nie jest $
temp1+=char(buf[i]);
else // w innym wypadku (jeśli otrzymanym znakiem jests $)
{
i++; // dodajemy 1 do i
last = i;
break; // kończymy pętlę
}
}
//zmienna 3
for (i = last; i < buflen; i++)
{
if (char(buf[i]) != '$') // jeśli otrzymanym znakiem nie jest $
kupa1+=char(buf[i]);
else // w innym wypadku (jeśli otrzymanym znakiem jests $)
break; // przerywamy pętlę
}
Spoko dałem radę, nie wysyłałem danych :)
Artykuł bardzo dobrze napisany ;)
Jeszcze dopiszę takie uzupełnienie ;)
Żeby nie trzeba było łączyć znaków przy odbiorze danych można zrobić coś takiego:
Jeżeli chodzi o zasięgi udało mi się dotrzeć przez ścianę i szafę około 10-15m, później już gubi zasięg. Antenki zrobiłem z skrętki nie wiem dokładnie jakie długości, ale nie za bardzo mam miejsce w urządzeniu na większe antenki :( czujnik będzie z 5-6m za oknem więc chyba będzie działać ;)
Odbiornik nie może być podłączony do pinu 10, nie wiem dlaczego ale na tym pinie po prostu nie działa.
Jeżeli chodzi o kilka nadajników i jeden odbiornik to rozgryzłem temat w ten sposób:
Żeby rozróżnić co skąd odbieram wysyłam takie tablice czt1-26C oraz czt2-30C, później substr rozbieram sobie ciąg i sprawdzam pierwsze 4 znaki czyli nazwę nadajnika i już wiem skąd mam sygnał ;)
Jest jeden minus tego rozwiązania czasem sygnał się nakłada i dostaję tylko dane z jednego odbiornika ale przy ustawieniu odpowiednich opóźnień działa ok ;)
Jak za takie pieniądze to te badziewka są nawet w porządku ;)
Pozdrawiam
Hej, powie mi ktoś co dokładnie oznacza liczba 15 w linii :”char msg[15];” Czy to znaczy że tablica ma 15 znaków, a jeśli nie wypełnię jej do “pełna” to coś się może stać? Kręcę tym parametrem i nic się nie zmienia. Wybaczcie moją niewiedzę, ale nie znam angielskiego :(
Ponieważ bardzo zależało mi na przesyłaniu liczb z ułamkiem dziesiętnym do 2 cyfr po przecinku, pomnożyłem float razy 100 i zapisałem wartość do inta – w nadajniku, a w odbiorniku oczywiście odwrotnie – podzieliłem. Wszystko wydaje się działać pięknie od 2 lat, ale dziś zauważyłem pewien błąd – jeśli wyślę float o wartości 77.77 dostaję na odbiorniku 77.76, porównywałem setki innych wartości w tym 77.75, 77.78, 88.88, 99.99 itp. itd. i zawsze dostaję poprawną wartość, tylko jak wysyłam 77.77 to odbiera mi 77,76 :( co ciekawe przy wysłaniu 77,76 też dostaję 77,76 czyli poprawnie.
Pomoże ktoś? Robiąc patent posiłkowałem się właśnie tym wpisem, a przesyłam temperaturę z DS18B20 i pomiar napięcie.
Fragment o którym mowa wygląda u mnie tak:
pomiarTemp = temperature * 100; // wysylamy wynik pomnozony przez 100
pomiarV = pomiarAku * 100; // pomiar aku razy 100 da pomiarV
String toSend = (String(pomiarTemp, DEC)) + “$” + (String(pomiarV, DEC)) + “$”; // tekst wiadomości
char msg[23]; // tworzymy tablicę typu char
toSend.toCharArray(msg, toSend.length() + 1); // konwertujemy nasz tekst do tablicy charów
Hej to ja raz jeszcze, wychodzi na to że to nie wina modułu wysyłającego bo wysłałem jako INT liczbę 7777 i bez problemu RX odebrał to jako 77.77.
Taki prosty przykład:
float temperature = 77.77;
int pomiarTemp;
void setup() {
// put your setup code here, to run once:
Serial.begin (9600);
}
void loop() {
// put your main code here, to run repeatedly:
pomiarTemp = temperature * 100;
Serial.println(pomiarTemp);
delay (1000);
}
Według arduino 77.77 razy 100 to jest 7776 – o co chodzi? :D
Witam,
Wszystko śmiga ładnie, pięknie.
Ale jak dopiąć zamiast DHT11 , BMP280 /temp. wilgotność ciśnienie/ ?
Czujnik pracuje na magistrali I2c
Romuś na youtube masz tego pełno :)
Arczi,
Jeśli znalazłeś coś ze wsadem to podlinkuj,
jakoś nie mogę na nic trafić.
A może któryś z Kolegów pomoże zmienić soft podany
przez autora artykułu, może sam autor ?
Fajny artykuł. Dodam tylko z własnego doświadczenia że zasilając 5V, nie używając anten, gdy odbiornik i nadajnik sa oddalone od siebie nie dalej niż 10 cm, sygnał “lubi” się gubić. Dziś idę do sklepu po drucik 0,5mm i spróbuję zrobić antenkę. Zobaczymy ile to pomoże :) Daję 5teczkę bo ten tutek bardzo mi się przyda :)
Witam,
U mnie niestety odbiornik tylko raz odbierał sygnał z nadajnika i to z odległości kilku mm. Myślałem, że przy ponownym podłączeniu będzie przynajmniej podobnie, a tu prócz widocznego setupa nie ma nic . Zbliżenie odbiornika do nadajnika też już nic nie daje. Spróbuje jeszcze zrobić antenkę, ale nie wiem czy to rozwiąże problem…
Hej. Prosze zastosować zalecenia Pana Sakowicza film dostępny na youtbie. Sprawdziłem osobiście oscyloskopem. Do odbiornika należy dolutować opornik 1 M pomiedzy Out i trzecią nóżkę wzmacniacza. Oraz zastowować dławik. U mnie moduł bez anteny działał na odległość 10 metrów przez 3 ściany.
Jaka jest zaleta takiego rozwiązania w porównaniu do komunikacji wifi np. przez ESP8266? Która metoda jest lepsza?
!!! MAM PYTANIE !!!
Czy ta biblioteka działa na arduino nano every? Chyba to wina arduino bo na UNO działa doskonale