Lekce 20 - Arduino a využití 433,92 MHz

04.06.2013 16:19

Translate to English
  

Po nějaké době opět zdravím u dnešního tutoriálu, který se bude na přání věnovat využití frekvence 433,92Mhz (434Mhz) na bezdrátové ovládání čehokoliv na vzdálenost řekněme při dobrých podmínkách do 50m. Pracovat s ním budeme samozřejmě s Arduinem. K tomuto budeme potřebovat dva moduly pro frekvenci 433,92 MHz a to jeden vysílací a jeden přijímací. Cenu modulů sem ani psát nebudu, je hodně druhů a já používám nějaký ze zahraničí za cenu asi okolo 100 až 150 Kč.

Přijmač Vysílač

 

Všechny moduly vypadají od různých firem vesměs stejně rozhodující bude funkce, která je u všech modulů stejná. Vyobrazený modul vysílače má celkem 3 vývody z čehož jsou 2 pro napájení a jeden pro data. U přijímače jsou celkem 4 piny, ale data jsou na pinech 2 a 3, jsou propojena, takže je jedno kam vodič "připíchnete". Na modulech je zapojení čitelně značeno, takže by němel vzniknout problém. Napájecí napětí je našich klasických 5V z Arduina. 

Teď trošku k funkci. Představme si komunikaci mezi modulem (jednostranná od přijímače k vysílači) jako klasické vysílání rádia s tím, že probíhá digitálně (1000101010). Mnozí z Vás si ale myslí, že když přivedeme 1 (hodnota HIGH) na datový pin u vysílače tak se u přijímače objeví na datovém výstupu také jednička a když vysíláme 0 (hodnota LOW) tak na výstupu bude také 0. To není tak zcela pravda. V době dnešního digitálního vysílání to již na obrazovkách moc není vidět, ale v případě, kdy jste ztratili anténní příjem, tak jste na obrazovce viděli jen šum, v případě rádia také to jenom šumělo. A to je i v případě našeho přijímače. Neustále běhají na výstupu přijímače jedničky a nuly a to nekontrolovaně a zcela náhodně. Na vině je klasický šum z prostředí (vypínaní spotřebičů, atmosférické poruchy a jiné) a také ostatní vysílání na této frekvenci (meteostanice, dálková ovládání nebo jiná zařízení pracující z touto frekvencí 433 Mhz. Úkolem bude udělat v džungli jedniček a nul nějaká pravidla pro vysílač, který vyšle sekvenci dat v sekvenci, kterou si určíme a také abychom mohli naprogramovat Arduino s přijímačem tak, aby zrovna v záplavě jedniček a nul našel naše vysílání a zpracoval data jen taková, která chceme. 

Samozřejmně to zase zní trošku složitě. My si vše ulehčíme. My totiž použijeme knihovnu využívající již vymyšlený a fungující protokol komunikace pro výrobky firmy RFLightWave. Ta totiž při komunkaci (el.l zásuvky ovládané dálkovým ovládáním) odesílá vysílač přimači 10 4bitových hodnot (v překladu pošle 10 čísel v rozsahu od 0 do 15). Takže jako první si samozřejmě seženeme moduly vysílače a přijímače, dále budeme potřebovat 2 kusy nějakých Arduin (asi jedno jakých) a to je zatím vše.

Nejprve si postavíme vysílač. Modulek vysílače zapojíme např. přes kontaktní pole s Arduinem (v mém případě Arduino UNO). Napájení modulu klasicky a datový vstup jsem napojil na pin č. 3. jak můžete na obrázku níže vidět.

Vysílací modul bude obdobně zapojen s tím, že datový výstup s přijímače je na pin 2 s použitím Arduina MEGA.

Tak teď si stáhneme naše knihovny pro práci s vysílačem a přijímače. Knihovna je každá zvlášť pro přijímač a vysílač. Najdete ji na adrese zde. Po stažení si ze zipu nakopírujete z adresáře libraries dva adresáře LvRx a LvTx do adresáře libraries v prostředí Arduina. Kam kopírovat knihovny jsme si vysvětlili již v minulých dílech tak by Vám neměl vzniknout žádný problém. Kdyby na uvedeném odkazu již soubory nebyli, kontaktujte mě a já se pokusím nalézt jinde. 

Tak po nahrání knihoven si do Arduina s vysílačem nahrajeme i tento program:

Jak vidíte není složitý. Máme tam funkci lwtx_setup(3, 2);, která inicializuje vysílač a nastaví, že datový vstup vysílače je na pinu 3. Druhý parametr ta dvojka je že se vysílač data odvysílá 2x za sebou, kdyby se v tom davu jedniček a nul asi nějaké vysílání ztratilo. To zvyšuje spolehlivost přenosu. Soudím dle autora knihovny. Potom tam máme funkci lwtx_free();, která vrací zda je vysílač volný a nemá žádnou práci. Vrací TRUE nebo FALSE. Když je tedy volný, můžeme vysílat. A nakonec funkce lwtx_send(data); - ta odešle konečně naše data. Jedná se o čísla od 0 do 9. (jak jsem již uvedl, můžete zadat čísla až do 15 (4bitové hodnoty). Výsledek se zobrazí na serial port s tím, že Arduino každých 5 sekund odvysílá naše data a na Serial port vypíše "Data odeslana".  

Tak jestli vysílač funguje správně zjistíme až si zprovozníme přijímač. Do druhého Arduina si připojíme modul přijímače. U mne tedy na pin 2. Pozor - knihovna pro příjem používá pro detekci přijmu signálu tzv. přerušení, takže můžeme použít v případě Arduina UNO nebo MEGA pouze pin 2 nebo 3. Přerušení - interrupt si vysvětlíme u zřejmě dalšího tutoriálu, kde jej využijeme. 

Nyní si nahrajeme do Arduina s přijímačem tento program:

Vysílač necháme zapnutý a přijímač zapojíme také. Spustíme si SerialMonitor (nezapomeňte si nastavit správný COM - port, aby jste nesledovali vysílač, kde se objevuje pouze nápis "Data odeslana"). Na výstupu vidíme, že se nám tam objevují po 5 vteřinách čísla  1 2 3 4 5 6 7 8 9 0 tak jak jsme je odvysílali :-)

Tak pokud vidíte toto tak gratuluji, vše funguje bezvadně. Můžete si zkusit jaký má vysílač a přijímač dosah a připájet si jak u vysílače tak u přijímače antenku ve formě drátu nebo vodiče o délce 10 - 15 cm. V mém případě mám anténu pouze u vysílače a když jsem dal vysílač do druhé místnosti tak data na přijímač stále chodily. Ale samozřejmě že lepších výsledků dosáhnete, použijete-li anténu na obou zařízeních. 

Data jsme si tedy nějak odeslali, ale nějak nevyužili. V prvním případě si ukážeme jak jednoduše zapínat a vypínat třeba nějaké spotřebič nebo zásuvku. Jak to tedy uděláme. Jednoduše. Prostě budeme odesílat jak jednu hodnotu pro zapnutí tak druhou pro vypnutí.

Na kontaktní pole si tedy dáme u vysílače ještě 2 tlačítka, která připojíme k digitálnímu pinu 4 (pro zapnutí) a 5 (pro vypnutí). Nesmíme zapomenout na odpor cca 10KOhm, který připojíme piny ke GND (LOW), jinak v případě nestisknutého tlačítka tam nebyla ani LOW ani HIGH hodnota. Ale pro jistotu malý plánek :-):

  

