Definitions for the NodeState.
In the last installment, we implemented a small actuator project where we are able to switch a remote LED using MQTT. To recap, our hardware consists of a Pretzel board equipped with an ESP8266 Wi-Fi chip controlled by an ATmega328 using AT commands. We are using Arduino software which we developed step by step in previous installments. This includes a small TCP / IP library and a rudimentary MQTT library for compiling the necessary bytes which need to be sent to the MQTT test broker (see the MQTT specification). Communication begins with a CONNECT request; we then check whether the test broker responds with fixed CONNACK acknowledgement bytes. Then we send the so-called PINGREQ bytes every 15 s. The test server answers these with a fixed byte sequence (PINGRESP) and now knows that the client still has an open connection. In addition, we have subscribed to the topic "/ ElektorMyJourneyIoT / TestTopic / test" using SUBSCRIBE to receive messages from the controlling client (realized by us in PC software) and to switch the LED. Here we send out PUBLISH messages as confirmation after the topic "... / TestTopicBack / ..." when this has been done.

So far, so good - but every so often the connection from the actuator board to the MQTT test server disconnects from the network. This state can be detected when a PINGREQ no longer receives an acknowledgement. In the last episode, we indicated this by switching a red LED on. By pressing the pushbutton, the user can then ensure that the actuator client logs on to the test server again and subscribes to the topic.

The whole thing is of course not very practical, if the actuator is situated somewhere in the field. When you discover on the controller client side of the MQTT connection that acknowledgements are not being received you physically need to go out and reset the actuator board.

A reconnect can however also be initiated automatically; In the Arduino software from the last sequence, all the functions are already available. What I've improved for this installment can be seen by comparing the new sketch (download below) with the sketch from the last episode.

MQTT State Machine

I have introduced some definitions for a "NodeState" (see screenshot). Positive numbers represent normal operation, 0 and negative values ​​indicate an error. The functions for connecting and subscribing to the topic (ConnectAndSubscribeToTopic ()) and sending the ping (SendPingRequestToBroker ()) now not only switches the LED red, but also returns a negative value to the main loop. A small state machine has been implemented. Based on the returned value, a variable MQTTClient_Connected is served which only has two states: Namely true if the connection attempt and the corresponding ping were successful and the connection is (still) valid and false if an error has occurred. In the former case the board responds as in the last sequence: A ping is sent regularly and listens to switching commands sent via MQTT. When a command is received the actuator is switched accordingly and a feedback message is published via MQTT.
If, however, MQTTClient_Connected == is false, the connectionAndSubscribeToTopic () function is used to initiate a (renewed) connection attempt. MQTTClient_Connected is also set to false at the beginning of the program so that the first connection attempt occurs immediately after logging into the Wi-Fi network and not when the user first presses the button. Pressing the button again forces a reconnect.

Status messaging using MQTT

So much of this is automatic, the board also generates status messages, locally sent via the serial interface (which is useful when setting up in the field), as well as via MQTT (on the same topic as the actuator feedback). In the event of an error occurring, it is not possible to send status messages via MQTT, so the error is buffered in the NodeStateLog variable and the corresponding message is sent when the connection is restored. Status messages are "S1" to "S3" for normal operation and "E0" to "E4" for errors.

Try it out - the setup is the same as in the last episode. In addition to the Arduino code, where you always have to enter the SSID and the password of your Wi-Fi network, the MQTT client for the PC is also included in the download. The actuator board now also operates for an extended period without external intervention; you can look at the serial output to see that the connection is automatically re-established from time to time (the PC client still needs a restart now and again). I think we can put the unreliable connection down to the fact that we are (still) using a publicly accessible test broker.
There is still much to do, standby for the next installment!