WLAN basierter Schalter

WLAN-basierte Schalter haben den Charme, dass sie von überall auf der Welt auslösbar sind. So können beispielsweise vom Urlaubsort aus in der heimatlichen Wohnung Rollläden bedient, Licht und Heizungen an- und ausgeschaltet werden.

Voraussetzung dafür ist, dass der Schalter dauerhaft im WLAN-Netz eingebunden und der Access-Point („Router“) im Internet erreichbar ist. Informationen dazu, ob die Voraussetzungen dafür beim eigenen Gerät gegeben sind und wie man sich über das Internet einloggen kann, liefert der Hardware-Hersteller.

Käufliche Lösungen solcher Schalter sehen etwa so aus wie rechts abgebildet: Der Strom wird aus einer normalen Steckdose abgezweigt. Damit diese Anschlussmöglichkeit für externe Haushaltsgeräte erhalten bleibt, sind die elektrischen Kontakte nach vorn in einer zweiten Steckdose zusammengeführt. Zudem ist das Gehäuse so groß, dass die benötigte Schalt-Elektronik darin Platz finden kann.

Da es Gehäuse wie oben abgebildet nicht leer zu kaufen gibt, müssen die Bauteile anderweitig untergebracht werden, beispielsweise in einer Unter- oder Aufputzdose, in der auch die Anschlüsse mit dem 230V Stromnetz realisiert werden können. Was es dabei zu beachten gibt, findet sich hier.

Der erste Baustein ist ein Netzteil mit der Bezeichnung MW (Mean Well) IRM-01-3.3, das den auf 230V hochgespannten Wechselstrom umwandelt in Gleichstrom von 3,3V.

Das Netzteil verfügt über sehr kleine Abmessungen von 33,7 x 22,2 x 15 mm und hat eine extrem niedrige Leistungsaufnahme von weniger als 0,075W.

Es genügt weltweiten Anforderungen nach geringem Stromverbrauch bei elektronischen Geräten, ist zertifiziert nach EN60950-1 und zudem designt nach EN60335-1 bzw. IEC60601-1. Es hält dem 5G Vibrationstest stand und verfügt über ein nach UL94V-0 schwer entflammbares Kunststoffgehäuse. Damit eignet es sich für Anwendungen wie Automatisierungsanlagen, eine IoT-bezogene digitale Ausstattung, mechanische Geräte, industrielle elektrische Geräte und elektrische Handgeräte.

Der zweite Baustein ist ein Relais, das – ausgelöst von einem Mikrocontroller – größere Ströme schalten kann. Das abgebildete Gerät ist ein einkanaliges 5V Schaltmodul mit optischer Kopplung. Dieser sogenannte „Optokoppler“ dient zur Übertragung der Signale zwischen Hoch- und Niedervoltbereich, die somit galvanisch getrennt bleiben können. Das ist unabdingbar, um beispielsweise mit einem Arduino Mikrocontrollerboard oder einer NodeMCU im Stromnetz arbeiten zu können.

Der dritte und letzte Baustein ist ein WLAN-fähiges Controllerboard, das sich mit einer entsprechenden Programmierung selbsttätig in ein bestehendes WLAN-Netz einloggen kann. Dort ist es anhand der IP-Adresse identifizierbar und kann über einen beliebigen Webbrowser eines im selben Netz eingebundenen digitalen Endgeräts angesprochen werden.

Die nebenstehende Abbildung zeigt, wie die Bausteine zueinander angeordnet werden müssen, damit Netzteil, Relais und Controller nicht mehr Platz benötigen als ein üblicher Lichtschalter.

Die grauen Punkte in der Zeichnung stehen für elektrische Verbindungen, die durch Löten, Schraubverbinder oder Klemmen zu realisieren sind. Es ist darauf zu achten, dass die blanken, 230V Wechselspannung führenden Teile gut isoliert sind.

