Po stronie nadawczej Arduino nano wykrywa temperaturę i wilgotność powietrza w pomieszczeniu za pomocą czujnika DHT22 i przesyła dane do odbiornika Arduino poprzez łącze RF 433 MHz ASK. Arduino po stronie odbiorczej dekoduje otrzymane bajty i wyświetla informacje na ekranie LCD. Zasięg wewnętrzny transmisji RF wynosi około 30m, co jest wystarczające nawet dla dużego domu.
Do zbudowania tego projektu będziesz potrzebował następujących elementów:
- Para nadajnik/odbiornik ASK
- Dwie płytki Arduino. Ja używam Arduino Nano po stronie nadawczej i Arduino Uno po stronie odbiorczej.
- Jeden wyświetlacz LCD Nokia 5110 do wyświetlania danych po stronie odbiorczej
- Jeden czujnik DHT22 do pomiaru temperatury i wilgotności po stronie nadawczej
- Dwie diody LED i dwa oporniki 330 Ω
- Przewody, płytka drukowana, płytka prototypowa, itp.
Kilka słów o zestawach ASK RF
Istnieją różne moduły ASK Tx/Rx dostępne online zarówno na rynku krajowym jak i międzynarodowym (szczególnie w Chinach). Niektóre z nich są dostarczane z antenami sprężynowymi, a niektóre nie. W przypadku tych bez anten, można podłączyć przewód o długości ~20 cm do pinu antenowego na płytce drukowanej. Poniższy rysunek pokazuje niektóre z modułów ASK RF, które można kupić na eBay i Amazon.
Do tego projektu użyłem wysokiej jakości modułów ASK RF produkowanych przez NiceRF, firmę z Chin. Są to bardzo kompaktowe moduły, wykonane na płytkach PCB wysokiej jakości PCB, dostarczane z miedzianymi antenami sprężynowymi i mają rozsądny zasięg transmisji.
Konfiguracja sprzętowa po stronie nadawczej
Moduł nadajnika ASK ma trzy piny: VCC, Data, oraz Gnd. Mogą one być w różnej kolejności w zależności od producenta. Dlatego zawsze należy uważnie czytać etykiety pinów, aby zidentyfikować piny danych i zasilania w tych modułach. Piny VCC i Gnd są podłączone do pinów +5V i Gnd Arduino Nano, podczas gdy pin Data modułu Tx idzie do cyfrowego I/O pin 12 Arduino. Do pinu I/O 11 podłączona jest również dioda LED wraz z szeregowo połączonym rezystorem ograniczającym prąd. Podczas transmisji danych dioda ta jest włączona.
Obwód ten jest połączony na płytce prototypowej, jak pokazano niżej.
Konfiguracja obwodu: Rx End
Moduł Rx składa się również z pinów VCC, Gnd i Data. Niektóre moduły mogą mieć więcej niż jeden pin Data. W takim przypadku możesz użyć dowolnego z nich, ponieważ wszystkie są połączone razem. Po stronie odbiorczej, pin Data modułu Rx jest wyprowadzany i odczytywany przez pin Arduino. W naszym przypadku jest on podłączony do pinu D11 w Arduino. Podobnie jak w przypadku końcówki Tx, dioda LED podłączona do pinu D3 jest wskaźnikiem odbioru danych wysyłanych przez nadajnik. Do Arduino po stronie odbiorczej podłączony jest również wyświetlacz LCD Nokia 5110, który wyświetla temperaturę i wilgotność na zdalnej stacji. W tym eksperymencie używam Crowduino Uno (klon Arduino Uno) po stronie odbiorczej.
Należy pamiętać, że wyświetlacz LCD Nokii 5110 działa przy napięciu 3,3 V. Ja używam mojej płytki Crowduino Uno z napięciem 3,3 V, więc nie ma to znaczenia w tym przypadku. Jeśli twoja płytka Arduino pracuje pod napięciem 5,0 V, będziesz potrzebował dzielnika napięcia pomiędzy Arduino a LCD. Poniższy schemat pokazuje połączenia po stronie odbiorczej w sposób bardziej szczegółowy.
Do zbudowania powyższego obwodu użyłem proto-shield Arduino ogólnego przeznaczenia. Poniższy rysunek pokazuje zmontowany obwód odbiornika przylutowany do Arduino proto-shield.
Oprogramowanie
W projekcie wykorzystano bibliotekę VirtualWire dla Arduino napisaną przez Mike'a McCauleya. Biblioteka ta obsługuje wiele tanich nadajników i odbiorników RF dostępnych na rynku i pozwala na wysyłanie krótkich wiadomości poprzez modulację ASK. W tym projekcie Arduino po stronie Tx odczytuje temperaturę i wilgotność z czujnika DHT22, łączy te dwa odczyty w ciąg znaków i wysyła go przez łącze RF. Po stronie odbiorczej, Arduino wyodrębnia dwa odczyty z otrzymanego ciągu znaków i wyświetla dane na wyświetlaczu LCD Nokii 5110. Bibliotekę VirtualWire oraz kody Arduino dla końcówek Tx i Rx można pobrać z linków na końcu artykułu.
Po wgraniu firmware do dwóch płytek Arduino, projekt jest gotowy do testów. Możesz umieścić moduł Tx w miejscu, w którym chcesz zdalnie monitorować temperaturę i wilgotność oraz umieścić moduł Rx w zasięgu 30 m. Powinieneś zobaczyć zmierzone wartości na ekranie LCD, jak pokazano poniżej:
Ten projekt może być dalej rozbudowany poprzez dodanie brzęczyka do Rx i zaprogramowanie Arduino do alarmowania, gdy temperatura i/lub wilgotność spadnie poza ustawione limity.
#include <VirtualWire.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
#include <Adafruit_Sensor.h>
Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 5, 4, 2);
const int receive_pin = 11;
const int led_pin = 3;
void setup()
{
delay(1000);
Serial.begin(9600); // Debugging only
Serial.println("setup");
display.begin();
display.setContrast(50);
display.clearDisplay();
// Initialise the IO and ISR
vw_set_rx_pin(receive_pin);
vw_set_ptt_inverted(true); // Required for DR3100
vw_setup(2000); // Bits per sec
vw_rx_start(); // Start the receiver PLL running
}
void loop()
{
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(buf, &buflen)) // Non-blocking
{
int i;
buf[buflen] = '\0';
digitalWrite(led_pin, HIGH);
// Message with a good checksum received, print it.
Serial.print("Got: ");
Serial.print(buflen);
Serial.print("Got: ");
for (i = 0; i < buflen; i++)
{
Serial.write(buf[i]);
}
Serial.println();
// digitalWrite(led_pin, LOW);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(0,0);
display.print("Baby's Room");
display.setTextSize(2);
display.setTextColor(BLACK);
display.setCursor(0,14);
char tt[5]={buf[0],buf[1], buf[2],buf[3],'\0'};
char rh[5]={buf[6],buf[7], buf[8],buf[9],'\0'};
display.print(tt);
display.setTextSize(1);
display.print(" o");
display.setTextSize(2);
display.print("F");
display.setTextSize(1);
display.setCursor(0,35);
display.print("Humidity=");
display.print(rh);
display.print("%");
display.display();
delay(100);
digitalWrite(led_pin, LOW);
}
}
#include "VirtualWire.h"
#include "DHT.h"
#include "string.h"
#define DHTPIN 5 // what pin we're connected to
// Uncomment whatever type you're using!
//#define DHTTYPE DHT11 // DHT 11
#define DHTTYPE DHT22 // DHT 22 (AM2302)
const int led_pin = 11;
const int transmit_pin = 12;
//const int receive_pin = 2;
//const int transmit_en_pin = 3;
DHT dht(DHTPIN, DHTTYPE);
void setup()
{
// Initialise the IO and ISR
vw_set_tx_pin(transmit_pin);
// vw_set_rx_pin(receive_pin);
// vw_set_ptt_pin(transmit_en_pin);
vw_set_ptt_inverted(true); // Required for DR3100
vw_setup(2000); // Bits per sec
dht.begin();
Serial.begin(9600); // Debugging only
Serial.println("DHT22 Tx");
}
char buffT[6];
char buffH[6];
char buff[15];
void loop()
{
float h = dht.readHumidity();
float t = dht.readTemperature();
float tf = t*9.0/5.0 + 32.0;
// check if returns are valid, if they are NaN (not a number) then something went wrong!
if (isnan(t) || isnan(h)) {
Serial.println("Failed to read from DHT");
} else {
Serial.print("H=");
Serial.print(h);
Serial.print(" %\t");
Serial.print("T= ");
Serial.print(tf);
Serial.println(" *F");
dtostrf(tf, 5,2, buffT);
Serial.print("buffT= ");
Serial.println(buffT);
dtostrf(h, 5,2, buffH);
Serial.print("buffH= ");
Serial.println(buffH);
buff[0]='\0';
strcat(buff, buffT);
strcat(buff, " ");
strcat(buff, buffH);
Serial.print("Mess= ");
Serial.println(buff);
digitalWrite(led_pin, HIGH); // Flash a light to show transmitting
vw_send((byte *)buff, strlen(buff));
vw_wait_tx(); // Wait until the whole message is gone
digitalWrite(led_pin, LOW);
delay(10000);
}
}