Definities voor de NodeState.
In de vorige aflevering hebben we een klein actuator-project gerealiseerd, waarmee we een LED op afstand konden schakelen via MQTT. Ter herinnering: Onze hardware, het Pretzel-Board, is uitgerust met een WLAN-chip van het type ESP8266, die door een ATmega328 wordt bestuurd met behulp van AT-commando’s. Op de ATmega draait Arduino-software, die we in de afgelopen delen stap voor stap hebben ontwikkeld. Daarbij horen een kleine TCP/IP-bibliotheek en een rudimentaire MQTT-library voor het samenstellen van de berichten voor de MQTT-testbroker (zie MQTT-specificatie). De communicatie begint met een CONNECT-aanvraag; we controleren daarna, of de testbroker antwoordt met de vastgelegde CONNACK-bytes. Daarna sturen we om de 15 s de zogenaamde PINGREQ-bytes. Ook die worden door de testserver beantwoord met een vastgelegde reeks van bytes (PINGRESP). Hij weet dan, dat de verbinding met de client open staat. Verder hebben we ons met SUBSCRIBE geabonneerd op het topic „/ElektorMyJourneyIoT/TestTopic/test“ om berichten van de besturende client (die we hebben gerealiseerd als PC-software) te ontvangen en de LED te schakelen. En we sturen onder het topic „…/TestTopicBack/…“ nog PUBLISH-berichten uit als terugmelding, wanneer een commando is uitgevoerd.

So far, so good. Maar af en toe wordt de verbinding van de actuator-kaart met de MQTT-testserver ergens in het Internet verbroken. We kunnen dat detecteren, omdat een PINGREQ dan niet meer wordt beantwoord. In het vorige deel hebben we in die situatie gewoon de rode LED ingeschakeld. Met een druk op de knop kon de gebruiker er dan voor zorgen, dat de actuator-client zich opnieuw aanmeldde bij de testserver en zich op het genoemde topic abonneerde.

Die manier van werken is natuurlijk niet erg bruikbaar in de praktijk, als de actuator ergens „in het veld “ is ondergebracht. Als we aan de kant van de besturende MQTT-client vaststellen, dat de terugmeldingen uitblijven, dan moeten we in actie komen en de actuator-kaart opnieuw „op scherp zetten“. Enzovoort, enzovoort.

Maar opnieuw verbinding maken is heel goed te automatiseren; in de Arduino-software uit de vorige aflevering zitten al alle functies die we daarvoor nodig hebben. Als u de nieuwe sketch (download onderaan de pagina) vergelijkt met de sketch uit de vorige aflevering, kunt u meteen zien, wat ik dit keer heb verbeterd.

MQTT state machine

Ik heb een paar definities voor een „NodeState“ ingevoegd (zie screenshot). Positieve numerieke waarden staan voor de normale verwerking, 0 en negatieve waarden duiden op een fout. De functies voor het maken van de verbinding en het abonneren op het topic (ConnectAndSubscribeToTopic()) en voor het verzenden van de pings (SendPingRequestToBroker()) schakelen nu bij het optreden van een fout niet alleen de rode LED in, maar geven ook een negatieve waarde terug naar de hoofdlus. Daar is een kleine state machine gerealiseerd. Aan de hand van de teruggegeven waarde wordt een variabele MQTTClient_Connected ingevuld, die maar twee toestanden kent: Namelijk true als de poging om een verbinding te maken en later te pingen succesvol waren en de verbinding (nog) bestaat en false, als er een fout is opgetreden. In het eerste geval gedraagt de kaart zich net als in de vorige aflevering: Er wordt regelmatig een ping uitgestuurd en geluisterd naar de schakelcommando’s die binnenkomen via MQTT. Bij het ontvangen van een commando wordt de actuator in de juiste toestand geschakeld en wordt via MQTT een terugmelding gepubliceerd.
Maar als MQTTClient_Connected == false, dan wordt met de functie ConnectAndSubscribeToTopic() opnieuw geprobeerd om een verbinding te maken. MQTTClient_Connected is trouwens ook bij het begin van het programma op false gezet, zodat de eerste poging om een verbinding te maken meteen na het inloggen op het WLAN-netwerk wordt uitgevoerd en niet pas als de gebruiker op de druktoets drukt. Maar door op de knop te drukken kan de gebruiker nog steeds een nieuwe verbinding laten maken.

Statusmeldungen via MQTT

Omdat er nu zoveel automatisch gaat, geeft de kaart ook statusmeldingen, lokaal via de seriële interface (dat helpt bij de installatie het veld) en ook via MQTT (op hetzelfde topic als de actuator-terugmeldingen). Omdat we bij het optreden van een fout natuurlijk geen statusmeldingen via MQTT kunnen verzenden, wordt de fout tussentijds opgeslagen in de variabele NodeStateLog en wordt de melding pas uitgestuurd, als er weer verbinding is. Bij de statusmeldingen staan „S1“ v/m „S3“ voor normale* werking en „E0“ t/m „E4“ voor fout.

Probeer het maar eens uit; de setup is hetzelfde als bij de vorige aflevering. Naast de Arduino-code, waar u zoals altijd eerst de SSID en het wachtwoord van uw WLAN-netwerk moet invoeren, is ook de MQTT-client voor de PC in de download te vinden. De actuator-kaart werkt nu voor langere tijd zonder ingrepen van buitenaf; we kunnen in de seriële uitvoer zien, dat de verbinding van tijd tot tijd automatisch opnieuw wordt gemaakt (bij de PC-client kan het af en toe nog nodig zijn om opnieuw te starten). De onbetrouwbare verbinding wordt mede veroorzaakt, doordat we (nog) werken met een heel onbetrouwbare, openbaar toegankelijke testbroker.

Er is nog veel te doen; in de volgende delen gaan we verder!