The firmware was developed in C in Visual Studio. At first we used Arduino Studio for flashing, but later on, we discovered Arduino IDE extension for Visual Studio, which lets you write code and flash it in the same environment. It also has an inbuilt system for installing libraries that are needed to add support for sensors, MQTT etc. You can also set all kinds of settings like board type, firmware upload speed, clock rate etc.
Writing the firmware was a challenging process. First of all, flashing new firmware on a cheap ESP8266 development board is not reliable and sometimes results in bricking the board and making it unusable. It happens quite often even with all the correct settings. And if you chose the wrong settings to break the board is even more likely. It would be very helpful to have an easy process to reset the onboard memory of ESP8266, but unfortunately, when something goes wrong during flashing, the memory cannot be erased and while the device can show signs of life, all you get in the development console is garbage instead of readable output.
Getting messages from Azure wasn’t easy either. The main problem was to find a time window when the device is ready to accept a message, even when the device is powered on. In deep sleep, it obviously can't receive messages.
Our devices work like this:
- wake up;
- connect to WiFi;
- get data from the sensor;
- send data to Azure over MQTT;
- start 30-second countdown;
- be ready to receive messages;
- wait for the countdown to be over;
- go to sleep.
So the device does not accept messages over all of the time when it is powered-on. There're a few seconds when it’s busy getting and sending data.
A queue of messages for a device would be a perfect solution, but there is no easy way to implement it because that’s just not the way MQTT is designed. So the messages to the devices are sent a few seconds after receiving a power-on event. Luckily that fits our needs as our only messages to devices contain instructions to switch topic and are designed to be sent after getting data from the device.
If we wanted the devices to be able to receive messages at any time, we would have to keep them always on, which would increase the power consumption.