Időjárás állomás 433Mhz-es vezetéknélküli adóvevővel
by Roboworld Hobbielektronika
Rövid leírás:
Ebben a rövid projektben bemutatjuk neked, hogyan építheted meg saját időjárás állomásod. A projekt során vezeték nélküli kommunikációt hozunk létre, hogy ne kelljen a vezetékkel törődni. A vezeték nélküli kapcsolatot egy 433Mhz-es rádiófrekvenciás adó és egy vevő fogja biztosítani. A hőmérséklet méréséért egy DHT22-es hőmérséklet és páratartalom érzékelő fog segítségünkre lenni. A DHT22-es hőmérsékletérzékelő a DHT11-es nagytestvére. Különbség köztük, hogy a DHT22-es képes tizedes pontossággal meghatározni a környezet hőmérsékletét és páratartalmát. Bővebben erről az előző (20. projektben) találsz információkat.
Hardware:
2 db Arduino UNO mikrovezérlő
1 db DHT22-es hőmérsékletérzékelő
1db 433Mhz RF adó modul
1 db 433Mhz RF vevő modul
1 db 1602 I2C kommunikációs LCD kijelző
Jumper kábel
Kapcsolási rajz
433MHz-es rádiófrekvenciás modulról:
Áttekintés
A 433 MHz-es RF adó-vevő modulok olyan vezeték nélküli kommunikációs eszközök, amelyek rádiófrekvenciás (RF) jeleket használnak (hasonlóan ahhoz, amit egyes távirányítású játékokban használnak).
A vevő egységet egy kimenetként is felfoghatjuk, amely képes 433MHz -es frekvencia tartományon jelet fogadni, majd azt továbbítani a vezérelt áramkör felé, míg az adó egységet egy bemenetként, amely a hozzá beérkező adatokat küldi el ( pl: távirányítós autó).
Ezek a modulok rövid és hosszú távú kommunikáció esetén is jól működnek. Hosszabb távolság elérése érdekében már antenna használata ajánlott. Antenna csatlakozáshoz használhatunk egy 15-20 cm hosszúságú rézhuzalt, amelyet a modulnak az ANT pontjához kell forrasztani vagy a hozzá tartozó antennával, amelyet a következő kép illusztrál:
Antenna segítségével szabad rálátás mellett az adó és a vevő távolsága akár 90m-is lehet (nem tesztelve). További információkat a hosszú távolság elérése érdekében itt olvashatsz. és itt olvashatsz
Fontos még megjegyezni, hogy a kommunikáció egy irányú lehet: adótól - vevőhöz., mivel számos véletlenszerű rádiójel van környezetünkben, amely a mi eszközünket befolyásolhatja működés szempontjából. Ezeket az eseményeket hívjuk zajnak. A vevők egyszerre csak egy rövid jelzést képesek fogadni. Ez problémás lehet akkor amikor egyszerre több adóval rendelkezünk de csak egy vevővel. Ekkor fontos a megfelelő időzítés.
Specifikáció
Adó
• Működési feszültség: 3V - 12V max. energiafelhasználás 12V
• Működési áram: min 9mA , max 40mA
• Rezonancia üzemmód: (SAW)
• Modulációs mód: ASK ( Amplitude Shift Keying)
• Mûködési frekvencia: 433MHz
• Átviteli teljesítmény: 25mW (12V-nál)
• Frekvenciahiba: + 150 kHz (max)
• Sebesség: kevesebb, mint 10 Kbps
Vevő
• Működési feszültség: 5.0VDC + 0.5V
• Működési áram: ≤5.5mA max
• Működési metódus: OOK / ASK
• Mûködési frekvencia: 315MHz-433.92MHz
• Sávszélesség: 2 MHz
• Érzékenység: 100dBm (50Ω)
• Átviteli sebesség: <9,6Kbps (315MHz és -95dBm)
VirtualWire libraryről
A VirtualWire olyan Arduino könyvtár, amely rövid üzenetek küldésére képes, címzés, újraküldés vagy nyugtázás nélkül. Az üzeneteket 4-6 bites kódolással küldi el. Számos olcsó rádióadót és vevőt támogat.
A könyvtár teljes funkciója:
#include <VirtualWire.h> --> A VirtualWire könyvtár használatához meg kell adni
vw_set_tx_pin --> Az adóadat-pin kiválasztásához:
vw_set_rx_pin --> A vevőadat-pin kiválasztásához
vw_setup (uint16_t speed) -->Az átvitel sebességnek beállítása: A TX sebességnek meg kell egyeznie az RX sebességével. A sebesség 0-tól 9600-ig terjedő bit/sec lehet. Rövid távolsághoz gyors sebességet érdemes használni. A nagyobb, hosszú távolságra a lehető legrövidebb átviteli sebességet kell használni.
vw_rx_start (); --> Elindítja el a vevőegységet, ezt meg kell tennie, mielőtt bármilyen üzenetet fogadna.
vw_rx_stop (); --> Ezt meg kell tennie, mielőtt bármilyen üzenetet fogadna. Amikor egy üzenet elérhető akkor vw_have_message () a visszatérő érték TRUE logikai jelet tartalmaz.
vw_wait_tx (); --> Blokkol és vár, amíg az egész üzenet elküldésre kerül
vw_wait_rx (); --> Blokkol és vár, amíg az egész üzenet megérkezésre kerül
vw_send (uint8_t * buf, uint8_t len); --> Elküld egy üzenetet a megadott hosszúsággal
vw_have_message (); --> Visszaigazolás az üzenet meglétéről
Mintakód és programozás
Ahogy a korábbi 20. projektben is tettük, úgy ebben a projektben is használjuk a megfelelő könyvtárakat. Melyek is ezek? VirtualWire.h , DHT.h , Adafruit sensor, valamint a LiquidCrystal.h könyvtárakat.
Mivel vezeték nélküli kapcsolatot akarunk létrehozni, így szükségünk van egy „adó” mintakódra és egy „vevő” mintakódra. A programok feltöltése után, láthatjuk, hogy a vezérlőink 13-as LEDjei felvillannak amikor adatküldés és adatbeérkezés történt. Ez egy jó visszacsatolás számunkra, hogy létrejött a kommunikáció.
Adó:
#include <VirtualWire.h> // VirtualWire library használata
#include "DHT.h" // DHT library használata
#define DHTPIN 4 // 4-es pinre csatlakozik a DHT hőmérséklet szenzor
#define DHTTYPE DHT22 // Kiválasztottuk ,hogy DHT22-es típusú hőmérséklet szenzort használunk.
// Ha DHT11 -et szeretnénk akkor a DHT22 helyett DHT11-et írunk a helyére
const int led_pin = 13; // 13-as LED pin
const int transmit_pin = 12; // A 12-es pinen keresztül küldi az információt
struct package // Adó adata amit küld
{
float temperature ;
float humidity ;
};
typedef struct package Package;
Package data;
DHT dht(DHTPIN, DHTTYPE);
void setup()
{
vw_set_tx_pin(transmit_pin);
vw_set_ptt_inverted(true); // Required for DR3100
vw_setup(500); // Bit per sec
pinMode(led_pin, OUTPUT);
}
void loop()
{
digitalWrite(led_pin, HIGH); // A LED villog amikor adat küldés történik
readSensor();
vw_send((uint8_t *)&data, sizeof(data));
vw_wait_tx(); // Egészen addig vár míg a teljes üzenet elment
digitalWrite(led_pin, LOW);
delay(2000); //2s vár
}
void readSensor()
{
dht.begin();
delay(1000);
data.humidity = dht.readHumidity(); // Olvassa a páratartalmat a szenzor
data.temperature = dht.readTemperature(); // Olvassa a hőmérsékletett a szenzor
}
Vevő: #include <VirtualWire.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h> // LiquidCrystal_I2C könyvtár használata
//(addr, EN,RW,RS,D4,D5,D6,D7,BL,BLpol)
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // LiquidCrystal_I2C könyvtárat használjuk
// Szükséges megadni a kommunikációs csatornát. Esetünkben ez 0x3F azonban ez eltérhet.
// Ha nem működik a 0x3F akkor i2c_scanner.ino futtatása szükséges, amely kiírja a megfelelő értéket. 0x3F-et átírva pl: 0x27 -re megoldhatja a kommunikációs hibát.
byte thermometer[8] = //Hőmérő ikon
{
0b00100,
0b01010,
0b01010,
0b01110,
0b01110,
0b11111,
0b11111,
0b01110
};
byte droplet[8] = //Csepp ikon
{
0b00100,
0b00100,
0b01010,
0b01010,
0b10001,
0b10001,
0b10001,
0b01110,
};
const int receive_pin = 12; // 12-es pint kiválasztva a vevő data pinnek
char temperatureChar[10]; // egyéni hőmérséklet karakter
char humidityChar[10]; // egyéni páratartalom karakter
struct package //Package struktúra definiálása, lényegébében ez az adat amilyen formában várjuk azt.
{
float temperature = 0.0;
float humidity = 0.0;
};
typedef struct package Package;
Package data;
void setup()
{
lcd.begin(16, 2); // 2 soros 16 karakteres LCD meghatározása
Serial.begin(9600);
delay(1000);
lcd.createChar(1, thermometer); // Egyedi karakter képzés (hőmérő)
lcd.createChar(2, droplet); // Egyedi karakter képzés (vízcsepp)
vw_set_rx_pin(receive_pin);
vw_setup(500); // Bit per sec
vw_rx_start(); // Start: Vevő figyel, hogy jön e adat
}
void loop()
{
uint8_t buf[sizeof(data)];
uint8_t buflen = sizeof(data);
if (vw_have_message()) // Van üzenet számunkra ?
{
vw_get_message(buf, &buflen);
memcpy(&data, &buf, buflen);
Serial.print("\nHomerseklet: ");
Serial.print(data.temperature);
String temperatureString = String(data.temperature, 1);
temperatureString.toCharArray(temperatureChar, 10);
String humidityString = String(data.humidity, 1);
humidityString.toCharArray(humidityChar, 10);
Serial.print("\nParatartalom: ");
Serial.println(data.humidity);
lcd.setCursor(0, 0); // a kurzort a 0 karakterhez és az 1 sorhoz helyezi
lcd.write(1); // hőmérő kijelzőre írása
lcd.print(" Hom.: "); // Kiírja hogy "Hom: "
lcd.print(data.temperature);
lcd.write(0b11011111);
lcd.print("C");
delay(10);
lcd.setCursor(0, 1); // a kurzort a 0 karakterhez és az 1 sorhoz helyezi
lcd.write(2); // vízcsepp képernyőre írása
lcd.print(" Parata:"); // Kiírja hogy "Parata: "
lcd.print(data.humidity);
lcd.print("%");
delay(10);
}
}
Letöltés
A leírás PDF-ben: itt elérhető
Mintakód letöltése
Libraries letöltése
Megjegyzések
Megjegyzés küldése