Software for Building IoT Devices
Generation 1: PubSubClient, ESP8266Client, ITEADLIB Arduino WeeESP8266
This is the stack I used first, and for quite some time:
- MQTT client: PubSubClient. Regarding the data connection it is based on the standard Arduino Client interface.
- Client: ESP8266Client: This is a library I wrote that provides a Client facade to the ITEADLIB Arduino WeeESP8266 lib. It deals with ESP8266 misbehavior that can't be handled on the ESP8266 level itself (like, lost TCP or WLAN connectivity).
- ESP8266: ITEADLIB Arduino WeeESP8266. This library is quite voluminous (in example, because of the use of String) and has a few small bugs
Generation 2: AC_MQTT & AC_ESP8266
After dealing with various problems and repairing and optimizing things to a degree I finally did what all programmers must do at some point: rewrite the whole damn thing :-)
- MQTT client: AC_MQTT. Compact and easy to understand code implementing MQTT operation for QoS levels 0 and 1. Does not reserve buffers and performs only streaming read and write operations.
- "Client": AC_ESP8266Client. This is NOT the Arduino standard Client interface, but a tighter integration between AC_MQTT and AC_ESP8266. While it would have been nice to stick to the Arduino Client interface I found this requires too much of a compromise in terms of excessive memory use and type of access ("Client" is rather serial while the ESP8266 expects reading and writing buffers). It deals with all kinds of problems like WLAN and TCP connection troubles and general ESP8266 misbehavior. Depending on the hardware provided it can even hardware-reset or power-cycle the ESP8266 if necessary. It can even power-cycle a router if so required (yes, sometimes a mobile Internet router deserves and profits from a kick).
- ESP8266: AC_ESP8266. The library only provides access to ESP functions that are needed for MQTT communications. The code is pretty compact as it does not reserve buffers on its own (though it relies on buffers provided by clients). It provides a callback interface in case some data arrived over an IP connection (no need to poll).
My stack does quite a bit more than the stack above regarding error handling, and it does so with less flash and SRAM memory usage while IMHO being more readable at the same time.
Generation 3: AC_IoT, AC_MQTT, AC_TCP_ESP8266, AC_ESP8266
And while the generation 2 solution was not bad per se I wanted more.
I found that I wanted to deploy multiple devices of the same kind, but without having to change the configuration in multiple files. And I would like to simply plug in capabilities like measuring temperature or switching a relay. From an architectural standpoint, I prefer MQTT to interface with TCP, not with the ESP8266. As buffers are limited and awkward to handle (make them too big and memory is gone; make them too small and you'll get overruns), streaming is the preferred mode of data exchange. I want my code to be readable by humans. And, yes, this can be done. Even in the limited Arduino environment.
Follow me to the detailed description.