anbei eine kleine Anleitung für einen visuellen Müllkalender: Je nach morgiger Müllabholung leuchten die jeweiligen kleinen Mülltonnen (Maßstab 1:12, ca. 5€, siehe hier).
Grob: Bei uns ist ein Grohe Gong verbaut (Grothe 465 BW/w). Darin fand ich zwei unbenutzte Adern und hinreichend Platz für ein ESP32 Dev Modul (z.B. diymore ESP32 NodeMCU ESP32 WROOM 32D - development board CH340 (ähnlich, link2). Außerdem bietet der Gong mit ca. 11cm Breite genug Platz für 4 der kleinen Modell-Mülltonnen in einer Reihe gestellt.
---------------------------------
Grundlegend für die Umsetzung ist natürlich, dass man zuerst die Müllkalender-Daten in Loxone bekommt. Das geht z.B. über das CalDAV-4-Lox Plugin auf dem Loxberry. Sofern man die Daten auch per http in seinen Miniserver bekommt, erübrigt sich ggf. der Loxberry.
Stromversorgung: Auf die zwei freien Adern habe ich 24VDC vom Loxone Netzteil im Zählerschrank gelegt. Mit dem Spannungswandler LM2596 (sieht so aus wie dieses hier) wandle ich diese Spannung direkt vor dem ESP32 Modul in 5,1VDC um. Die beiden Module habe ich dabei fest verbunden (etwas provisorisch).
Dann zum ESP32: Der Code am Ende des Posts nutzt die Pins 33, 25, 26, 27 um jeweils eine weiße LED zu schalten (z.B. wie diese hier). Diese benötigen jeweils einen Vorwiderstand, welchen ich mit 10 Ohm gewählt habe. Der Strom lag damit bei ca. 10mA.
Hardware: Nach dem Programmieren des ESP32 über die Arduino IDE Software benötigt man eine geeignete Verdrahtung. Die LEDs lässt man am besten in eine kleine Plastik-Platte (dicke ca. 5mm, kommt am Ende auf den Gong) ein, und lässt die LEDs oben schön rausgucken. Für die Kabel kann man am besten Kabelkanäle fräsen, oder aber nutzt 3 Platten übereinander, wobei die mittlere entsprechende Aussparungen hat. Um Platz zu sparen kann man die Vorwiderstände im Gong-Gehäuse verbauen, oder aber erledigt das gleich in der Plastik-Platte. Ich habe also nur Kabel mit Dupont-Steckern konfektioniert und so die LEDs in der Platte verdrahtet.
Der ESP32 braucht die Out+ Spannung vom LM2596 an Vin, und das Out- Potential an GND. Außerdem benötigt man eine Verbindung mit den entsprechenden Enden aller LEDs. Die anderen Enden der LED-Kabel kommen auf die GPIO Pins gemäß Programmierung, also auf 33, 25, 26, 27 (liegen bei mir nebeneinander, alle neben Vin in GND). Für die Verbindung aller GNDs (GND ESP32, Enden der LEDs, Out- vom LM2596) habe ich ein Header-Stück (female) zweckentfremdet: die unten rausschauenden Pins verlötet / verbunden und das ganze dann in einen großen Schrumpfschlauch.
Alles zusammen passte bei mir in den Gong rein. Die vorkonfektionierten Kabel mit ihren female Dupont Stecker-Enden habe ich durch ein Loch oben durchgefädelt (vorhandenes minimal aufgebohrt / verbreitert).
Zuletzt noch die Loxone Programmierung: Hier bietet sich eine Zeitschaltuhr zusammen mit Bewegungstriggern an. Den V1 am Analogwahlschalter auf 0, den V2 Wert auf den Val-Wert eines Statusbausteins (Dieser muss die Info von der richtigen Tonne in Form einer Zahl 1-.. enthalten). Getriggert werden dann Ausgänge eines Radiobutton-Bausteins, welche wiederum den http-Befehl an den ESP32 geben → virtueller Ausgang mit der Adresse des ESP32 (fixe IP!) ist anzulegen, und dann je LED einen virt. Ausgangsbefehl mit EIN: /L1 bzw. AUS: /D1.
// Playmobile USS Enterprise #include <WiFi.h> //Wifi support #include <WiFiClient.h> //Wifi support #include <HTTPClient.h> //Wifi server support //On-chip LED GPIO (depends on used ESP32 board) int LED_BUILTIN = 2; const byte LED_L1 = 33; // blaue Tonne const byte LED_L2 = 25; // braune Tonne const byte LED_L3 = 26; // gelbe Tonne const byte LED_L4 = 27; // schwarze Tonne //Wifi SSID and password const char* ssid = "YourSSID"; const char* password = "YourPWD"; unsigned long previousMillis = 0; unsigned long timeoutTime = 30000; //timeout for Wifi-Connection unsigned long previousMillisS = 0; unsigned long timeoutTimeS = 1000; // Define timeout for Server connection /BUGFIX: const long to unsigned long WiFiServer server(80); WiFiClient espClient; // Standard Arduino function which is called once when the device first starts up void setup() { // Setup for Serial Monitor (when connected to Arduino IDE: Tools -> Serial Monitor) Serial.begin(9600); while(!Serial) { delay(10); } // Initialize digital pin LED_BUILTIN, & the external LED pins (LED_Blue, LED_White) as an output. pinMode(LED_BUILTIN, OUTPUT); pinMode(LED_L1, OUTPUT); pinMode(LED_L2, OUTPUT); pinMode(LED_L3, OUTPUT); pinMode(LED_L4, OUTPUT); // Connect to WiFi Serial.println("\nConnecting to WiFi"); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while(WiFi.status() != WL_CONNECTED){ Serial.print("."); delay(500); } Serial.print("\nConnected to the WiFi network: "); Serial.print(String(ssid)); Serial.print(" | local ESP32 IP: "); Serial.print(WiFi.localIP()); Serial.print(" | RSSI: "); Serial.println(WiFi.RSSI()); //start server to allow control via http commands server.begin(); // Blink LED on Chip once on Startup BlinkLED();BlinkLED();BlinkLED(); } // Blink LED on Chip void BlinkLED() { digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level) delay(100); // LED on for 100msec digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW delay(100); // wait / off for 100msec } // Standard Arduino function that is called in an endless loop after setup void loop() { unsigned long currentMillis = millis(); //works for ca. 50 days before reset to 0 unsigned long currentMillisS = millis(); //works for ca. 50 days before reset to 0 // if WiFi is down, try reconnecting every timeoutTime seconds if ((WiFi.status() != WL_CONNECTED) && (currentMillis - previousMillis >= timeoutTime)) { Serial.print(millis()); Serial.println("Reconnecting to WiFi..."); WiFi.disconnect(); WiFi.reconnect(); Serial.print("\nConnected to the WiFi network: "); Serial.print(String(ssid)); Serial.print(" | local ESP32 IP: "); Serial.print(WiFi.localIP()); Serial.print(" | RSSI: "); Serial.println(WiFi.RSSI()); previousMillis = currentMillis; } //bugfix: removed rollover handling! unsigned long never <0! //get restart command from external http command to server WiFiClient client = server.available(); if (client) { currentMillisS = millis(); previousMillisS = currentMillisS; Serial.println("New Client"); String currentLine = ""; while (client.connected() && (currentMillisS - previousMillisS <= timeoutTimeS)) { currentMillisS = millis(); if (client.available()) { char c = client.read(); Serial.write(c); if (c == '\n') { if (currentLine.length() == 0) { // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK) // and a content-type so the client knows what's coming, then a blank line: client.println("HTTP/1.1 200 OK"); client.println("Content-type:text/html"); //client.println("Connection: close"); client.println(); //create the buttons client.print("L1: LED 1 (blaue Tonne) <a href=\"/L1\">AN</a> / <a href=\"/D1\">AUS</a><br>"); client.print("L2: LED 2 (braune Tonne) <a href=\"/L2\">AN</a> / <a href=\"/D2\">AUS</a><br>"); client.print("L3: LED 3 (gelbe Tonne) <a href=\"/L3\">AN</a> / <a href=\"/D3\">AUS</a><br>"); client.print("L4: LED 4 (schwarze Tonne) <a href=\"/L4\">AN</a> / <a href=\"/D4\">AUS</a><br>"); client.print("LEDs: <a href=\"/X\">Alle AUS</a><br>"); client.print("ESP32 Modul: <a href=\"/B\">Blink On-Chip LED</a><br>"); client.print("ESP32 Modul: <a href=\"/S\">Deep Sleep</a><br>"); client.print("ESP32 Modul: <a href=\"/R\">Restart</a><br>"); // The HTTP response ends with another blank line: client.println(); // break out of the while loop: break; } else { currentLine = ""; } } else if (c != '\r') { currentLine += c; } // Execute commands if (currentLine.endsWith("GET /B")) { Serial.println(" command received to Blink ESP32 Module"); BlinkLED();BlinkLED();BlinkLED(); } if (currentLine.endsWith("GET /R")) { Serial.println(" command received to restart ESP32 Module"); ESP.restart(); } if (currentLine.endsWith("GET /L1")) { Serial.println(" command received to set LED 1 GPIO to HIGH / LED ON"); BlinkLED(); digitalWrite(LED_L1, HIGH); } if (currentLine.endsWith("GET /D1")) { Serial.println(" command received to set LED 1 GPIO to LOW / LED OFF"); BlinkLED(); digitalWrite(LED_L1, LOW); } if (currentLine.endsWith("GET /L2")) { Serial.println(" command received to set LED 2 GPIO to HIGH / LED ON"); BlinkLED(); digitalWrite(LED_L2, HIGH); } if (currentLine.endsWith("GET /D2")) { Serial.println(" command received to set LED 2 GPIO to LOW / LED OFF"); BlinkLED(); digitalWrite(LED_L2, LOW); } if (currentLine.endsWith("GET /L3")) { Serial.println(" command received to set LED 3 GPIO to HIGH / LED ON"); BlinkLED(); digitalWrite(LED_L3, HIGH); } if (currentLine.endsWith("GET /D3")) { Serial.println(" command received to set LED 3 GPIO to LOW / LED OFF"); BlinkLED(); digitalWrite(LED_L3, LOW); } if (currentLine.endsWith("GET /L4")) { Serial.println(" command received to set LED 4 GPIO to HIGH / LED ON"); BlinkLED(); digitalWrite(LED_L4, HIGH); } if (currentLine.endsWith("GET /D4")) { Serial.println(" command received to set LED 4 GPIO to LOW / LED OFF"); BlinkLED(); digitalWrite(LED_L4, LOW); } if (currentLine.endsWith("GET /X")) { Serial.println(" command received to turn OFF all LEDs"); BlinkLED(); digitalWrite(LED_L1, LOW); digitalWrite(LED_L2, LOW); digitalWrite(LED_L3, LOW); digitalWrite(LED_L4, LOW); } if (currentLine.endsWith("GET /S")) { Serial.println(" command received to deep-sleep ESP32. Repower to reconnect"); esp_deep_sleep_start(); } } } client.stop(); Serial.println("Client disconnected"); } }
Kommentar