Jeg har lenge hatt garasjedøra styrt av Smarthuset. En iTach Relee enhet har styrt døra, og en Nexa sender har lest av to mikrobrytere; en for døra oppe og en for løra lukket.
Etter å ha forsøkt å rygge ut bilen før døra ver helt oppe (og siden jeg hadde to ledige releer i iTach'en) ble det "trafikklys" fra Biltema.
Automatikken (ikke mulig å åpne døre om den allerede er åpen (for da lukker den seg)) ble laget som eventer i HomeSeer og garasjedøra ble styrt av Alexa, mini sendere i bilene og diverse brytere på veggene inne og i kjelleren osv.
En blir jo lei av å bytte batterier på Nexa sendere og iTach'en er jo så gammel at den bruker 802.11b, så det var på tide å bygge noe selv og da blir det jo ESP32 og MQTT
Jeg hadde noen billige releer liggende fra Ali men de var 5V i styringen og jeg var redd ESP32 pinnen ikke likte det så jeg la inn en transistor.
Fordi det billige releet allerede hadde en transistor måtte jeg ha en Pullup Resistor som ga en spenning på over 4.6V (jeg målte) for å få det til å slå inn. For at ikke spenningen på pinnen til ESP32en skulle bli for høy fikk jeg ChatGPT til å beregne disse to motstandene for meg. Det var faktisk veldig praktisk for jeg er ikke så sterk på slike beregninger, og selv om det tok litt tid å få formidlet alle kravene og en del kontrollspørsmål måtte til ("men hva blir spenningen på ESP32 pinnen nå da?") så kom jeg altså fram til noen greie verdier.
Siden jeg ikke hadde akkurat den transistoren som ChatGPT foreslo, kunne jeg også foreslå noen av dem jeg hadde liggende helt til jeg fikk beskjed fra ChatGPT om at den kunne brukes. Veldig kjekt, raskt og forholdsvis trygt.
Med ett rele for døra (ett sekund klikk for å åpne, samme for å lukke), ett for det røde lyset og ett for det grønne og en sensor inngang for hver endebryter, var behovet dekket. Siden "trafikklysene" var 12V måtte jeg inn med en spenningsregulator på 5V.
Jeg liker at mikroprosessoren forteller hva den driver med, for det gjør testingen enklere under utviklingen men også under evnt. feilsøking senere, så jeg måtte inn med noen LEDs.
Før brukte jeg RGB LEDs for å kunne vise forskjellige farger i den samme LEDen men nå har jeg begynt å bruke adresserbare LEDs istedenfor. For det første klarer jeg meg med 1 motstand (i stedet for 3) og for det andre er det bare å koble seg videre til neste og neste uten flere motstander eller flere pinner på ESP32en.
Siden jeg har en haug adresserbare LEDs liggende fråtset jeg i 5 stykker:
- Connect Status(Gul=Startup, Rød=Venter på WiFi, Blå=Har WiFi venter på MQTT, Grønn=MQTT Connected
- Mikrobryter oppe (Gul=Startup, Rød=Bryter Lukket, Grønn=Bryter Åpen)
- Mikrobryter nede (Gul=Startup, Rød=Bryter Lukket, Grønn=Bryter Åpen)
- Trafikklys Rød (Gul=Startup, Sterk Rød = Lampe Rød Lyser, Svakt Rød=Lampe Rød Slukket)
- Trafikklys Grønn (Gul=Startup, Sterk Grønn = Lampe Grønn Lyser, Svakt Grønn=Lampe Grønn Slukket)
OBS Uten en motstand mellom ESP32en og den første LEDen ble det kjempeustabilt og blinket i hytt og vær. Jeg bruke en 330 ohm.
Transistorene og motstandene og ESP32en ble loddet på et lite "kobber stripe" kort og en liten boks ble 3D Printet
Tips for å koble adresserbare LEDs: Fordi data in og ut er på hver ende av beina, kan du bøye pluss og minus pinnene til hver sin side og lodde dem etter hverandre på et "3 punkt" kobberkort:
Først hadde koden egne Topics for å styre lysene fra HomeSeer men så fant jeg ut at det ver like greit å pakke all den logikken inn i softwaren her og endte da bare opp med kommandoene:
- OpenDoor (Åpner døra om den er lukket (og bare da))
- CloseDoor (Lukkerdøra om den er åpen (og bare da))
- ActivateDoor (Trigger døra uansett hviken tilstand den er i. For å kunne override automatikken om en bryter henger seg opp)
Men status fikk da også fire tilstander (med tilhørende lys):
- Open (Grønnt lys)
- Closed (Ingen lys)
- Opening (Rødt)
- Closing (Rødt og Grønnt)
Sitat#include <EspMQTTClient.h>#include "FastLED.h"#define ONBOARD_LED 2 // Onboard LED// Adressable LED#define AddressableLEDPin GPIO_NUM_13#define WiFiStatusLED 0#define openDoorSwitchStatusLED 1#define closedDoorSwitchStatusLED 2#define redLightsStatusLED 3#define greenLightsStatusLED 4#define NUM_LEDS 5CRGB leds[NUM_LEDS];const uint8_t brightness = 255; //0-255// Switches (Buttons)#define switchDoorOpenPin GPIO_NUM_12#define switchDoorClosedPin GPIO_NUM_25int lastSwitchDoorOpenState = 20; // undefinedint lastSwitchDoorClosedState = 20; // undefinedint switchDoorOpenState = 10; // undefinedint switchDoorClosedState = 10; // undefinedint readingDoorOpenSwitch ;int readingDoorClosedSwitch ;unsigned long lastDebounceTime = 0; // the last time input pin was toggledunsigned long debounceDelay = 100; // the debounce time; increase if the output flickers// Relays#define relayRedPin GPIO_NUM_26#define relayGreenPin GPIO_NUM_33#define relayDoorPin GPIO_NUM_32//MQTTEspMQTTClient MQTTclient("ThePromisedLAN", // SSID"Hallelujah!", // WiFi Password"192.168.232.8", // MQTT Broker server ip"", // MQTTUsername Can be omitted if not needed"", // MQTTPassword Can be omitted if not needed"carportDoorClient", // Client name that uniquely identify your device1883 // The MQTT port, default to 1883. this line can be omitted);// *********************************************************************void setup() {//Serial.begin(115200);//Serial.println("Startup");// Set pin mode for test LEDpinMode(ONBOARD_LED ,OUTPUT);digitalWrite(ONBOARD_LED ,HIGH);// LEDFastLED.addLeds<WS2812B, AddressableLEDPin, RGB>(leds, NUM_LEDS);FastLED.setBrightness(brightness);leds[WiFiStatusLED] = CRGB::Yellow;leds[openDoorSwitchStatusLED] = CRGB::Yellow;leds[closedDoorSwitchStatusLED] = CRGB::Yellow;leds[redLightsStatusLED] = CRGB(10,0,0);leds[greenLightsStatusLED] = CRGB(0,10,0);FastLED.show(); // initdelay(1000);// MQTTclient.setKeepAlive();MQTTclient.setKeepAlive(60);// SwitchespinMode(switchDoorOpenPin, INPUT_PULLUP);pinMode(switchDoorClosedPin, INPUT_PULLUP);// RelayspinMode(relayRedPin,OUTPUT);pinMode(relayGreenPin,OUTPUT);pinMode(relayDoorPin,OUTPUT);// Transistor drive invert signals so HIGH = RelayOFFdigitalWrite(relayRedPin,LOW); // Turn offdigitalWrite(relayGreenPin,LOW); // Turn offdigitalWrite(relayDoorPin,LOW); // Turn off}// *********************************************************************void loop() {MQTTclient.loop();// LED Connection statusif (MQTTclient.isMqttConnected() && MQTTclient.isWifiConnected() ) {leds[WiFiStatusLED] = CRGB::Green; // ok// Serial.println("Mqtt wifi");}if (!MQTTclient.isMqttConnected() && MQTTclient.isWifiConnected() ) {leds[WiFiStatusLED] = CRGB::Blue; // Wait MQTT// Serial.println("!Mqtt wifi");}if (!MQTTclient.isMqttConnected() && !MQTTclient.isWifiConnected() ) {leds[WiFiStatusLED] = CRGB::Red; // Wait WiFI// Serial.println("!Mqtt !wifi");}// Switch statusesif (switchDoorOpenState==LOW) { // Closedleds[openDoorSwitchStatusLED] = CRGB::Red;} else {leds[openDoorSwitchStatusLED] = CRGB::Green;}if (switchDoorClosedState==LOW) {leds[closedDoorSwitchStatusLED] = CRGB::Red;} else {leds[closedDoorSwitchStatusLED] = CRGB::Green;}// UpdateFastLED.show();delay(1);// Onboard LED Statusif (MQTTclient.isMqttConnected()) {digitalWrite(ONBOARD_LED ,LOW);} else {digitalWrite(ONBOARD_LED ,HIGH);}// Read SwitchesreadingDoorOpenSwitch = digitalRead(switchDoorOpenPin);readingDoorClosedSwitch = digitalRead(switchDoorClosedPin);if (readingDoorOpenSwitch != lastSwitchDoorOpenState || readingDoorClosedSwitch != lastSwitchDoorClosedState ) { // any change?lastDebounceTime = millis(); // reset the debouncing timer//Serial.print("Open:");//Serial.println(readingDoorOpenSwitch);//Serial.print("Close:");//Serial.println(readingDoorClosedSwitch);}//Check debounceif ((millis() - lastDebounceTime) > debounceDelay) { // has it been there for longer than the debounceif (MQTTclient.isMqttConnected()) {//test DoorOpen Switchif (readingDoorOpenSwitch != switchDoorOpenState) {if (readingDoorOpenSwitch==LOW) { // Active LOWMQTTclient.publish("carportDoorClient/status", "Open");digitalWrite(relayGreenPin,HIGH); // Turn onleds[greenLightsStatusLED] = CRGB(0,255,0);digitalWrite(relayRedPin,LOW); // Turn offleds[redLightsStatusLED] = CRGB(10,0,0);} else {MQTTclient.publish("carportDoorClient/status", "Closing");digitalWrite(relayRedPin,HIGH); // Turn onleds[redLightsStatusLED] = CRGB(255,0,0);digitalWrite(relayGreenPin,LOW); // Turn offleds[greenLightsStatusLED] = CRGB(0,10,0);}//Serial.println("Publish switchDoorOpen");switchDoorOpenState=readingDoorOpenSwitch;}//test DoorClose Switchif (readingDoorClosedSwitch != switchDoorClosedState) {if (readingDoorClosedSwitch==LOW) { // Active LOWMQTTclient.publish("carportDoorClient/status", "Closed");digitalWrite(relayGreenPin,LOW); // Turn offleds[greenLightsStatusLED] = CRGB(0,10,0);digitalWrite(relayRedPin,LOW); // Turn offleds[redLightsStatusLED] = CRGB(10,0,0);} else {MQTTclient.publish("carportDoorClient/status", "Opening");digitalWrite(relayRedPin,HIGH); // Turn onleds[redLightsStatusLED] = CRGB(255,0,0);digitalWrite(relayGreenPin,HIGH); // Turn onleds[greenLightsStatusLED] = CRGB(0,255,0);}//Serial.println("Publish switchDoorClosed");switchDoorClosedState=readingDoorClosedSwitch;}}}lastSwitchDoorOpenState=readingDoorOpenSwitch;lastSwitchDoorClosedState=readingDoorClosedSwitch;}// ********************** SUBS ***********************************************void onConnectionEstablished(){Serial.println("onConnectionEstablished");MQTTclient.publish("carportDoorClient/status", "started"); // You can activate the retain flag by setting the third parameter to trueMQTTclient.subscribe("carportDoorClient/activateDoor", [](const String & payload) {//Serial.print("activateDoor: ");//Serial.println(payload);// Click door relay for 1 sekdigitalWrite(relayDoorPin,HIGH); // Turn ondelay(1000);digitalWrite(relayDoorPin,LOW); // Turn off});MQTTclient.subscribe("carportDoorClient/openDoor", [](const String & payload) {//Serial.print("openDoor: ");//Serial.println(payload);// Only if door are closedif (switchDoorClosedState==LOW) {// Click door relay for 1 sekdigitalWrite(relayDoorPin,HIGH); // Turn ondelay(1000);digitalWrite(relayDoorPin,LOW); // Turn off}});MQTTclient.subscribe("carportDoorClient/closeDoor", [](const String & payload) {//Serial.print("closeDoor: ");//Serial.println(payload);// Only if door are openif (switchDoorOpenState==LOW) {// Click door relay for 1 sekdigitalWrite(relayDoorPin,HIGH); // Turn ondelay(1000);digitalWrite(relayDoorPin,LOW); // Turn off}});}
Jeg burde selvfølgelig puttet all den lys-koden i små subrutiner, men det kan dere kose dere selv med 😉
Jeg har alltid med denne lille koden
Anbefalte kommentarer
Det er ingen kommentarer å vise.
Bli med i samtalen
Du kan publisere innhold nå og registrere deg senere. Hvis du har en konto, logg inn nå for å poste med kontoen din.