Asynchronous ESP8266 based WiFi Communication with MQTT

Project:

To implement 30+ controlled portable lighting displays in an area where not all displays can communicate with each other, or a central router.

Initial effort:

Implemented standard ESP8266 WiFi in conjunction with the MQTT PubSubClient library on the ESP8266’s. Also setup an Android phone as a WiFi hotspot, an MQTT Broker as well as an MQTT Control Panel.

This worked reasonable well in controlled conditions, except that some of the displays sporadically would not respond to an immediate command. For instance, 9 displays were setup and connected to the Android. The control panel was configured with a ‘reboot’ command. They would ALL reboot at the same time about 10% of the time. As a result, this made synchronization of these displays challenging at best.

In the field, I brought 20 MQTT enabled displays, again spread out over a limited area. Not all of them were controllable, which turned out to be the fact that Android only supported up to 10 remote WiFi devices. This was rectified by purchasing a small WiFi router.

Despite having spent considerable effort in writing and testing non-blocking characteristics in my Arduino programs, in a later exhibition, the displays still stuttered and halted when my phone, operating as an MQTT broker travelled in and out of range of the router’s WiFi network.

Challenge:

To create a program that allows displays to be continuous during WiFi and MQTT connect/disconnect/reconnect.

Issues:

  • All ‘WiFi’ repeaters use STA/AP mode and thus don’t ‘boost’ a WiFi signal, but rather act as a WiFi NAT router.
  • The MQTT functionality MUST be non-blocking during connect/disconnect/reconnect.
  • The router’s WiFi will not be able to cover the entire geographic area of the displays.

Reddit Suggestions to this problem:

From this request:

https://old.reddit.com/r/esp8266/comments/dirozo/looking_for_nonblocking_preferably_mqtt_library/

  • Implement a mesh network.
  • Install a centralized MQTT broker (on ESP32 or Raspi).
  • Use additional ESP8266’s in the mesh to bridge between geographic areas.
  • Implement ESP8266 WiFi repeater. Note: Not applicable as it’s actually a NAT router.
  • Implement wled. Note: Looked into this and it’s big. Not sure it covers my reliability use case.
  • Implement async MQTT library.
  • Use LoRa

Libraries to Review (sorted by top priority):

Async MQTT Client

This has ESPAsyncTCP as a pre-requisite library, so there’s a bit involved here. Anyways, once I installed the libraries, added the credentials and figured out how to add a username/password as MQTT credentials, I then calculated the time difference between loop iterations and then connected/disconnected/reconnected to both the WiFi as well as MQTT.

There was no measured difference, and it never went over 1mS from what I could tell.

This library covers asynchronous communications flawlessly, however it doesn’t address increasing the wifi range with a mesh or signal boosting.

ESP8266MQTTMesh

Apparently, this library now uses the ESPAsync libraries above, so this might be a great solution . . . This was tested briefly, however I abandoned it as too complex.

WiFi Range Extension

This caused me more challenge than I’d hoped. First off, the USB wifi extenders were not easy to program because packets kept on getting dropped by them.

Then, I was not able to ping devices between the router and the extenders. Testing eventually revealed that I needed to connect the LAN cable. A loopback with a static IP address worked.

Finally, the extenders didn’t work after the router rebooted. After yet more testing, I was able to DHCP reserve IP addresses for them and FINALLY range extension worked.

Conclusion

Between WiFi range extension, the Async MQTT Client and adding:

#define FASTLED_ALLOW_INTERRUPTS 0

to the code, I think we may have non-blocking WiFi and MQTT with QoS support for FastLED animations. A lot more testing to go and it’s been a difficult journey.

Comments are closed.