Tak taková tlačítka tedy připojíme 2. Nahrajeme do Arduina tento prográmek:

Z programu je zřejmé, že jsme si připravili do proměnných "zapnuto" a "vypnuto" hodnoty. Rozdílná je pouze hodnota na konci, kde při zapnutí je 1. Program v cyklech hlídá, zda bylo stisknuto nějaké tlačítko. Když zjistí, že ano odešle příjímač hodnotu buď k zapnutí nebo vypnutí. Teď, když si zapneme přijímač a k němu SerialMonitor, uvidíme hodnoty, které byly přijmuty při stisku tlačítek. To čekání (delay(400);) je tam z důvodu, že stisk může trvat nějakou dobu a hodnoty by se neustále odesílali. 

Je to opravdu hodně zjednodušeno, ale funkci to splní, teď si jenom napíšeme jiný prográmek pro přijímač a k Arduinu s modulem přijímače připojíme LED diodu k pinu 3, která bude simulovat zapnutí třeba relé, ketré bude zapínat a vypínat zásuvku či jiný spotřebič (nezapomeňte na odpor tak cca 1,2 kOhm k LED). 

A co se nám stalo? Jedno tlačítko diodu rozsítí a druhé jí zhasne. A dálkové ovládání třeba k zásuvkám máme hotové :-). Samozřejmně můžeme přidat další tlačítka k ovládání čehokoliv jak jen je libo a co nám Arduino dovolí.

