Der ESP Chip ist ein kleiner Funkchip, mit dem sich per WiFi / WLAN kommunizieren lässt: Auf einem NodeMCU oder Wemos Board lässt er sich auch mit der Arduino Software programmieren und verhält sich, bis auf eine veränderte Pin-Belegung, fast wie ein etwas schnellerer Arduino mit WLAN-Chip.
Da die Boards mit etwa 6 Euro (zum Beispiel bei eBay oder bei Amazon) recht günstig sind, lassen sich sehr leicht eigenständige Sensoren bauen, die die Daten dann per Funk weitergeben und direkt mit der freien Smart-Home Software FHEM kommunizieren können.
In unserem Beispiel verbindet sich der NodeMCU zunächst mit dem eigenen WLAN: Dafür muss man Passwort und den Namen des Netzwerkes (SSID) angeben. Anschließend sendet er die Daten per GET Befehl an FHEM und schaltet das Gerät “MEINDEVICE” an, in dem wir den Befehl “set MEINDEVICE on” an FHEM senden:
#include "ESP8266WiFi.h"
const char* server = "192.168.1.1"; // FHEM Server
const int serverport = 8083;
const char* ssid = "MEINE_WLAN_SSID";
const char* passwort = "MEIN_WLAN_PASSWORT";
WiFiClient client;
unsigned long bewegung = 0;
void setup() {
Serial.begin (9600); // Monitor starten
Serial.println(" ");
Serial.print("Verbindungsaufbau mit: ");
Serial.println(ssid);
WiFi.begin(ssid, passwort);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(100);
}
Serial.println(" ");
Serial.println("WLAN verbunden!");
Serial.println("IP Addresse: ");
Serial.println(WiFi.localIP());
}
void loop() {
WiFiClient client;
if (!client.connect(server, serverport)) {
Serial.println("Verbindungsfehler");
return;
}
// Daten per GET senden
String url = "/fhem?";
url += "cmd.MEINDEVICE=";
url += "set%20MEINDEVICE%20on";
Serial.println(url);
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + server + "\r\n" +
"Connection: close\r\n\r\n");
delay(50);
// Server-Antwort ausgeben
while(client.available()){
String antwort = client.readStringUntil('\r');
Serial.print(antwort);
}
delay(1000);
}
Bewegungsmelder mit NodeMCU und FHEM
Im nächsten Beispiel bauen wir das Skript etwas aus: Der NodeMCU (auf dem sich bei uns der ESP Chip befindet) überwacht einen Raum mit einem einfachen Infrarot-Bewegungssensor, zum Beispiel einem HC-SR501 (Tipp: in diesen Artikeln zeigen wir, wie man den Sensor mit einem Arduino und einem Raspberry Pi ausliest und anschließt!).
Registriert er eine Bewegung an Pin D4 (GPIO2 auf dem NodeMCU!), schaltet er an Pin D5 (GPIO14) eine LED ein und sendet die Daten an FHEM: Dafür haben wir vorher in FHEM einen dummy “Bewegung” angelegt, der jetzt auf “on” oder “off” gesetzt wird:
define Bewegung dummy
Erkennt das ESP Board eine Bewegung, wird die interne Variable “bewegung” auf 100 gesetzt und zählt dann langsam herunter: Misst der Sensor in dieser Zeit keine neue Bewegung, wird die LED ausgeschaltet und der ESP sendet ein “set Bewegung off” an FHEM.
#include "ESP8266WiFi.h"
const char* server = "192.168.1.1"; // FHEM Server
const int serverport = 8085;
const char* ssid = "MEINE_WLAN_SSID";
const char* passwort = "MEIN_WLAN_PASSWORT";
WiFiClient client;
unsigned long bewegung = 0;
unsigned long sendenon = 0;
unsigned long sendenoff = 0;
void setup() {
Serial.begin (9600); // Monitor starten
pinMode(14,OUTPUT);
pinMode(2,INPUT);
Serial.println();
Serial.println();
Serial.print("Verbindungsaufbau mit: ");
Serial.println(ssid);
WiFi.begin(ssid, passwort);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WLAN verbunden!");
Serial.println("IP Addresse: ");
Serial.println(WiFi.localIP());
}
void loop() {
// LED ein- oder ausschalten
if (bewegung > 1) { digitalWrite(14, LOW);
} else { digitalWrite(14, HIGH); }
if (digitalRead(2) == HIGH) {
Serial.println("Bewegung erkannt!");
digitalWrite(14, LOW);
bewegung = 30;
if(sendenon == 0) {
sendenon = 1;
sendenoff = 0;
WiFiClient client;
if (!client.connect(server, serverport)) {
Serial.println("Verbindungsfehler");
return;
}
// Daten per GET senden
String url = "/fhem?";
url += "cmd.Bewegung=";
url += "set%20Bewegung%20on";
Serial.println(url);
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + server + "\r\n" +
"Connection: close\r\n\r\n");
delay(50);
// Server-Antwort ausgeben
while(client.available()){
String antwort = client.readStringUntil('\r');
Serial.print(antwort);
}
delay(1000);
}
} else {
if(bewegung < 1) {
bewegung = 0; sendenon = 0;
if(sendenoff == 0) {
sendenoff = 1;
WiFiClient client;
if (!client.connect(server, serverport)) {
Serial.println("Verbindungsfehler");
return;
}
// Daten per GET senden
String url = "/fhem?";
url += "cmd.Bewegung=";
url += "set%20Bewegung%20off";
Serial.println(url);
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + server + "\r\n" +
"Connection: close\r\n\r\n");
delay(50);
// Server-Antwort ausgeben
while(client.available()){
String antwort = client.readStringUntil('\r');
Serial.print(antwort);
}
delay(1000);
}
} else { bewegung = bewegung - 1; }
}
Serial.print("Bewegung: ");
Serial.print(bewegung);
Serial.println(" ");
delay(1000);
}