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

    ESP32/MQTT Det første programmet (3)

    Først basis koden, her er et generisk basis skjelett for MQTT:

     

    Sitat
    #include <EspMQTTClient.h>

     

    //MQTT
    EspMQTTClient MQTTclient(
      "ThePromisedLAN", // SSID
      "Hallelujah!", // WiFi Password
      "192.168.1.2",  // MQTT Broker server ip
      "",   // MQTTUsername Can be omitted if not needed
      "",   // MQTTPassword Can be omitted if not needed
      "hjemmeautomasjonClient",     // Client name that uniquely identify your device
      1883              // The MQTT port, default to 1883. this line can be omitted
    );

     

    // *********************************************************************
    void setup() {
       
      MQTTclient.setKeepAlive(60);
    }

     

    // *********************************************************************
    void loop() {
        MQTTclient.loop();

     

        // Can test for this if you need
        if (!MQTTclient.isMqttConnected() && MQTTclient.isWifiConnected() ) {
          // Connected to WiFi only
         }
        if (MQTTclient.isMqttConnected() ) {
          // Connected to MQTT
         }

     

         if ( 1 == 2 ) { // her legger du testen på når du skal sende MQTT data
          MQTTclient.publish("hjemmeautomasjonClient/switch", "1"); // Publish something
        }
      }

     

    // ********************** SUBS ***********************************************
    void onConnectionEstablished()
     {
     Serial.println("onConnectionEstablished");
     MQTTclient.publish("hjemmeautomasjonClient/status", "started"); // You can activate the retain flag by setting the third parameter to true

     

      MQTTclient.subscribe("hjemmeautomasjonClient/LED", [](const String & payload) {
        Serial.print("Led: ");
        Serial.println(payload);
        if (payload.toInt()==0) {
          // Turn off
        } else {
         // Turn on
        }
      });
     
      }

     

    Så til saken; La oss starte med noe enkelt og tenne onboad LED'en med en MQTT kommando.

     

    Sitat
    #include <EspMQTTClient.h>

     

    #define ONBOARD_LED 2

     

    //MQTT
    EspMQTTClient MQTTclient(
      "ThePromisedLAN", // SSID
      "Hallelujah!", // WiFi Password
      "192.168.1.2",  // MQTT Broker server ip
      "",   // MQTTUsername Can be omitted if not needed
      "",   // MQTTPassword Can be omitted if not needed
      "hjemmeautomasjonClient",     // Client name that uniquely identify your device
      1883              // The MQTT port, default to 1883. this line can be omitted
    );

     

    // *********************************************************************
    void setup() {
      MQTTclient.setKeepAlive(60);
    }

     

    // *********************************************************************
    void loop() {
        MQTTclient.loop();

     

      }

     

    // ********************** SUBS ***********************************************
    void onConnectionEstablished()
     {
     Serial.println("onConnectionEstablished");
     MQTTclient.publish("hjemmeautomasjonClient/status", "started"); // You can activate the retain flag by setting the third parameter to true

     

      MQTTclient.subscribe("hjemmeautomasjonClient/LED", [](const String & payload) {
        Serial.print("Led: ");
        Serial.println(payload);
        if (payload.toInt()==0) {
          digitalWrite(ONBOARD_LED, LOW); // Turn off
        } else {
         digitalWrite(ONBOARD_LED, HIGH); // Turn on
        }
      });
     
      }

     

    Start opp MQTT Brokeren og MQTT Exploreren og overfør dette programmet til ESP32'en

     

    Det første vi ser i MQTT Exploreren resultatet av at denne linjen:

    MQTTclient.publish("hjemmeautomasjonClient/status", "started");

    er utført og at Staus = started er sendt:

     

    image.png

     

    Om vi deretter sender denne meldingen med MQTT Exploreren

     

    image.png

     

    Så tenner LED'en og vi ser også meldingen her:

     

    image.png

     

    Nå har vi altså en kommuniasjon oppe der vi kan styre ESP32'en fra MQTT.

     

    Neste stepp er å hente data fra Esp32'en.

     

    Vi bruker samme prisippet som i "Komme i gang med ESP32" koden der vi lager en "bryter" mellom GND og GPIO_13:

     

    Sitat
    #include <EspMQTTClient.h>
    #define ONBOARD_LED  2 // Onboard LED

     

    // Switches (Buttons)
    #define switchPin               GPIO_NUM_13
    int lastSwitchState             = 20; // undefined
    int switchState                 = 10; // undefined
    int readingSwitch ;
    unsigned long lastDebounceTime  = 0;  // the last time input pin was toggled
    unsigned long debounceDelay     = 100;    // the debounce time; increase if the output flickers

     

    //MQTT
    EspMQTTClient MQTTclient(
      "ThePromisedLAN", // SSID
      "Hallelujah!", // WiFi Password
      "192.168.232.50",  // MQTT Broker server ip
      "",   // MQTTUsername Can be omitted if not needed
      "",   // MQTTPassword Can be omitted if not needed
      "hjemmeautomasjonClient",     // 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);

     

        // MQTTclient.setKeepAlive();
      MQTTclient.setKeepAlive(60);

     

     // Switches
      pinMode(switchPin, INPUT_PULLUP);
    }

     

    // *********************************************************************
    void loop() {
        MQTTclient.loop();
     
        // Read Switch
        readingSwitch = digitalRead(switchPin);
       
        if (readingSwitch != lastSwitchState ) { // any change?
          lastDebounceTime = millis(); // reset the debouncing timer
        }
       
        //Check debounce
        if ((millis() - lastDebounceTime) > debounceDelay) { // has it been there for longer than the debounce
          // Switch new value?
          if (readingSwitch != switchState) {
            if (MQTTclient.isMqttConnected()) {
              if (readingSwitch==LOW) { // Active LOW
                MQTTclient.publish("hjemmeautomasjonClient/switch", "Closed");
              } else {
                MQTTclient.publish("hjemmeautomasjonClient/switch", "Open");
              }
              Serial.println("Publish switch");
              switchState=readingSwitch;
            }
          }
        }
       lastSwitchState=readingSwitch;
      }

     

    // ********************** SUBS ***********************************************
    void onConnectionEstablished()
     {
     Serial.println("onConnectionEstablished");
     MQTTclient.publish("hjemmeautomasjonClient/status", "started"); // You can activate the retain flag by setting the third parameter to true
      Serial.println("onConnectionEstablished");
     
      MQTTclient.subscribe("hjemmeautomasjonClient/LED", [](const String & payload) {
        Serial.print("Led: ");
        Serial.println(payload);
        if (payload.toInt()==0) {
          digitalWrite(ONBOARD_LED, LOW); // Turn off
        } else {
         digitalWrite(ONBOARD_LED, HIGH); // Turn on
        }
      });
     
      }

     

    Mekaniske brytere åpner og lukker seg ikke helt nøyaktig men "spretter" et bittelite øyeblikk. Mikroprosessoren er imidlertid rask nok til å lese dette flere hundre ganger så dersom vi ikke legger på noen kode for fikse det vil vi sende VELDIG MANGE MQTT meldinger.
    Koden vi legger på kalles "debounce" kode og fungerer ved å måle tiden på hvor lenge bryteren var vært i den stillingen etter at den sist endret seg. Det kommer en egen mini-guide senere om debounce prinsipper.

     

    Start opp MQTT Brokeren og MQTT Exploreren og overfør dette programmet til ESP32'en

     

    image.png

     

    Om du kortslutter mellom GND og GPIO_13 ser du at det går en melding:

     

    image.png

     

    Vi har nå et program som både mottar og sender MQTT meldinger 🙂 

     

    Og vi kan følge med i Serial Monitor så lenge den er koblet til PCen:

     

    image.png

     

    Følg med!
    Jeg skal forsøke å legge ut en liten "LEGO kloss" med (u)jevne mellomrom 🙂

     

    Brukertilbakemelding

    Anbefalte kommentarer

    Har hatt et par ESP32 gående en ukes tid med program basert på denne malen og de har så langt vært mer stabile enn andre ESP32/MQTT varianter jeg har laget tidligere, ingen stopp enda.

     

    Er der LWT funksjon (Last Will and Testament) innebygget i biblioteket og hvordan settes evt. denne opp?

     

    Jeg har en "uptime" teller som oppdateres til MQTT hvert 10 sekund så jeg vil jo se om ESPen sovner inn/mister nett...

    Lenke til kommentar
    Del på andre sider

    stigvi skrev (3 timer siden):

    Med tanke på hvor ekstremt mye en får i esphome og hvor enkel denne er å bruke, er det litt interessant å høre hvorfor dere ikke velger å bruke den?

    Når en først har valgt bort Home Assistant så virker det lite logisk innføre noe som ser veldig Home Assistant ut...

    Lenke til kommentar
    Del på andre sider

    SveinHa skrev (9 timer siden):

    Når en først har valgt bort Home Assistant så virker det lite logisk innføre noe som ser veldig Home Assistant ut...

    Esphome er universell og støtter mqtt. Den har støtte for å sende data til HA i et mer effektivt binær format, men som de skriver, bruker en noe annet enn HA og vil bruke mqtt så slår en av denne muligheten for å sende i binærformat.

    https://esphome.io/components/mqtt.html?highlight=mqtt

    Lenke til kommentar
    Del på andre sider

    Jeg tenkte mer på at når en ikke liker måten HA er bygget opp og programmeres på så innfører en ikke andre dingser som som programmeres som HA. Det jeg har sett av HA og esphome så ser de veldig like ut...

    Lenke til kommentar
    Del på andre sider

    SveinHa skrev (7 minutter siden):

    Jeg tenkte mer på at når en ikke liker måten HA er bygget opp og programmeres på så innfører en ikke andre dingser som som programmeres som HA. Det jeg har sett av HA og esphome så ser de veldig like ut...

    Ok, grei nok forklaring selv om jeg ikke helt er med på at C kode er så mye lettere å skrive enn yaml på et høyere nivå. Og da spesielt ikke når esphome har så mange ferdig lagde komponenter.

    Lenke til kommentar
    Del på andre sider

    SveinHa skrev (På 27.1.2024 den 13.36):

    Er der LWT funksjon (Last Will and Testament) innebygget i biblioteket og hvordan settes evt. denne opp?


    Ja det er det. Skal se om jeg kan grave det fram om litt

    stigvi skrev (På 27.1.2024 den 19.38):

    Med tanke på hvor ekstremt mye en får i esphome og hvor enkel denne er å bruke, er det litt interessant å høre hvorfor dere ikke velger å bruke den?


    Bra spørsmål. Når det gjelder meg personlig; se mitt svar under artikkel "0" 🙂

    Lenke til kommentar
    Del på andre sider

    Fermate skrev (5 minutter siden):

    Ja det er det.

    Fant litt om LWT og la inn dette:

    top = baseTopic;
    top += "LWT";
    char messageLWT[] = "Offline";
    void enableLastWillMessage(const char* top, const char* messageLWT, const bool retain = false);

    ...men det virker ikke. Har ikke lagt stort mer arbeid i det enn å få kompilatoren til å svelge det... 

    Lenke til kommentar
    Del på andre sider

    SveinHa skrev (På 31.1.2024 den 16.24):
    void enableLastWillMessage(const char* top, const char* messageLWT, const bool retain = false);


    Må ikke retain flagget være TRUE?

    Lenke til kommentar
    Del på andre sider

    Fermate skrev (22 minutter siden):


    Må ikke retain flagget være TRUE?

    Mye mulig men får ikke liv likevel. Eksempelet er plukket fra nett og der var ikke stort beskrivelse av parametre...

    Lenke til kommentar
    Del på andre sider

    @SveinHa Her er et eksempel som virker:

    Jeg trodde meldingen skulle komme 60 sek ( setKeepAlive(60)) etter at power forsvant men det er visst ikke helt sånn. Noen steder står det KeepAliveTime * 1,5 men jeg målte 30 sek noen ganger også.
    Si ifra om du finner ut logikken. Har testet både med og uten retain = true.

     

    Sitat
    #include <EspMQTTClient.h>
     
    #define ONBOARD_LED 2 // Onboard LED
     
    //MQTT
    EspMQTTClient MQTTclient(
      "ThePromisedLAN", // SSID
      "Hallelujah!", // WiFi Password
      "192.168.1.2",  // MQTT Broker server ip
      "",   // MQTTUsername Can be omitted if not needed
      "",   // MQTTPassword Can be omitted if not needed
      "LWTTestClient",     // Client name that uniquely identify your device
      1883              // The MQTT port, default to 1883. this line can be omitted
    );
     
    // *********************************************************************
    void setup() {
     
      // Set pin mode for test LED
      pinMode(ONBOARD_LED,OUTPUT);
      digitalWrite(ONBOARD_LED,HIGH);
     
      // MQTTclient.setKeepAlive();
      MQTTclient.setKeepAlive(60);
      MQTTclient.enableLastWillMessage("LWTTestClient/lastwill","ByeBye");
    }
     
    // *********************************************************************
    void loop() {
        MQTTclient.loop();
     
        // Onboard LED Status
        if (MQTTclient.isMqttConnected()) {
         digitalWrite(ONBOARD_LED,LOW);
        } else {
         digitalWrite(ONBOARD_LED,HIGH);
        }
     
      }
     
    // ********************** SUBS ***********************************************
    void onConnectionEstablished()
     {
     Serial.println("onConnectionEstablished");
     MQTTclient.publish("LWTTestClient/status", "started"); // You can activate the retain flag by setting the third parameter to true  
      }


     

     

    Fra MQTT Esplorer:

     

    image.png

     

    Lenke til kommentar
    Del på andre sider

    Den virker fint som i eksempelet men ikke med mine variabler så der må jeg forske litt til...

     

    Vedr retain = true vs false så plukket jeg denne fra et kommentarfelt:

    Sitat

    The difference between that setting the retained flag to true ist hat the message will be stored on the topic and any client that connects to the broker and subscribes to that topic will immediately receive the message. A typical use case is to have topic like {clientID}/status that has the online status of the client retained. A newly connecting client can now subscribe to that topic and find out the online status of the client.

    Så "retain=true" virker som på alle andre MQTT-meldinger: Når nye abonnenter kobler seg til vil de få eksisterende LWT melding tilsendt umiddelbart men ved "retain=false" sendes den bare til eksisterende abonnenter og nye blir værende uinformert.

     

    En eller annen plass i loopen bør der være noe sånt som:

    MQTTclient.publish("LWTTestClient/lastwill","Online");

    for å nullstille LWT når enheten er oppegående igjen.

    Lenke til kommentar
    Del på andre sider

     

    SveinHa skrev (19 minutter siden):

    En eller annen plass i loopen bør der være noe sånt som:


    Hva med å bruke samme som status og la LWT overskrive den?

     

    ---

      MQTTclient.enableLastWillMessage("OTATestClient/status","OffLine");
     
    ---
     
    void onConnectionEstablished()
     {
     Serial.println("onConnectionEstablished");
     MQTTclient.publish("OTATestClient/status", "OnLIne"); 
      }
    • Like 1
    Lenke til kommentar
    Del på andre sider

    SveinHa skrev (På 27.1.2024 den 13.36):

    Har hatt et par ESP32 gående en ukes tid med program basert på denne malen og de har så langt vært mer stabile enn andre ESP32/MQTT varianter jeg har laget tidligere, ingen stopp enda.

    Ser veldig bra ut. Her er "Uptime" historikken (timer oppetid siden sist restart) fra noen ESP32 med "ny" MQTT (gul penn er skjult bak grønn) og en gammel (TR1):

    image.png.401b9e71b15703431dcd356a47f74bfc.png

     

    TR1 bruker disse bibliotekene:

     

    #include <Adafruit_SleepyDog.h>
    #include <PubSubClient.h>
    //#include <WiFi.h> //ESP32
    #include <WiFiNINA.h> //Arduino

     

    Lenke til kommentar
    Del på andre sider



    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.