Já ještě na konci nastíním, jak využít také vysílač a přijímač k přenosu nějakých dat k druhému zařízení. A vyzkoušíme si třeba přenést hodnotu teploty z čidla DTH11, jehož funkci a použití jsme si popsali v lekci 6. Připravíme si tedy nějaké čidlo v mém případě již zmíněné DHT11 (samozřejmě můžete použít i cokoliv jiného z čehoz získáme nějakou hodnotu) a něco kam budeme tyto hodnoty na přijmači zobrazovat. Abych se vyhnul složitosti připojení, použiji LCD displej s modulem na I2C. 

Tak nejprve si nahrajeme program do vysílače upraveného pro získání hodnoty z DHT11. 

Vysvětlení k DHT11 najdete v lekci 6 takže to rozebírat nebudeme. Víme ale, že teplota z čidla je v celých číslech a na její uchování a přenos nám bude stačit nějaké 8-bitové číslo (0-255). Vysílač nám vysílá sekvenci 10ti 4bitových čísel. Použijeme tedy dvě poslední 4-bitová čísla do kterých si pomocí bitového posunu hodnotu o teplotě rozdělíme. Jak je vidět z kódu, je to velice jednoduché. Pokud by jsme potřebovali odeslat větší hodnotu než 255, použijeme více 4bitových čísel (bitový posun jsme si vysvětlili již u zápisu a čtení z EPROM) Například takto:

Tak vysílač je funkční, můžeme zkusit i bez displeje s připačem a ukázkou programu, kdy se hodnoty vypisují na SerialMonitor. Pokud, ale máme nějaký displej, připojíme a zkusíme si hodnotu o teplotě zobrazit. Jak jsem již podoktnul, já použiji LCD displej 16x2 znaků připojený na I2C modul, aby jsem měl zapojení co nejjednodušší a takto mi budou stačit k propojení displeje s Arduinem jen 4 vodiče. Kód pro přijímač je zde:

Přenos jakékoliv hodnoty je jednoduchý a pomocí rozložení hodnoty na 4bitové informace a následné složení není složité. Nyní by jste měli být schopni vytvořit i sami sofistikovanější projekty, kde budete  cokoliv řídit nebo přenášet hodnoty dálkově pomocí modulů na 433 MHz.

 

Zpět

Diskusní téma: Lekce 20 - Arduino a využití 433,92 MHz

Datum
Vložil
Titulek

Nefunkční

Ahoj. Pokouším se rozchodit první příklad. U vysílače mi při kompilaci neustále vyskakovala chyba u lwtx_setup(3, 2,)
z přiloženého příkladu u knihovny jsem to změnil na : lwtx_setup(3, 2, 0, 140) a kompilace proběhla. Na serial monitoru taky vše běží jak má, ale přijímač mi nepříime vůbec nic. Patřím taky do skupinky úplných začátečníků.

Díky moc za odpověď

Datum
Vložil
Titulek

Chybný příjem

Ahoj, potřebuji pomoc. Sestavil jsem a napsal vše co se tu řeklo. Jak přijímač, tak vysílač jedou až na jeden malý problémek. Když zapnu přijímač, tak po 5s (to je správně) začne přijímat. Bohužel nezobrazuje to co posílám, ale stále se opakující 207 95 111 231 243 178 251 251 63 230. Když následně odpojím vysílač, tak se nic nestane a přijímač vypisuje tuto hlášku stále dokola. Prosím o pomoc, jsem v tomto světě (arduino) nováček, takže asi tak.
Moc děkuji za pomoc.

Datum
Vložil
Titulek

Re: Chybný příjem

Jinak ta čísla se změní třeba na 207 95 111 231 179 178 251 255 205 81 po buildu.

Datum
Vložil
Titulek

příklad s 2 tlačítky

Zdravím, ať to prohlížím jak chci nevidím jak to ovládá právě jen poslední bit.

Datum
Vložil
Titulek

Re: příklad s 2 tlačítky

Navíc teď při zkoušce jen v IDE mi to hlásí :
sketch_feb20a.ino: In function 'void setup()':
sketch_feb20a.ino:13:18: error: too few arguments to function 'void lwtx_setup(int, byte, byte, int)'
In file included from sketch_feb20a.ino:1:0:
C:\Program Files (x86)\Arduino\libraries\LwTx/LwTx.h:37:13: note: declared here
extern void lwtx_setup(int pin, byte repeats, byte invert, int uSec);

Datum
Vložil
Titulek

chyba kompilace

DD, zkouším aplikovat INO pro TX a RX a v obou případech to háže chybu při kompilaci:
avr-g++: error: missing filename after '-o'
Zkoušel někdo jen zkompilovat RX a TX bez chyb? Mám 1.8.1 a knihovnu zde doporučenou.
Děkuji, Petr