Kurze Anschlusswege auf der Niedervoltseite zwischen Netzteil, Relais und Controller stellen sicher, dass das 5V-Relais trotz der niedrigeren Spannung von 3,3V sicher schaltet. Sollte es wider Erwarten Probleme geben, kann ein Transistor (1) helfen.

Um den Schaltvorgang auslösen zu können, muss die NodeMCU entsprechend programmiert werden. Der nachfolgende Programmcode erfüllt diesen Zweck.

 #include <ESP8266WiFi.h>
 const char* ssid = "Name des Access-Points";
 const char* password = "Passwort";
 int RelaisPin = D3;
 unsigned long Steuerbefehle;
 unsigned long Verbindungen;
 // Server an Port 80 etablieren
 WiFiServer server(80);
 void setup() {
   Steuerbefehle = 0;
   Verbindungen = 0;
   // Seriellen Monitor starten
   Serial.begin(9600);
   delay(1);
   // Relaispin (D3) ansteuern und auf LOW setzen
   pinMode(RelaisPin, OUTPUT);
   digitalWrite(RelaisPin, LOW);
   // WLAN-Verbindung initiieren
   Serial.println();
   Serial.println();
   Serial.print("Verbinde mit ");
   Serial.println(ssid);
   WiFi.begin(ssid, password);
 while (WiFi.status() != WL_CONNECTED) {
   delay(500);
   Serial.print(".");
 }
 Serial.println("");
 Serial.println("Mit dem Router verbunden");
 Serial.println();
 // Den Server starten
 server.begin();
 Serial.println("Server gestartet");
 Serial.println();
 Serial.println();
 // IP-Adresse für den Aufruf des ESP-Servers
 Serial.print("Kopiere die nachstehende IP in die Adresszeile deines Browsers,");
 Serial.println();
 Serial.print("um die Verbindung herzustellen: ");
 Serial.print("http://");
 Serial.println(WiFi.localIP());
 Serial.println("/");
 }
 void loop()
 {
   // Verbindung zum WLAN-Netz prüfen
   WiFiClient client = server.available();
   if (!client)
   {
     return;
   }
   // Warten, bis der Client Daten sendet
   Serial.println("new client");
   unsigned long TimeOut = millis() + 250;
   while (!client.available() && (millis() < TimeOut) )
   {
     delay(1);
   }
   if (millis() > TimeOut)
   {
     Serial.println("client connection time-out!");
     return;
   }
   // Die erste Zeile der Anforderungen lesen
   String Request = client.readStringUntil('\r');
   //Serial.println(Request);
   client.flush();
   // Client stoppen, wenn keine Anforderung vorliegen
   if (Request == "")
   {
     Serial.println("empty request! - stopping client");
     client.stop();
     return;
   }
   // Pfad aufnehmen
   String Path = "", Param = "", Cmd = "";
   String GetStart = "GET ";
   int Start, EndSpace, EndQuest;
   Start = Request.indexOf(GetStart);
   if (Start >= 0)
   {
     Start += +GetStart.length();
     EndSpace = Request.indexOf(" ", Start);
     EndQuest = Request.indexOf("?", Start);
     // Sind da irgendwelche Parameter?
     if (EndSpace > 0)
     {
       if (EndQuest > 0)
       {
         // Es gibt Parameter
         Path = Request.substring(Start, EndQuest);
         Param = Request.substring(EndQuest, EndSpace);
       }
       else
       {
         // Keine Parameter
         Path = Request.substring(Start, EndSpace);
       }
     }
   }
   // Serieller Monitor
   if (Param.length() > 0)
   {
     int Equ = Param.indexOf("=");
     if (Equ >= 0)
     {
       Cmd = Param.substring(Equ + 1, Param.length());
       Serial.println(Cmd);
     }
   }
   // Browser
   String Response, Header;
   // Fehlermeldung
   if (Path != "/")
   {
     Response = "<html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>Die angeforderte URL wurde auf diesem Server nicht gefunden.</p></body></html>";
     Header = "HTTP/1.1 404 Not found\r\n";
     Header += "Content-Length: ";
     Header += Response.length();
     Header += "\r\n";
     Header += "Content-Type: text/html\r\n";
     Header += "Connection: close\r\n";
     Header += "\r\n";
   }
   // Formatierung der Serverinhalte
   else
   {
     Steuerbefehle++;
     Verbindungen++;
     Response = "<html><head><title>Demo f&uumlr ESP8266 Steuerung</title></head><body>";
     Response += "<font color=\"#0000FF\"><body bgcolor=\"#CCEEFF\">";
     Response += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=yes\">";
     Response += "<h1>Relaissteuerung</h1>";
     Response += "Durch Antippen von STROM_AN und STROM_AUS kann das Relais an GPIO4 (D3) auf HIGH bzw. LOW gesetzt werden. ";
     Response += "<FONT SIZE=+1>";
     Response += "<p>Funktionen: <a href=\"?pin=AN\"><button>STROM_AN</button></a> <a href=\"?pin=AUS\"><button>STROM_AUS</button></a></p>";
     // Auf Eingaben reagieren
     if (Cmd.length() > 0)
     {
       // Empfangene Kommandos anzeigen
       Response += "Status: " + Cmd + "<BR>";
       // GPIO-Pin schalten, Ereignisse zählen und anzeigen
       if (Cmd.indexOf("AUS") >= 0)
       {
         digitalWrite(RelaisPin, HIGH);
       }
       else if (Cmd.indexOf("AN") >= 0)
       {
         digitalWrite(RelaisPin, LOW);
       }
     }
     Response += "<FONT SIZE=-2>";
     Response += "<BR>Aufrufzähler=";
     Response += Steuerbefehle;
     Response += " - Verbindungszähler=";
     Response += Verbindungen;
     Response += "<BR>";
     Response += "</body></html>";
     Header = "HTTP/1.1 200 OK\r\n";
     Header += "Content-Length: ";
     Header += Response.length();
     Header += "\r\n";
     Header += "Content-Type: text/html\r\n";
     Header += "Connection: close\r\n";
     Header += "\r\n";
   }
   // Reaktionen zum Client senden
   client.print(Header);
   client.print(Response);
   // Client stoppen
   client.stop();
   Serial.println("Client disconnected");
 } 

Der Programmcode kann über Copy & Paste in die Arduino-IDE übernommen werden. Danach muss der Name des eigenen Accesspoints (ssid) und das dazugehörige Passwort gleich zu Beginn der Codierung mit Anführungszeichen eingegeben werden. Ist das geschehen, wird er auf die NodeMCU übertragen. Näheres dazu findet sich hier.

Die Programmierung unterstützt HTTP 1.1 mit definierten Unterbrechungen. Das heißt, dass sich die NodeMCU selbsttätig ins WLAN-Netz einwählt und die WiFi-Verbindung zu jeder Zeit wiederaufnimmt, wenn sie verloren geht.

Die in der Programmierung enthaltene Benutzeroberfläche kann mit Hilfe eines Webbrowsers über die IP-Adresse der NodeMCU abgerufen werden (192.168.178.?? in die Adresszeile des Browsers eintippen).

Die IP-Adresse selbst kann über den seriellen Monitor der Arduino-IDE oder die Bedienoberfläche des Access-Points ermittelt werden (bei einer Fritzbox beispielsweise durch die Eingabe von „fritz.box“ in die Adresszeile eines Webbrowsers).

Um sich zum Schalten das lästige Eintippen der IP-Adresse zu sparen, empfiehlt es sich, die Internetseite samt IP-Adresse als Link auf dem Handy zu speichern.



(1) Zusatzinformation

Sollte das Relais mit 3,3 V nicht schalten, hilft ein Transistor vom Typ TIP 120 STM. Er kann auf dem Relais platziert werden und verbindet bzw. trennt IN am Relais mit bzw. von GND.


Bezugsquellen:

Netzteil MW IRM-01-3.3, NodeMCU, Relais, Transistor