Die Hardware
Der Sensor BME280 misst Temperatur, Luftfeuchtigkeit und Luftdruck. Der Luftdruck kann verwendet werden, um die ungefähre Höhe des Standorts zu berechnen.
BME280 mit QWIIC-Anschluss
Der Arduino UNO R4 WiFi verfügt über ein WiFi-Modul und über einen QWIIC-Anschluss.
Dieser Anschluss wurde von Sparkfun entwickelt und fasst die Anschlüsse für 3,3 V, GND, SCL und SDA in einem Stecker zusammen. Selbstverständlich kann für diese Anleitung auch das Modul mit vier separaten Anschlüssen verwendet werden.
QWIIC-Anschluss am UNO R4 WiFi
Die Schaltung
Vorbereitung
Zunächst musst du über den Boardverwalter das Board installieren:
Wenn das Board angeschlossen ist, kann der USB-Anschluss ausgewählt werden. Der Name des Anschlusses unterschiedet sich je nach verwendetem Betriebssystem.
Wetterstation im Seriellen Monitor
I2C-Bussysteme
Der UNO R4 Wifi verfügt über zwei I2C-Bussysteme:
- den ersten I2C-Bus, er wird über vier Leitungsdrähte (3,3V, GND, SCL und SDA) angeschlossen (Wire)
- den zweiten I2C-Bus, er wird über QWIIC verbunden (Wire1)
Ein Testprogramm zeigt die verwendete Adresse an. Wenn du den ersten I2C-Bus abfragen willst, musst du jeweils Wire1 durch Wire ersetzen.
Das dazugehörige Programm. Wenn du den ersten I2C-Bus abfragen willst, musst du jeweils Wire1 durch Wire ersetzen.
#include "Wire.h"
void setup()
{
// Wire1 → QWICC
Wire1.begin();
Serial.begin(9600);
delay(500);
Serial.print("I2C Scanner QWIIC");
}
void loop()
{
byte Fehler, Adresse;
int Geraete = 0;
Serial.println("Starte Scanvorgang");
for (Adresse = 1; Adresse < 127; Adresse++ )
{
// Übertragung starten
Wire1.beginTransmission(Adresse);
// wenn die Übertragung beendet wird
Fehler = Wire1.endTransmission();
if (Fehler == 0)
{
Serial.print("I2C Gerät gefunden - Adresse: 0x");
if (Adresse < 16) Serial.print("0");
Serial.print(Adresse, HEX);
Serial.println("");
Geraete++;
}
}
if (Geraete == 0) Serial.println("Keine I2C Geräte gefunden\n");
else Serial.println("Scanvorgang abgeschlossen");
delay(10000);
}
Benötigte Bibliothek
Funktionen der Bibliothek BME280
Schlüsselwort | Aktion |
---|---|
begin() | BME280 starten |
readTemperature() | Temperatur messen |
readHumidity() | Luftfeuchtigkeit messen |
readPressure() | Luftdruck messen |
readAltitude(LuftdruckMeeresHoehe) | Höhe ermitteln |
Das Programm
Das Programm ermittelt die Messwerte für die Temperatur, Luftfeuchtigkeit, Luftdruck und die ungefähre Höhe. Diese wird aus der Gewichtskraft der Luftsäule, die auf einem Gegenstand steht, berechnet. Der Luftdruck auf Meereshöhe beträgt 1013,25 Hektopascal (hPa). Je höher der Ort der Messung, desto niedriger ist der Luftdruck.
So sieht es aus:
#include "Wire.h"
#include "SPI.h"
#include "Adafruit_Sensor.h"
#include "Adafruit_BME280.h"
// Luftdruck auf Meereshöhe
#define LuftdruckMeeresHoehe (1013.25)
// Name des Sensors
Adafruit_BME280 bme;
int Wartezeit = 5000;
void setup()
{
Serial.begin(9600);
while (!Serial);
delay(1000);
// I2C über SCL/SDA oder A5/A4
// if (!bme.begin()
// I2C über QWIIC-Verbindung
// Adresse und Wire1-Bus
if (!bme.begin(0x77, &Wire1))
{
Serial.println("Kein BME280-Modul gefunden");
while (true)
;
}
else Serial.println("BME280-Modul gefunden");
Serial.println();
}
void loop()
{
String Temperatur = String(bme.readTemperature());
Temperatur.replace(".", ",");
Serial.println("Temperatur: " + Temperatur + " °C");
String Luftfeuchtigkeit = String(bme.readHumidity());
Luftfeuchtigkeit.replace(".", ",");
Serial.println("Luftfeuchtigkeit: " + Luftfeuchtigkeit + " %");
String Luftdruck = String(bme.readPressure() / 100.0);
Luftdruck.replace(".", ",");
Serial.println("Luftdruck: " + Luftdruck + " hPa");
String Hoehe = String(bme.readAltitude(LuftdruckMeeresHoehe));
Hoehe.replace(".", ",");
Serial.println("Ungefähre Höhe: " + Hoehe + " m");
Serial.println();
delay(Wartezeit);
}
Wetterstation im Browser anzeigen
Jetzt sollen die gemessenen Daten, Datum und Zeit in einem Browser angezeigt werden.
So sieht es aus:
Das Programm
Zusätzlich benötigte Bibliothek
Im Seriellen Monitor wird die verwendete IP-Adresse angezeigt. Diese Adresse musst du in einem Browser deiner Wahl eingeben.
Bibliotheken und Variable
#include "Wire.h"
#include "SPI.h"
#include "Adafruit_Sensor.h"
#include "Adafruit_BME280.h"
#include "WiFiS3.h"
#include "NTP.h"
// Luftdruck auf Meereshöhe
#define LuftdruckMeeresHoehe (1013.25)
// Name des BME280
Adafruit_BME280 bme;
// SSID und Passwort des Routers
char Router[] = "Router_SSID";
char Passwort[] = "xxxxxxxx";
WiFiServer WiFiServer(80);
WiFiClient WiFiClient;
WiFiUDP wifiUdp;
NTP ntp(wifiUdp);
Der setup-Teil
void setup()
{
Serial.begin(9600);
while (!Serial);
delay(1000);
// Verbindung aufbauen
WiFi.begin(Router, Passwort);
while(WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.print("Verbindung aufbauen mit ");
Serial.println(Router);
// Webserver starten
WiFiServer.begin();
// IP des Servers/des verbundenen Computers anzeigen
Serial.print("Server: ");
Serial.println(WiFi.SSID());
// IP des Arduinos anzeigen
Serial.print("IP Adresse Arduino DHCP: ");
Serial.println(WiFi.localIP());
/*
Zeitzone
CEST: Central European Summertime
Beginn europäische Sommerzeit letzter Sonntag im März 2 Uhr GMT + 2 Stunden
*/
ntp.ruleDST("CEST", Last, Sun, Mar, 2, 120);
// CET: Central European Time
// Beginn Normalzeit letzter Sonntag im Oktober 3 Uhr GMT + 1 Stunde
ntp.ruleSTD("CET", Last, Sun, Oct, 3, 60);
// ntp starten
ntp.begin();
// Zeit aktualisieren
ntp.update();
// Zeit mit formatedTime() anzeigen:
// %d = Tag, %m = Monat, %Y = Jahr, %T = Zeit in Stunden, Minuten, Sekunden
Serial.println(ntp.formattedTime("%d.%m.%Y Uhrzeit: %T"));
// I2C über SCL/SDA oder A5/A4
// if (!bme.begin()
// I2C über QWIIC-Verbindung
// Adresse und Wire1-Bus
if (!bme.begin(0x77, &Wire1))
{
Serial.println("Kein BME280-Modul gefunden");
while (true);
}
else Serial.println("BME280-Modul gefunden");
Serial.println();
}
Der loop-Teil
void loop()
{
WiFiClient = WiFiServer.available();
if (WiFiClient) {
// Seite aufbauen wenn SeiteAufbauen true ist
boolean SeiteAufbauen = true;
while (WiFiClient.connected())
{
if (WiFiClient.available())
{
char Zeichen = WiFiClient.read();
if (Zeichen == '\n' && SeiteAufbauen)
{
// HTTP-Anforderung senden
WiFiClient.println("HTTP/1.1 200 OK");
WiFiClient.println("Content-Type: text/html");
// Leerzeile zwingend erforderlich
WiFiClient.println();
/*
HTML-Seite aufbauen
die folgenden Anweisungen müssen mit print oder println gesendet werden
println "verschönert" den Quelltext
" muss mit \" maskiert werden
*/
WiFiClient.println("<!doctype html>");
WiFiClient.println("<html>");
WiFiClient.println("<body>");
// alle 60 Sekunden aktualisieren mit meta-Tag
WiFiClient.println("<meta http-equiv=\"refresh\" content=\"60\">");
WiFiClient.println("<h1> Temperatur und Luftfeuchtigkeit messen</h1>");
WiFiClient.println("<hr />");
WiFiClient.print("<h2>Letzte Messung: ");
// Zeit aktualisieren
ntp.update();
// formatedTime() zeigt Wochentage in englischer Sprache
// -> müssen einzeln abgefragt werden
switch (ntp.weekDay())
{
case 0:
WiFiClient.print("Sonntag");
break;
case 1:
WiFiClient.print("Montag");
break;
case 2:
WiFiClient.print("Dienstag");
break;
case 3:
WiFiClient.print("Mittwoch");
break;
case 4:
WiFiClient.print("Donnerstag");
break;
case 5:
WiFiClient.print("Freitag");
break;
case 6:
WiFiClient.print("Samstag");
break;
}
WiFiClient.print(", ");
WiFiClient.print(ntp.formattedTime("%d.%m.%Y Uhrzeit: %T"));
WiFiClient.println("</h2>");
WiFiClient.println("<hr />");
// Temperatur
String Temperatur = String(bme.readTemperature());
Temperatur.replace(".", ",");
WiFiClient.print("<b>Temperatur:</b><blockquote>");
WiFiClient.println(Temperatur + " °C</blockquote>");
WiFiClient.println("<br>");
// Luftfeuchtigkeit
String Luftfeuchtigkeit = String(bme.readHumidity());
Luftfeuchtigkeit.replace(".", ",");
WiFiClient.print("<b>Luftfeuchtigkeit:</b><blockquote>");
WiFiClient.println(Luftfeuchtigkeit + " %</blockquote>");
WiFiClient.println("<br>");
// Luftdruck
String Luftdruck = String(bme.readPressure() / 100);
Luftdruck.replace(".", ",");
WiFiClient.print("<b>Luftdruck:</b><blockquote>");
WiFiClient.println(Luftdruck + " hPa</blockquote>");
WiFiClient.println("<br>");
// Höhe
String Hoehe = String(bme.readAltitude(LuftdruckMeeresHoehe));
Hoehe.replace(".", ",");
WiFiClient.println("<b>Ungefähre Höhe:</b><blockquote>");
WiFiClient.println(Hoehe + " m</blockquote>");
WiFiClient.println("<hr>");
WiFiClient.println("<form>");
// Button formatieren
WiFiClient.print("<input style=\"font-size:16pt; font-weight:bold;");
WiFiClient.print("background-color:#55A96B;");
WiFiClient.print("display:block; cursor:pointer;\"type=\"button\"");
WiFiClient.println(" onClick=\"location.href='WiFi.localIP()'\" value=\"aktualisieren\">");
WiFiClient.println("</form>");
WiFiClient.println("<hr />");
// IPs anzeigen
WiFiClient.print(F("<b>Eigene IP: "));
WiFiClient.print(WiFiClient.remoteIP());
WiFiClient.print(F("</b>"));
WiFiClient.print(F("<br><b>IP Klient: "));
WiFiClient.print(WiFi.localIP());
WiFiClient.print(F("</b>"));
WiFiClient.println("</b>");
WiFiClient.println("</body>");
WiFiClient.print("</html>");
// HTTP-Antwort endet mit neuer Zeile
WiFiClient.println();
// Seite vollständig geladen -> loop verlassen
break;
}
if (Zeichen == '\n') SeiteAufbauen = true;
else if (Zeichen != '\r') SeiteAufbauen = false;
}
}
delay(1);
// Seitenaufbau stoppen
WiFiClient.stop();
}
}
Letzte Aktualisierung: