Eine zuverlässige Arduino-basierte Wireless Wetterstation bauen
In diesem Tutorial lernen wir, wie man eine Arduino-basierte Wireless Wetterstation baut. Sie können das folgende Video ansehen oder die schriftliche Anleitung unten lesen. Die Außentemperatur und -luftfeuchtigkeit werden mit dem DHT22-Sensor gemessen und diese Daten werden drahtlos an die Inneneinheit über NRF24L01-Transceiver-Module gesendet. An der Inneneinheit befindet sich ein weiterer DHT22-Sensor zur Messung der Innentemperatur und -luftfeuchtigkeit sowie ein DS3231 Real Time Clock Modul, das die Zeit auch bei Stromausfall behält. Alle diese Daten werden auf einem 0,96″ OLED-Display angezeigt. Sehen wir uns den Schaltplan an und wie dieses Projekt funktioniert. Beachten Sie, dass ich bereits detaillierte Tutorials zu jedem dieser Module habe, die Sie für weitere Details prüfen können: NRF24L01 Tutorial, DHT22 Tutorial, DS3231 Tutorial. Sie erhalten die für dieses Projekt benötigten Komponenten über die Links unten: Sowohl das Real Time Clock Modul als auch das OLED-Display verwenden das I2C-Protokoll zur Kommunikation mit dem Arduino, daher sind sie an die I2C-Pins oder die analogen Pins 4 und 5 am Arduino Nano Board angeschlossen. Direkt neben dem NRF24L01 Transceiver Modul befindet sich ein Kondensator, um die Stromversorgung stabiler zu halten. Es gibt auch einen Pull-Up-Widerstand am Datenpin des DHT22, damit der Sensor ordnungsgemäß funktioniert. Für die Stromversorgung habe ich ein 12V DC Netzteil für die Inneneinheit verwendet, und für die Außeneinheit zwei Li-Ion-Akkus, die ca. 7,5V liefern. Mit dieser Konfiguration konnte die Außeneinheit ca. 10 Tage laufen, bevor die Akkus entladen waren, da wir Daten periodisch senden und den Arduino dazwischen in den Sleep-Modus versetzen, wo der Stromverbrauch nur ca. 7mA beträgt. Um die elektronischen Bauteile organisiert zu halten, habe ich gemäß dem Schaltplan eine benutzerdefinierte PCB mit der kostenlosen Online-Schaltungsdesign-Software EasyEDA entworfen. Man beachte, dass dieselbe PCB sowohl für die Innen- als auch für die Außeneinheit verwendet werden kann, nur der Arduino Board muss unterschiedlich programmiert werden. Nach Abschluss des Designs können wir einfach die Gerber-Datei exportieren, die für die PCB-Fertigung verwendet wird. Sie können die EasyEDA-Projektdateien der Arduino Wireless Wetterstation hier überprüfen. Dann können wir unsere PCB bei JLCPCB bestellen, was tatsächlich der Sponsor dieses Videos ist. Hier können wir einfach die Gerber-Datei per Drag & Drop hochladen und sie im Gerber-Viewer prüfen. Wenn alles in Ordnung ist, können wir fortfahren, die gewünschten Eigenschaften für unsere PCB auswählen und sie zu einem vernünftigen Preis bestellen. Beachten Sie, dass Sie bei Ihrer ersten Bestellung bei JLCPCB bis zu 10 PCBs für nur 2$ erhalten können. Nach einigen Tagen sind die PCBs angekommen. Die Qualität ist hervorragend und alles entspricht genau dem Design. Ich begann mit dem Bestücken der elektronischen Bauteile, indem ich Pin-Header auf die PCB lötete. So können wir die Komponenten bei Bedarf einfach anschließen und trennen. Dann lötete ich auch den Kondensator und den Pull-Up-Widerstand ein. Mit diesem Schritt können wir nun einfach die Komponenten auf die Pin-Header der PCB stecken. Als Nächstes fertigte ich die Gehäuse für das Projekt an. Dafür verwendete ich 8mm starkes MDF-Board und schnitt mit einer Kreissäge alle Teile auf Maß. Um genaue Temperatur- und Feuchtigkeitsmessungen zu ermöglichen, müssen die Seiten der Gehäuse Luft zulassen. Deshalb bohrte und feilte ich mehrere Schlitze in die Seitenwände sowohl der Innen- als auch der Außeneinheit. Ich machte auch einen Schlitz für das OLED-Display auf der Frontplatte sowie ein kleines Stück Aluminium, das ich später als Dekoration auf der Frontplatte anbrachte. Für den Zusammenbau der Gehäuse verwendete ich Holzleim, Zwingen und einige Schrauben. Ich lackierte die Gehäuse mit Sprühfarbe: Weiß für die Außeneinheit und Schwarz für die Inneneinheit. Nach dem Trocknen steckte ich einfach die PCBs in die Gehäuse. An der Rückseite der Inneneinheit brachte ich eine Strombuchse und einen Netzschalter an, an der Außeneinheit verwendete ich einen einfachen Jumper-Draht als Netzschalter. Und das war's – unsere Arduino Wireless Wetterstation funktioniert nun. Was in diesem Video noch bleibt, ist ein Blick auf die Programmierung. Beschreibung: Die Außeneinheit ist der Sender der drahtlosen Kommunikation. Zuerst binden wir die RF24-Bibliothek, die DHT-Bibliothek sowie die LowPower-Bibliothek ein, die verwendet wird, um den Arduino in den Sleep-Modus zu versetzen. Nach der Definition der Instanzen, der Pins und einiger Variablen initialisieren wir im Setup die drahtlose Kommunikationsadresse. Im Loop lesen wir zuerst die Daten vom DHT22-Sensor – Temperatur und Luftfeuchtigkeit. Anfangs sind diese Werte ganze Zahlen und getrennt, daher fasse ich sie in einer einzelnen String-Variable zusammen, lege sie in ein Zeichen-Array und sende sie mit der radio.write()-Funktion an die Inneneinheit. Mit der for-Schleife senden wir die Daten 3-mal, um sicherzustellen, dass der Empfänger die Daten erhält, falls der Controller zum Sendezeitpunkt beschäftigt ist. Am Ende versetzen wir den Arduino für einen bestimmten Zeitraum in den Sleep-Modus, um den Stromverbrauch zu minimieren. Beschreibung: Auf der Empfängerseite (Inneneinheit) benötigen wir zwei zusätzliche Bibliotheken: eine für das DS3231 Real Time Clock Modul und eine für das OLED-Display, die U8G2-Bibliothek. Genauso wie zuvor definieren wir die Instanzen, Pins und Variablen. Außerdem definieren wir die Temperatur- und Feuchtigkeits-Icons als Bitmaps. Temperatur-Icon Bitmap: Dafür können wir GIMP, einen Open-Source-Bildeditor, verwenden, um etwas zu zeichnen und es als Bitmap (.xbm) zu exportieren. Dann können wir diese Datei mit einem Editor öffnen und die Bitmap in den Arduino-Code kopieren. Beachten Sie, dass wir die Bitmap als Konstante mit dem PROGMEM-Modifier definieren können, sodass sie im Flash-Speicher statt im SRAM des Arduino-Boards gespeichert wird. Im Setup initialisieren wir die drahtlose Kommunikation sowie das OLED-Display und das Real Time Clock Modul. Im Loop überprüfen wir ständig, ob eingehende Daten über die NRF24L01-Module verfügbar sind. Falls ja, lesen wir sie mit der radio.read()-Funktion und speichern die ersten beiden Zeichen in der Temperatur-String-Variable und die nächsten beiden in der Feuchtigkeits-String-Variable. Dann verwenden wir die millis()-Funktion, um die verschiedenen Daten in Intervallen anzuzeigen, die mit der interval-Variable definiert sind (ich habe sie auf 3 Sekunden gesetzt). Wir nutzen millis() anstelle von delay(), damit der Rest des Codes wiederholt ausgeführt werden kann – bei delay() würde das Programm warten und wir würden wahrscheinlich eingehende Daten von der Außeneinheit verpassen. Anschließend verwenden wir die firstPage()- und nextPage()-Funktionen der U8G2-Bibliothek, um die fünf verschiedenen Bildschirme anzuzeigen, die mit benutzerdefinierten Funktionen definiert sind. Die drawDate()-Funktion holt Datum und Uhrzeit vom Real Time Clock Modul und zeigt sie auf dem Display an. Die drawInTemperature()-Funktion liest die Innentemperatur und zeigt sie entsprechend an. Im Grunde wird dieselbe Methode für alle Bildschirme verwendet. Das war es für dieses Arduino-Projekt. Ich hoffe, es hat Ihnen gefallen und Sie haben etwas Neues gelernt. Stellen Sie gerne Fragen im Kommentarbereich unten.Überblick

