Zugriffskontrolle mit Nummernfeld, ESP32 und Shelly
In diesem Beitrag möchte ich dir zeigen, wie du eine Zugriffskontrolle mit einem Nummernfeld und einem ESP32 fĂŒr einen Shelly bauen und programmieren kannst.
Den Shelly habe ich dir bereits in diversen BeitrĂ€gen vorgestellt, wie zum Beispiel.: - Shelly Plus #1: Shelly Plus 1 Ăberblick - Einsatzgebiete fĂŒr den Shelly - Shelly Plus #4: PIR Sensor am AddOn
AZ-Delivery D1 Board mit ESP32 Chip
Shelly Plus 1 Der Shelly verfĂŒgt ĂŒber ein Relais, mit welchem wir Lasten bis zu 16A steuern können und wenn wir ein SchĂŒtz anklemmen, sogar noch gröĂere. Mit diesem Relais können wir somit recht einfach ein Rolltor oder ein Schiebetor mit Motor steuern.
Was ist ein SchĂŒtz?
Ein SchĂŒtz, auch bekannt als SchaltschĂŒtz, dient zum Schalten von groĂen Lasten. Dabei wird mit einer kleinen Spannung eine groĂe Last ĂŒber einen elektromagnetischen Schalter gesteuert. Mithilfe dieses Bauteils können wir also mit einer kleinen Spannung einen groĂen Verbraucher schalten. Möchtest du mehr ĂŒber dieses Bauteil lesen, so empfehle ich dir den Beitrag von elektro4000.de.
Installationsschutz der Marke ABB
Ziel des Projektes - Zugriffskontrolle per Nummernfeld am ESP32 fĂŒr Shelly
Das Ziel dieses kleinen Projektes ist es, eine Schaltung aufzubauen, mit welcher wir ĂŒber ein Nummernfeld und einem ESP32 den Befehl an ein Shelly zum Aktivieren / Deaktivieren senden können. Die Stern-Taste soll mit der Funktion letzte Stelle löschen und die Raute-Taste mit AusfĂŒhren belegt werden. Die Eingabe soll dabei ĂŒber ein LCD-Display ablesbar sein. https://youtu.be/BtRdL_shxT8
Benötigte Ressourcen fĂŒr das Projekt
Wenn du das Projekt nachbauen möchtest, dann benötigst du: - einen Shelly, - einen ESP32, - ein Nummernfeld, - ein LCD-Display mit I2C Schnittstelle, - diverse Breadboardkabel, Der Shelly benötigt fĂŒr den Betrieb eine Stromquelle von 12 V Gleichstrom oder 230 V Wechselstrom. Den ESP32 versorge ich in diesem Beispiel mit einem einfachen USB-Netzteil.
Aufbau der Schaltung - Nummernfeld am ESP32
SchlieĂen wir zunĂ€chst das Nummernfeld und das LCD-Display an den ESP32 an.
Nachfolgend die Pinbelegungen am ESP32 fĂŒr diese Schaltung: BauteilESP323x4 KeypadPin 7GPIO12Pin 6GPIO14Pin 5GPIO27Pin 4GPIO16Pin 3GPIO17Pin 2GPIO25Pin 1GPIO26LCD-DisplayGNDGNDVCC5 VSDAGPIO21SCLGPIO22LED, grĂŒnGPIO19LED, rotGPIO18BuzzerGPIO23
Anschluss des Shelly
Der Shelly kann wie bereits erwĂ€hnt Verbraucher bis zu 16A schalten, das reicht im Hausgebrauch fĂŒr die meisten FĂŒr diesen Aufbau verwende ich eine Lampe, welche im spĂ€teren Verlauf aktiviert / deaktiviert wird.
Shelly Plus 1 mit Lampe Die Lampe habe ich wie im Beitrag Shelly Plus #1: Shelly Plus 1 Ăberblick mit einer Steckdose dargestellt angeschlossen.
Relais per HTTP Request steuern
Das Relais lĂ€sst sich sehr einfach per HTTP Request steuern. Die Dokumentation zur Schnittstelle findest du auf der Seite https://shelly-api-docs.shelly.cloud/gen2/ComponentsAndServices/HTTP/. FĂŒr das Absenden benötigen wir die IP-Adresse des Shellys diese findest du entweder in deinem Router oder in der Shelly App, wenn du das GerĂ€t auswĂ€hlst und dort die GerĂ€teinformationen aufrufst.
GerĂ€teinformationen zum Shelly Zum Aktivieren des Relais mĂŒssen wir nur den Befehl im Browser oder per Postman ausfĂŒhren. http:///relay/0?turn=on Wenn das Relais deaktiviert werden soll, so muss der Parameter "turn" lediglich auf den Wert "off" gestellt werden. http:///relay/0?turn=off Als RĂŒckgabe erhĂ€lt man ein JSON: {"ison": true, "has_timer":false, "timer_started_at": 0, "timer_duration": 0.00, "timer_remaining": 0.00, "source": "http"}
LCD-Display 16x2
Auf dem Display werden die verschiedenen ZustĂ€nde und Meldungen angezeigt. Im Fehlerfall soll zbsp. wenn der Shelly nicht erreichbar ist, die Meldung "Device not found" angezeigt werden. Wenn die WiFi Verbindung verloren gegangen ist, dann soll "missing WiFi" angezeigt werden. Wenn eine gĂŒltige Pin eingegeben wurde, dann wird dem Benutzer "ACCESS GRANTED!" angezeigt. In allen anderen FĂ€llen erscheint die Textzeile zum Eingeben einer Pin.
Programmieren in der Arduino IDE
Wie man die 3x4 Matrix am Arduino programmiert, habe ich dir bereits im Beitrag Arduino Lektion 64: 3Ă4 Matrix Tastatur erlĂ€utert, diesen Beitrag verwende ich als Grundlage fĂŒr das Programm. erzeugen einer Ausgabe am LCD-Display ZunĂ€chst binden wir die Bibliothek LiquidCrystal mit dem Befehl include ein. Diese kannst du ĂŒber den internen Bibliotheksverwalter (1) der Arduino IDE installieren, indem du zunĂ€chst nach "LiquidCrystal" (2) suchst und dann die SchaltflĂ€che "INSTALL" (3) am Eintrag "LiquidCrystal by Arduino, Adafruit" klickst. Wenn der Installationsprozess erfolgreich abgeschlossen ist, dann sollte der Text "INSTALLED" (4) angezeigt werden.
Installieren der Bibliothek LiquidCrystal ĂŒber den Bibliotheksmanager der Arduino IDE //Einbinden der Bibliotheken //fĂŒr das LCD-Display #include #include //Es wird ein I2C Display mit 16 Zeichen, //und zwei Zeilen verwendet. LiquidCrystal_I2C lcd(0x27, 16, 2); void setup() { //initialisieren des LCD-Displays lcd.init(); lcd.backlight(); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Shelly Secure v1"); lcd.setCursor(0, 1); lcd.print("PIN:"); } /** * Funktion wird fortlaufen ausgefĂŒhrt. **/ void loop() { //bleibt leer } lesen der Tasten am 3x4 Keypad FĂŒr die Programmierung des 3x4 Keypad benötigen wir wie auch beim LCD-Display eine Bibliothek, welche wir ebenso ĂŒber den Bibliotheksmanager installieren. Dazu suchen wir nach "Keypad" (1) und wĂ€hlen am Eintrag "Keypad by Mark Stanley, Alexander Brevig" die SchaltflĂ€che "INSTALL" (2), wenn der Installationsprozess abgeschlossen ist, dann wird der Text "INSTALLED" (3) angezeigt.
Installieren der Bibliothek Keypad ĂŒber den Bibliotheksmanager der Arduino IDE //Einbinden der Bibliotheken //fĂŒr das 3x4 Keypad #include //Definieren des Keypads const byte COLS = 3; //3 Spalten const byte ROWS = 4; //4 Zeilen //Pins von Links nach Rechts! byte colPins = { 12, 14, 27 }; byte rowPins = { 16, 17, 25, 26 }; //definieren wo welche Taste liegt. char KEYS = { { '#', '0', '*' }, { '9', '8', '7' }, { '6', '5', '4' }, { '3', '2', '1' } }; //Instanziieren eines Objektes vom Typ Keypad //mit den zuvor definierten Werten Keypad myKeypad = Keypad(makeKeymap(KEYS), rowPins, colPins, ROWS, COLS); void setup() { //begin der seriellen Kommunikation mit 115200 baud Serial.begin(115200); } /** * Funktion wird fortlaufen ausgefĂŒhrt. **/ void loop() { //auslesen der gedrĂŒckten Taste char key = myKeypad.getKey(); //Wenn eine Taste betĂ€tigt ist, dann enthĂ€lt die Variable key einen Wert if (key) { Serial.println(key); } } Aufbau einer WiFi-Verbindung und absenden eines HTTP Requests Die Bibliotheken fĂŒr den ESP32 wurden bereits mit dem Boardtreiber installiert, daher mĂŒssen wir diese lediglich mit dem include Befehl einbinden. //Einbinden der Bibliotheken //fĂŒr die WiFi Verbindung des ESP32 #include #include //SSID & Passwort fĂŒr das lokale WiFi #define WIFI_SSID "***" #define WIFI_PASSWORD "***" void setup() { //begin der seriellen Kommunikation mit 115200 baud Serial.begin(115200); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(200); } //Wenn die Verbindung erfolgreich aufgebaut wurde, //dann soll die IP-Adresse auf der seriellen Schnittstelle //ausgegeben werden. Serial.println(""); Serial.println("WiFi connected."); Serial.print("IP address: "); Serial.println(WiFi.localIP()); Serial.println(); } /** * Funktion wird fortlaufen ausgefĂŒhrt. **/ void loop() { //bleibt leer } Der komplette Code fĂŒr die Zugriffskontrolle am ESP32 mit Nummernfeld fĂŒr den Shelly Hier nun der komplette Code mit Kommentaren. Am Ende des Beitrages findest du einen Link, wo du diesen einfach als ZIP-Datei herunterladen kannst. //Einbinden der Bibliotheken //fĂŒr das LCD-Display #include #include //fĂŒr das 3x4 Keypad #include //fĂŒr die WiFi Verbindung des ESP32 #include #include //SSID & Passwort fĂŒr das lokale WiFi #define WIFI_SSID "****" #define WIFI_PASSWORD "*****" //Pins der LEDs #define ledGruen 19 #define ledRot 18 //Pin des Buzzers #define buzzer 23 //Konstanten fĂŒr die PWM Signalerzeugung. //Diese Werte werden benötigt damit ein //Ton am Buzzer wiedergegeben werden kann. const int CHANNEL = 0; const int FREQUENZ = 2000; const int RESOLUTIONBITS = 12; const int TONE_FREQ = 600; //Es wird ein I2C Display mit 16 Zeichen, //und zwei Zeilen verwendet. LiquidCrystal_I2C lcd(0x27, 16, 2); //Definieren des Keypads const byte COLS = 3; //3 Spalten const byte ROWS = 4; //4 Zeilen //Pins von Links nach Rechts! byte colPins = { 12, 14, 27 }; byte rowPins = { 16, 17, 25, 26 }; //definieren wo welche Taste liegt. char KEYS = { { '#', '0', '*' }, { '9', '8', '7' }, { '6', '5', '4' }, { '3', '2', '1' } }; //Instanziieren eines Objektes vom Typ Keypad //mit den zuvor definierten Werten Keypad myKeypad = Keypad(makeKeymap(KEYS), rowPins, colPins, ROWS, COLS); //Index ab wo die Pineingabe startet. //Auf dem Display soll in Zeile 2 zunĂ€chst //das Wort "Pin:" stehen. int keyIndex = 4; //Index fĂŒr die Anzahl der gedrĂŒckten Tasten int pinIndex = 0; //Auf dem Display sind lediglich 11 freie Stellen, //dieses bedeutet das eine Pin maximal 11 Stellen haben soll/kann. char pin = {}; //Die Pin welche spĂ€ter geprĂŒft werden soll. //Die Raute am Ende signalisiert das Ende der Pin. const char PIN = { '1', '4', '6', '2', '#' }; //Feld zum speichern ob die Pin korrekt eingegeben wurde. bool accessGranted = false; //Die Adresse zum steuern des Relais. //Hier musst du deine IP-Adresse eintragen! //der Wert fĂŒr den Key "turn" wird spĂ€ter im Code ergĂ€nzt. String shellyRelaisAddress = "http://192.168.178.101/relay/0?turn="; //Feld zum speichern des Relaisstatus bool relaisStatus = false; void setup() { //begin der seriellen Kommunikation mit 115200 baud Serial.begin(115200); //Definieren das die Pins der LEDs //und des Buzzers als Ausgang dient. pinMode(ledGruen, OUTPUT); pinMode(ledRot, OUTPUT); pinMode(buzzer, OUTPUT); //initial die rote LED aktivieren //und die grĂŒne deaktivieren digitalWrite(ledRot, HIGH); digitalWrite(ledGruen, LOW); //konfigurieren des PWM Channels ledcSetup(CHANNEL, FREQUENZ, RESOLUTIONBITS); ledcAttachPin(buzzer, CHANNEL); //starten der WiFi-Verbindung initWiFi(); //initialisieren des LCD-Displays lcd.init(); lcd.backlight(); //initialisieren des Displays und der Felder init(); } /** * Funktion initialisiert die WiFi-Verbindung * Wenn die Verbindung aufgebaut wurde, dann wird * die IP-Adresse auf der seriellen Schnittstelle ausgegeben. **/ void initWiFi() { WiFi.begin(WIFI_SSID, WIFI_PASSWORD); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(200); } //Wenn die Verbindung erfolgreich aufgebaut wurde, //dann soll die IP-Adresse auf der seriellen Schnittstelle //ausgegeben werden. Serial.println(""); Serial.println("WiFi connected."); Serial.print("IP address: "); Serial.println(WiFi.localIP()); Serial.println(); } /** * Initialisiert das LCD-Display & die Felder **/ void init() { accessGranted = false; keyIndex = 4; pinIndex = 0; //zurĂŒcksetzen der eingegeben Zeichen pin = {}; //löscht das LCD-Display lcd.clear(); reset(); digitalWrite(ledRot, HIGH); digitalWrite(ledGruen, LOW); } /** * Funktion zeigt auf dem LCD-Display * in Zeile 1 den Text "Shelly Secure v1" an * in Zeile 2 den Text "PIN:" gefolgt von * den bisher eingegebenen Zeichen an. **/ void reset() { lcd.setCursor(0, 0); lcd.print("Shelly Secure v1"); lcd.setCursor(0, 1); lcd.print("PIN:"); //Schleife von 0 bis pinIndex, //wobei pinIndex maximal 11 Stellen haben kann. for (int i = 0; i < pinIndex; i++) { //den aktuellen Cursor um eins nach links schieben //das Zeichen aus dem Array an die Position schreiben lcd.setCursor(i + 4, 1); lcd.print(pin); } } /** * Wenn die eingegebene Pin ok ist dann wird, * das Display gelöscht und * die Textzeile "ACCESS GRANTED!" angezeigt. **/ void executeAccessGranted() { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Shelly Secure v1"); lcd.setCursor(0, 1); lcd.print("ACCESS GRANTED!"); //setzen des Feldes auf TRUE accessGranted = true; //aktivieren/deaktivieren des Relais setShellyRelaisStatus(); } /** * Wenn die WiFi-Verbindung erfolgreich aufgebaut wurde, * dann wird der Status des Relais umgekehrt * aus true wird false / aus false wird true * und je nach Wert dann * der Parameterwert "on" oder "off" angehĂ€ngt. * Die URL sowie der HTTP-ResponseCode wird * fĂŒr Debugausgaben in der seriellen Schnittstelle angezeigt. **/ int setShellyRelaisStatus() { if (WiFi.status() == WL_CONNECTED) { String command = shellyRelaisAddress; relaisStatus = !relaisStatus; if (relaisStatus) { command += "on"; digitalWrite(ledGruen, HIGH); digitalWrite(ledRot, LOW); } else { command += "off"; init(); } Serial.print("URL:"); Serial.println(command); HTTPClient http; http.setTimeout(1000); http.begin(command.c_str()); int httpResponseCode = http.GET(); Serial.print("HTTP Code:"); Serial.println(httpResponseCode); http.end(); //Ein HTTP-ResponseCode ungleich als 200 bedeutet ein Fehler. //In diesem Fall wird es mit hoher Wahrscheinlichkeit sein das, //der Shelly nicht erreichbar ist. if (httpResponseCode != 200) { //Ausgeben der Meldung auf dem Display printMessage("Device Read the full article
















