Gå til innhold
  • Bli medlem
Støtt hjemmeautomasjon.no!
  • Fermate
    Fermate

    ESP32/MQTT Garasjeport åpner med sensorer og trafikklys

    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. 

    image.png 

     

    image.png

     

    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

     

    image.png

     

    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:

     

    image.png

     

    image.png

     

    image.png

     

    image.png

     

    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 5
    CRGB leds[NUM_LEDS];
    const uint8_t brightness      = 255; //0-255
     
    // Switches (Buttons)
    #define switchDoorOpenPin           GPIO_NUM_12
    #define switchDoorClosedPin         GPIO_NUM_25
    int lastSwitchDoorOpenState       = 20; // undefined
    int lastSwitchDoorClosedState     = 20; // undefined
    int switchDoorOpenState       = 10; // undefined
    int switchDoorClosedState     = 10; // undefined
    int readingDoorOpenSwitch ;
    int readingDoorClosedSwitch ;
    unsigned long lastDebounceTime = 0;  // the last time input pin was toggled
    unsigned 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
     
    //MQTT
    EspMQTTClient 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 device
      1883              // The MQTT port, default to 1883. this line can be omitted
    );
     
    // *********************************************************************
    void setup() {
      //Serial.begin(115200);
      //Serial.println("Startup");
     
      // Set pin mode for test LED
      pinMode(ONBOARD_LED ,OUTPUT);
      digitalWrite(ONBOARD_LED ,HIGH);
     
      // LED
      FastLED.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(); // init
      delay(1000);
     
      // MQTTclient.setKeepAlive();
      MQTTclient.setKeepAlive(60);
     
     // Switches
      pinMode(switchDoorOpenPin, INPUT_PULLUP);
      pinMode(switchDoorClosedPin, INPUT_PULLUP);
     
      // Relays
      pinMode(relayRedPin,OUTPUT);
      pinMode(relayGreenPin,OUTPUT);
      pinMode(relayDoorPin,OUTPUT);
      // Transistor drive invert signals so HIGH = RelayOFF
      digitalWrite(relayRedPin,LOW); // Turn off
      digitalWrite(relayGreenPin,LOW); // Turn off
      digitalWrite(relayDoorPin,LOW); // Turn off
     
    }
     
    // *********************************************************************
    void loop() {
        MQTTclient.loop();
     
        // LED Connection status
        if (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 statuses
        if (switchDoorOpenState==LOW) { // Closed
         leds[openDoorSwitchStatusLED] = CRGB::Red;
        } else {
         leds[openDoorSwitchStatusLED] = CRGB::Green;
        }
        if (switchDoorClosedState==LOW) {
         leds[closedDoorSwitchStatusLED] = CRGB::Red;
        } else {
         leds[closedDoorSwitchStatusLED] = CRGB::Green;
        }
        // Update
        FastLED.show();
        delay(1);
     
        // Onboard LED Status
        if (MQTTclient.isMqttConnected()) {
         digitalWrite(ONBOARD_LED ,LOW);
        } else {
         digitalWrite(ONBOARD_LED ,HIGH);
        }
     
        // Read Switches
        readingDoorOpenSwitch = 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 debounce
        if ((millis() - lastDebounceTime) > debounceDelay) { // has it been there for longer than the debounce
          if (MQTTclient.isMqttConnected()) {
            //test DoorOpen Switch
           if (readingDoorOpenSwitch != switchDoorOpenState) {
             if (readingDoorOpenSwitch==LOW) { // Active LOW
               MQTTclient.publish("carportDoorClient/status", "Open");
               digitalWrite(relayGreenPin,HIGH); // Turn on
               leds[greenLightsStatusLED] = CRGB(0,255,0);
               digitalWrite(relayRedPin,LOW); // Turn off
               leds[redLightsStatusLED] = CRGB(10,0,0);
              } else {
               MQTTclient.publish("carportDoorClient/status", "Closing");
               digitalWrite(relayRedPin,HIGH); // Turn on
               leds[redLightsStatusLED] = CRGB(255,0,0);
               digitalWrite(relayGreenPin,LOW); // Turn off
               leds[greenLightsStatusLED] = CRGB(0,10,0);
              }
              //Serial.println("Publish switchDoorOpen");
              switchDoorOpenState=readingDoorOpenSwitch;
            }
            //test DoorClose Switch
           if (readingDoorClosedSwitch != switchDoorClosedState) {
              if (readingDoorClosedSwitch==LOW) { // Active LOW
               MQTTclient.publish("carportDoorClient/status", "Closed");
               digitalWrite(relayGreenPin,LOW); // Turn off
               leds[greenLightsStatusLED] = CRGB(0,10,0);
               digitalWrite(relayRedPin,LOW); // Turn off
               leds[redLightsStatusLED] = CRGB(10,0,0);
              } else {
               MQTTclient.publish("carportDoorClient/status", "Opening");
               digitalWrite(relayRedPin,HIGH); // Turn on
               leds[redLightsStatusLED] = CRGB(255,0,0);
               digitalWrite(relayGreenPin,HIGH); // Turn on
               leds[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 true
     
      MQTTclient.subscribe("carportDoorClient/activateDoor", [](const String & payload) {
       //Serial.print("activateDoor: ");
       //Serial.println(payload);
       // Click door relay for 1 sek
       digitalWrite(relayDoorPin,HIGH); // Turn on
       delay(1000);
       digitalWrite(relayDoorPin,LOW); // Turn off
      });
     
      MQTTclient.subscribe("carportDoorClient/openDoor", [](const String & payload) {
       //Serial.print("openDoor: ");
       //Serial.println(payload);
       // Only if door are closed
       if (switchDoorClosedState==LOW) {
         // Click door relay for 1 sek
         digitalWrite(relayDoorPin,HIGH); // Turn on
         delay(1000);
         digitalWrite(relayDoorPin,LOW); // Turn off
        }
      });
     
      MQTTclient.subscribe("carportDoorClient/closeDoor", [](const String & payload) {
       //Serial.print("closeDoor: ");
       //Serial.println(payload);
       // Only if door are open
       if (switchDoorOpenState==LOW) {
         // Click door relay for 1 sek
         digitalWrite(relayDoorPin,HIGH); // Turn on
         delay(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

        // Onboard LED Status
        if (MQTTclient.isMqttConnected()) {
         digitalWrite(ONBOARD_LED ,LOW);
        } else {
         digitalWrite(ONBOARD_LED ,HIGH);
        }
    slik at jeg kan debugge debuggings lysene også 😄 
     
    Her er et bilde fra prototypingen:

    image.png

    Brukertilbakemelding

    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.

    Gjest
    Skriv en kommentar...

    ×   Du har limt inn tekst med formatering.   Lim inn uten formatering i stedet

      Du kan kun bruke opp til 75 smilefjes.

    ×   Lenken din har blitt bygget inn på siden automatisk.   Vis som en ordinær lenke i stedet

    ×   Tidligere tekst har blitt gjenopprettet.   Tøm tekstverktøy

    ×   Du kan ikke lime inn bilder direkte. Last opp eller legg inn bilder fra URL.




×
×
  • Opprett ny...

Viktig informasjon

Vi har plassert informasjonskapsler/cookies på din enhet for å gjøre denne siden bedre. Du kan justere dine innstillinger for informasjonskapsler, ellers vil vi anta at dette er ok for deg.