Schaltplan der Arduino Wireless Wetterstation

Custom Design PCB












Arduino Wireless Wetterstation Code
Außeneinheit Code (Sender)
/* Arduino Wireless Communication Tutorial Outdoor unit - Transmitter by Dejan Nedelkovski, www.HowToMechatronics.com Libraries: NRF24L01 - TMRh20/RF24, https://github.com/tmrh20/RF24/ DHT22 - DHTlib, https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTlib LowPower - https://github.com/rocketscream/Low-Power */
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <dht.h>
#include <LowPower.h>
#define dataPin 8 // DHT22 data pin
dht DHT; // Creates a DHT object
RF24 radio(10, 9); // CE, CSN
const byte address[6] = "00001";
char thChar[32] = "";
String thString = "";
void setup() {
radio.begin();
radio.openWritingPipe(address);
radio.setPALevel(RF24_PA_MIN);
radio.stopListening();
}
void loop() {
int readData = DHT.read22(dataPin); // Reads the data from the sensor
int t = DHT.temperature; // Gets the values of the temperature
int h = DHT.humidity; // Gets the values of the humidity
thString = String(t) + String(h);
thString.toCharArray(thChar, 12); // Sent the data wirelessly to the indoor unit
for (int i = 0; i <= 3; i++) { // Send the data 3 times
radio.write(&thChar, sizeof(thChar));
delay(50);
}
// Sleep for 2 minutes, 15*8 = 120s
for (int sleepCounter = 15; sleepCounter > 0; sleepCounter--) {
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
}
}Inneneinheit Code (Empfänger)
/* Arduino Wireless Communication Tutorial Indoor unit - Receiver by Dejan Nedelkovski, www.HowToMechatronics.com Libraries: DS3231 - https://www.rinkydinkelectronics.com/library.php?id=73 U8G2 - https://github.com/olikraus/u8g2 */
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <dht.h>
#include <DS3231.h>
#include <U8g2lib.h>
#include <Wire.h>
#define dataPin 8 // DHT22 sensor
dht DHT; // Creats a DHT object
DS3231 rtc(SDA, SCL);
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
RF24 radio(10, 9); // CE, CSN
const byte address[6] = "00001";
char text[6] = "";
int readDHT22, t, h;
String inTemp, inHum, outTemp, outHum;
String rtcTime, rtcDate;
int draw_state = 0;
unsigned long previousMillis = 0;
long interval = 3000;
#define Temperature_20Icon_width 27
#define Temperature_20Icon_height 47
static const unsigned char Temperature_20Icon_bits[] U8X8_PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x80, 0x7f, 0x00, 0x00, 0xc0, 0xe1, 0x00, 0x00, 0xe0, 0xc0, 0x01, 0x00, 0x60, 0x80, 0xf9, 0x03, 0x60, 0x80, 0x01, 0x00, 0x60, 0x80, 0x01, 0x00, 0x60, 0x80, 0x79, 0x00, 0x60, 0x80, 0x01, 0x00, 0x60, 0x80, 0x01, 0x00, 0x60, 0x80, 0xf9, 0x03, 0x60, 0x80, 0x01, 0x00, 0x60, 0x8c, 0x79, 0x00, 0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0xf9, 0x03, 0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0x79, 0x00, 0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0xf9, 0x03, 0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0x01, 0x00, 0x70, 0x9e, 0x03, 0x00, 0x38, 0x1e, 0x07, 0x00, 0x18, 0x3e, 0x0e, 0x00, 0x1c, 0x3f, 0x0c, 0x00, 0x0c, 0x7f, 0x18, 0x00, 0x8c, 0xff, 0x18, 0x00, 0x8e, 0xff, 0x38, 0x00, 0xc6, 0xff, 0x31, 0x00, 0xc6, 0xff, 0x31, 0x00, 0xc6, 0xff, 0x31, 0x00, 0x8e, 0xff, 0x38, 0x00, 0x8c, 0xff, 0x18, 0x00, 0x0c, 0x7f, 0x1c, 0x00, 0x3c, 0x1c, 0x0e, 0x00, 0x78, 0x00, 0x06, 0x00, 0xe0, 0x80, 0x07, 0x00, 0xe0, 0xff, 0x03, 0x00, 0x80, 0xff, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
#define Humidity_20Icon_width 27
#define Humidity_20Icon_height 47
static const unsigned char Humidity_20Icon_bits[] U8X8_PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, 0xdc, 0x01, 0x00, 0x00, 0x8e, 0x01, 0x00, 0x00, 0x86, 0x03, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00, 0x03, 0x07, 0x00, 0x80, 0x03, 0x06, 0x00, 0x80, 0x01, 0x0c, 0x00, 0xc0, 0x01, 0x1c, 0x00, 0xc0, 0x00, 0x18, 0x00, 0xe0, 0x00, 0x38, 0x00, 0x60, 0x00, 0x30, 0x00, 0x70, 0x00, 0x70, 0x00, 0x30, 0x00, 0xe0, 0x00, 0x38, 0x00, 0xc0, 0x00, 0x18, 0x00, 0xc0, 0x01, 0x1c, 0x00, 0x80, 0x01, 0x0c, 0x00, 0x80, 0x03, 0x0e, 0x00, 0x80, 0x03, 0x06, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0x03, 0x07, 0x00, 0x00, 0x07, 0x03, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00, 0x06, 0x63, 0x00, 0x00, 0x06, 0x63, 0x00, 0x00, 0x06, 0x63, 0x00, 0x00, 0x06, 0xe3, 0x00, 0x00, 0x06, 0xc7, 0x00, 0x00, 0x06, 0xc6, 0x01, 0x00, 0x07, 0x86, 0x03, 0x00, 0x03, 0x0e, 0x1f, 0x00, 0x03, 0x0e, 0x1e, 0x80, 0x01, 0x1c, 0x00, 0xc0, 0x01, 0x38, 0x00, 0xe0, 0x00, 0x78, 0x00, 0x70, 0x00, 0xf0, 0x00, 0x38, 0x00, 0xe0, 0x07, 0x1f, 0x00, 0x80, 0xff, 0x0f, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 };
void setup() {
radio.begin();
radio.openReadingPipe(0, address);
radio.setPALevel(RF24_PA_MIN);
radio.startListening();
u8g2.begin();
rtc.begin();
}
void loop() {
if (radio.available()) {
radio.read(&text, sizeof(text)); // Read incoming data
outTemp = String(text[0]) + String(text[1]) + char(176) + "C"; // Outdoor Temperature
outHum = String(text[2]) + String(text[3]) + "%"; // Outdoor Humidity
}
unsigned long currentMillis = millis();
if (currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
u8g2.firstPage();
do {
switch (draw_state ) {
case 0: drawDate(); break;
case 1: drawInTemperature(); break;
case 2: drawInHumidity(); break;
case 3: drawOutTemperature(); break;
case 4: drawOutHumidity(); break;
}
} while ( u8g2.nextPage() );
draw_state++;
if (draw_state > 4) { draw_state = 0; }
}
}
void drawDate() {
String dowa = rtc.getDOWStr();
dowa.remove(3);
rtcDate = dowa + " " + rtc.getDateStr();
u8g2.setFont(u8g2_font_timB14_tr);
u8g2.setCursor(0, 15);
rtcTime = rtc.getTimeStr(); // DS3231 RTC time
rtcTime.remove(5);
u8g2.print(rtcDate);
u8g2.setFont(u8g2_font_fub30_tf);
u8g2.setCursor(8, 58);
u8g2.print(rtcTime);
}
void drawInTemperature() {
readDHT22 = DHT.read22(dataPin); // Reads the data from the sensor
t = DHT.temperature; // Gets the values of the temperature
inTemp = String(t) + char(176) + "C";
u8g2.setFont(u8g2_font_helvR14_tr);
u8g2.setCursor(24, 15);
u8g2.print("INDOOR");
u8g2.setFont(u8g2_font_fub30_tf);
u8g2.setCursor(36, 58);
u8g2.print(inTemp);
u8g2.drawXBMP( 0, 17, Temperature_20Icon_width, Temperature_20Icon_height, Temperature_20Icon_bits);
}
void drawInHumidity() {
h = DHT.humidity; // Gets the values of the humidity
inHum = String(h) + "%";
u8g2.setFont(u8g2_font_helvR14_tr);
u8g2.setCursor(24, 15);
u8g2.print("INDOOR");
u8g2.setFont(u8g2_font_fub30_tf);
u8g2.setCursor(36, 58);
u8g2.print(inHum);
u8g2.drawXBMP( 0, 17, Humidity_20Icon_width, Humidity_20Icon_height, Humidity_20Icon_bits);
}
void drawOutTemperature() {
u8g2.setFont(u8g2_font_helvR14_tr);
u8g2.setCursor(12, 15);
u8g2.print("OUTDOOR");
u8g2.setFont(u8g2_font_fub30_tf);
u8g2.setCursor(36, 58);
u8g2.print(outTemp);
u8g2.drawXBMP( 0, 17, Temperature_20Icon_width, Temperature_20Icon_height, Temperature_20Icon_bits);
}
void drawOutHumidity() {
u8g2.setFont(u8g2_font_helvR14_tr);
u8g2.setCursor(12, 15);
u8g2.print("OUTDOOR");
u8g2.setFont(u8g2_font_fub30_tf);
u8g2.setCursor(36, 58);
u8g2.print(outHum);
u8g2.drawXBMP( 0, 17, Humidity_20Icon_width, Humidity_20Icon_height, Humidity_20Icon_bits);
}#define Temperature_20Icon_width 27
#define Temperature_20Icon_height 47
static const unsigned char Temperature_20Icon_bits[] U8X8_PROGMEM = { ... };

static const unsigned char Temperature_20Icon_bits[] U8X8_PROGMEM // Im Flash-Speicher
static unsigned char Temperature_20Icon_bits[] // Im SRAM
Herstellungsprozess
- DIY Solar-betriebene Wetterstation mit Raspberry Pi
- Outdoor-Wetterstation mit Raspberry Pi 2 & ADS-WS1 bauen
- Raspberry Pi Wetterstation bauen, die tägliche Wetterdaten per E-Mail sendet
- Fortgeschrittene Wetterstation v2.0: Echtzeit Temperatur, Druck, Feuchte & Höhe Monitoring
- Arduino Audio-Frequenz-Detektor – Lauteste Schallpeaks mit hochsensiblem Modul messen
- Intelligenter kabelloser Lichtschalter-Controller: Arduino-basierter Fernschalter-Manipulator
- Arduino Tic Tac Toe mit MAX7219 LED-Matrix und Karton-Gehäuse
- Zuverlässigen Arduino-Countdown-Timer mit SparkFun 7-Segment-Display bauen
- Tragbare Arduino-Wetterstation für 10$ bauen (Nano, DHT22, BMP180 & LCD)
- eDOT: Präzise Arduino-Uhr & Wetterstation mit IR-Fernbedienung