
Gewitterwarner mit Webserver
von Alexander Wankerl

Der
Gewitterwarner wurde zunächst in ein Kunststoffgehäuse eingebaut. Da
ich die ganze Sache aber weiter aufbohren wollte, wurde ein
Potentiometer zur Lautstärkeregelung angebracht, die Warnstufen
wollte ich über die beiden Digitalausgänge abgreifen und auf einem
NanoESP (bei Franzis als "Pretzel Board" erhältlich) via Webserver
darstellen. Es zeigte sich aber, dass WLAN und Gewitterwarner nicht gut
miteinander können, deswegen wurde schließlich ein Nano mit einem
Wiz820io von Wiznet (ein Hersteller, mit welchem ich u.a beruflich zu
tun habe) verwendet. Der Piezoschallwandler wurde durch einen kleinen
Lautsprecher ersetzt, die Stromversorgung erfolgt durch ein gängiges
Modul für Breadboards.
Die
verschiedenen Modi (Normal, Erweiterte Reichweite, Test und Memory)
sollte ursprünglich durch Kippschalter eingestellt werden. Ich verwarf
die Idee (obwohl ich sie schon eingebaut hatte) und benutze jetzt dafür
einen Drehschalter mit welchem folgende Modi einstellbar sind:
1. Normal
2. Erweiterte Reichweite
3. Test
4. Memory
5. Erweiterte Reichweite & Memory
6. Test & Memory
Gleichzeitig
werden diese Modi vom Nano über digitale Eingänge ausgelesen und auch
auf dem Webserver angezeigt. Die beiden ursprünglichen Kippschalter
dienen jetzt dazu, zum einen die Blitz-LED ein und aus zu schalten (der
Gewitterwarner wird in Zukunft im Wohnzimmer stehen, insbesondere bei
Dunkelheit kann das Blitzen der LED teilweise stark stören), zum
anderen den Nano ein oder aus zu schalten (falls ein Restart mal nötig
sein sollte, teilweise hängt sich nämlich der Webserver auf).
Da
ich den kleinen Microcontroller bestmöglich ausnutzen wollte, gab es
als Zugabe noch das BME280 Modul (zweites Bild
lila PCB links), welches
zusätzlich zu den Alarmstufen des Gewitterwarners Temperatur,
Luftfeuchte und Luftdruck misst. Diese Werte werden ebenfalls auf dem
Webserver angezeigt. Das Resultat ist auf dem untersten Bild zu sehen.
In Zukunft werde ich dieses Gerät in die Hausautomation einbinden und
die Warnstufen dazu verwenden, je nach Level verschiedene Aktionen
durchführen zu lassen (z.B. Email-Warnung, SMS-Warnung, etc.).
Das Auslesen der Daten auf dem
Webserver erfolgt im nächsten Schritt durch die
Automatisierungssoftware IP Symcon mittels TextParser und
WWWReader, welche auch zukünftig innerhalb der Hausautomation
zum Einsatz kommt. Als ersten Test für ereignisbasierte Aktionen
wird nunmehr eine Warnung via Email gesendet, sobald sich die
Warnstufe von grün auf gelb erhöht.
Der Sketch verwendet die Ethernet_Shield_W5200 Bibliothek welche
auch mit dem Ethernetshield, welches den Wiznet W5200
beinhaltet, zusammenspielt.
Download: Gewitterwarner_Webserver.zip
/*
Web Server for Thunderstorm Warner + BME280
This webserver is used to display the different alert levels of Franzis Thunderstorm Warner as well as the following different modes which can be switched by using a 2-pole rotary switch:
- normal operation
- extended range
- test
- memory
- extended range & memory
- test and memory
The alert levels can be read by connecting the outputs at M1 and M2 to two digital inputs (within this sketch D2 and D3), D4-D6 are used for the mode detection (Pulling HIGH to LOW when mode is ON).
Additionally a BME280 temperature, humidity and air pressure sensor was added to the system and the values are displayed on the webpage.
As Ethernet module a Wiznet Wiz820io with W5200 IC was used attached to pins 10 (SS), 11 (MOSI), 12 (MISO), 13 (SCL).
created 21 Jul 2018
by Alexander Wankerl
*/
#include <SPI.h>
#include <EthernetV2_0.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BME280 bme;
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
0x2A, 0xDE, 0x55, 0xA3, 0xF8, 0x0A };
IPAddress ip(192,168,1,10);
// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);
#define W5200_CS 10
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
// start the Ethernet connection and the server:
Ethernet.begin(mac, ip);
server.begin();
Serial.print("server is at ");
Serial.println(Ethernet.localIP());
pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
pinMode(4, INPUT_PULLUP);
pinMode(5, INPUT_PULLUP);
pinMode(6, INPUT_PULLUP);
bool status;
status = bme.begin(0x76);
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
}
void loop() {
// listen for incoming clients
EthernetClient client = server.available();
int J1 = digitalRead(4);
int J2 = digitalRead(5);
int J3 = digitalRead(6);
int M2 = digitalRead(2);
int M1 = digitalRead(3);
if (client) {
Serial.println("new client");
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connnection: close");
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
// add a meta refresh tag, so the browser pulls again every 10 seconds:
client.println("<meta http-equiv=\"refresh\" content=\"10\">");
// output the value of each analog input pin
client.println("<center>");
client.println("THUNDERSTORM WARNER");
client.println("<br />");
client.println("<br />");
if (M2 == LOW && M1 == LOW) {
client.print ("Alert Level = 0, ");
client.print ("<font color=lightblue>NO DANGER</font>");
}
if (M2 == HIGH && M1 == LOW) {
client.print ("Alert Level = 1, ");
client.print ("<font color=lightgreen>GREEN ALERT</font>");
}
if (M2 == LOW && M1 == HIGH) {
client.print ("Alert Level = 2, ");
client.print ("<font color=orange>ORANGE ALERT</font>");
}
if (M2 == HIGH && M1 == HIGH) {
client.print ("Alert Level = 3, ");
client.print ("<font color=red>RED ALERT</font>");
}
client.println("<br />");
if (J1 == HIGH && J2 == HIGH && J3 == HIGH){
client.print ("Mode = Normal");
}
if (J1 == LOW && J2 == HIGH && J3 == HIGH) {
client.print ("Mode = Extended Range");
}
if (J1 == HIGH && J2 == LOW && J3 == HIGH) {
client.print ("Mode = Test");
}
if (J1 == HIGH && J2 == HIGH && J3 == LOW) {
client.print ("Mode = Memory");
}
if (J1 == LOW && J2 == HIGH && J3 == LOW) {
client.print ("Mode = Extended Range And Memory");
}
if (J1 == HIGH && J2 == LOW && J3 == LOW) {
client.print ("Mode = Test And Memory");
}
client.println("<br />");
client.println("<br />");
client.print("Temperature = ");
client.print(bme.readTemperature());
client.println(" °C");
client.println("<br />");
client.print("Pressure = ");
client.print(bme.readPressure() / 100.0F);
client.println(" hPa");
client.println("<br />");
client.print("Approx. Altitude = ");
client.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
client.println(" m");
client.println("<br />");
client.print("Humidity = ");
client.print(bme.readHumidity());
client.println(" %");
client.println("</center>");
client.println("</html>");
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
}
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(2000);
// close the connection:
client.stop();
Serial.println("client disonnected");
}
}