In diesem Projekt habe ich mit einem ESP8266 eine einfache Türklingel smart gemacht. Sobald es an der Tür klingelt, wird eine MQTT-Nachricht verschickt. Es werden nur die folgende Komponenten benötigt:
- ESP8266
- Selbst gelötete Platine
- Normale Hausklingel
Das Prinzip
An einer normalen Türklingel liegen, wenn der Klingelknopf gedrückt wird eine 12 Volt Wechselspannung an (an den meisten Klingeln zumindest).
Diese wird mit einem Gleichrichter gleichgerichtet, also in eine Gleichspannung verwandelt (siehe Bild 1). Diese Gleichspannung aktiviert einen Optokoppler. Mehr dazu kann man dem Schaltplan entnehmen (siehe Bild 2). Dadurch, dass der Optokoppler einen Kurzschluss zwischen GND
und RESET
des ESP erzeugt, wacht der ESP auf und sendet ein Signal per MQTT an den Server. Dabei schickt er auch noch seine BatteryVoltage (eigentlich CORE-Spannung, da ich aber nicht Vin
nutze, sondern direkt 3.3V speise ist das egal) mit. Dieser wurde vorher in den Deepsleep versetzt. Das Batteriefach welches ich nutze, hat leider einen Vorwiederstand, dieser ist für uns aber nur hinderlich und wird überbrückt. Der Code ist auch auf Github verfügbar.
Um kurz meinen Code zu erklären: Zuerst wird der ADC (AnalogDigitalConverter) auf “ADC_VCC” gesetzt, das bedeutet das der ADC die interne CPU-Spannung misst. Im Abschnitt “WiFi Access Point” müssen die WLAN Anmeldedaten eingegeben werden. Also WLAN_SSID
muss die WLAN SSID sein, WLAN_PASS
muss das WLAN-Passwort sein. Wichtig ist auch der “MQTT Server Setup” Abschnitt. Dort müssen die MQTT Serveranmeldedaten eingegeben werden. In Feeds werden zwei Feeds definiert, einmal photocell
, dieser wird auf 1 gesetzt wenn es klingelt, battery
sendet den Batterieladezustand.
Der Code
ADC_MODE(ADC_VCC);
#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
/************************* WiFi Access Point *********************************/
#define WLAN_SSID ""
#define WLAN_PASS ""
/************************* MQTT Server Setup *********************************/
#define AIO_SERVER "server"
#define AIO_SERVERPORT 1883 // use 8883 for SSL
#define AIO_USERNAME ""
#define AIO_KEY ""
/************ Global State (you don't need to change this!) ******************/
// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient client;
// or... use WiFiFlientSecure for SSL
//WiFiClientSecure client;
// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
/****************************** Feeds ***************************************/
Adafruit_MQTT_Publish photocell = Adafruit_MQTT_Publish(&mqtt, "/klingel");
Adafruit_MQTT_Publish battery = Adafruit_MQTT_Publish(&mqtt, "/battery");
/*************************** Sketch Code ************************************/
void MQTT_connect();
void setup() {
Serial.begin(115200);
Serial.setTimeout(2000);
delay(10);
Serial.println(F("MQTT Tuerklingel"));
// Connect to WiFi access point.
Serial.println(); Serial.println();
Serial.print("Connecting to ");
Serial.println(WLAN_SSID);
WiFi.begin(WLAN_SSID, WLAN_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected");
Serial.println("IP address: "); Serial.println(WiFi.localIP());
}
uint32_t x = 0;
void loop() {
yield();
MQTT_connect();
Serial.print(F("\nSENDING door change "));
Serial.print(1);
Serial.print("...");
if (! photocell.publish(1)) {
Serial.println(F("Failed"));
} else {
Serial.println(F("OK!"));
}
Serial.print(F("\nSENDING battery "));
Serial.print(ESP.getVcc());
Serial.print("...");
if (! battery.publish(ESP.getVcc())) {
Serial.println(F("Failed"));
} else {
Serial.println(F("OK!"));
}
delay(1000);
Serial.print(F("\nSending RESET signal"));
Serial.print("...");
if (! photocell.publish(0)) {
Serial.println(F("Failed"));
} else {
Serial.println(F("OK!"));
}
Serial.println(F("Going to sleep!"));
delay(20);
ESP.deepSleep(0);
}
// Function to connect and reconnect as necessary to the MQTT server.
// Should be called in the loop function and it will take care if connecting.
void MQTT_connect() {
int8_t ret;
// Stop if already connected.
if (mqtt.connected()) {
return;
}
Serial.print("Connecting to MQTT... ");
uint8_t retries = 3;
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
Serial.println(mqtt.connectErrorString(ret));
Serial.println("Retrying MQTT connection in 5 seconds...");
mqtt.disconnect();
delay(5000); // wait 5 seconds
retries--;
if (retries == 0) {
// basically die and wait for WDT to reset me
while (1);
}
}
Serial.println("MQTT Connected!");
}
Zuletzt fehlte nur noch ein passendes Gehäuse. Die STL Datei des Gehäuses gibt es auch auf Github. An den Pfosten auf welchen der ESP8266 gesteckt werden sollte, musste erst die Feile etwas nachhelfen. Dann wurde noch ein 3mm dickes Loch in den Deckel gebohrt, um die Leitungen der Klingel durchlassen zu können. Zuletzt noch ein paar Bilder:
Nachtrag: Dieses Projekt macht nur wirklich Sinn wenn man eine ständige Stromversorgung hat und das WLan stabil ist. Ich nutze mittlerweile die HmIP-DSD-PCB von Homematic.
Leave a Reply