Datum
Vložil
Titulek

asj

Dobrý den,
Potřeboval bych vysílat ze čtyř vysílačů nejlépe do jednoho přijímače ?jde to ?nebo musím mít na každý vysílač svůj přijímač.
Případně, zapojím 4 přijímače na arduino due? Popřípadě, jak by vypadal přibližně program ?Děkuji

Datum
Vložil
Titulek

Re: asj

Jde to

Datum
Vložil
Titulek

Re: asj

Taky jsem řešil a hledal nějaké elegantní řešení a našel jsem toto... je to skvělé řešení... ukázka mého prog
V podstatě jde o to že data strukturuji, oděšlu přes bezdrát (433,92 SuperHet) a pak tu strukturu na druhé straně rozložím na původní data. je to část STRUCT a za int temp1 může být x-dalších a nejen int ale klidně float atd.

ten kontainer musí být na obou stranách stejný. v příkladu vyčítám jeden sensor DS18B20 ale v podstatě není problém jich použít více či i kombinovat více senzorů.... co nacpete na jedné straně do "kontaineru", na druhé vyleze.
Používám pro Přenost knihovnu VirtualWire (nyní je z ní RadioHead a VW už není rozvíjena)

použitý RF kit https://www.geeetech.com/433mhz-superheterodyne-3400-rf-link-kits-p-167.html
v rámci domu funguje bez problému jen s kouskem drátku



vysílač:

#include <VirtualWire.h>
#include <VirtualWire_Config.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 2

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

const int led = 4;
const int transmit_pin = 12;
boolean SenseSuccess = false;

float DS18B20 = 0.0;

void setup(void)
{
Serial.begin(9600);
sensors.begin();

// nastaveni vysilace 433MHz
vw_set_tx_pin(transmit_pin);
vw_set_ptt_inverted(true);
vw_setup(2000); // rychlost prenosu 2000bps

}

void loop(void)
{
SenseSuccess = PollSensors();
if(SenseSuccess == true)
{ TransmitData();
}
else {
LEDBlink();
LEDBlink();
LEDBlink();
}
delay(5000);

}

boolean PollSensors()
{
sensors.requestTemperatures();
DS18B20 = sensors.getTempCByIndex(0);

if( isnan(DS18B20))
{
return false;
}
else {
return true;
}
}

void TransmitData()
{
struct wData_STRUCT {
byte identifierB;
int temp1;
};

wData_STRUCT wData;

wData.identifierB = 100;
wData.temp1 = (DS18B20*100);

vw_send((uint8_t *)&wData, sizeof(wData));
vw_wait_tx();
LEDBlink();
}

void LEDBlink()
{
digitalWrite(led,HIGH);
delay(500);
digitalWrite(led,LOW);
delay(500);
}


Přijímač:

#include <VirtualWire.h>

const int led = 2;
const int receive_pin = 12;

struct wData_STRUCT {
byte identifierB;
int temp1;
};

wData_STRUCT wData;

float ts1 = 0.0;


void setup()
{
delay(1000);
Serial.begin(9600);

// Initialise the IO and ISR
vw_set_rx_pin(receive_pin);
vw_set_ptt_inverted(true);
vw_setup(2000); // 2000bps

vw_rx_start(); // Start prijimace
}

void loop()
{
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;

if (vw_get_message(buf, &buflen)) // Non-blocking
{
if (buflen == sizeof(wData_STRUCT))
{
memcpy( &wData, buf, sizeof(wData));
ts1 = (wData.temp1/100);
Serial.println(ts1);
LEDBlink();
}
else {
Serial.println("error");
LEDBlink();
LEDBlink();
LEDBlink();
}

}
}
void LEDBlink()
{
digitalWrite(led,HIGH);
delay(500);
digitalWrite(led,LOW);
delay(500);
}

Datum
Vložil
Titulek

Re: Re: asj

jinak k struktuře řeknu, že těch vysílačů od kterých se příjímají data může být více a každý může mít své ID, svoji vlastní strukturu ("konteiner").
ID je toto: wData.identifierB = 100;
ted ho v programu k ničemu nepoužívám, nechal jsem to tam k budoucímu využití.

tzn. jeden kontainer = jeden vysílač s x-senzory či daty. Nebo jeden vysílač může používat víče techto kontainerů a v jednom vysílat teploty každých 5min, v druhém pak třeba stav baterie jednou za hodinu.



1 | 2 | 3 | 4 | 5 >>

Vyhledávání

arduino8.cz © 2015 Všechna práva vyhrazena.