2022/08/14

Android #36 IoT 基本程式庫 Wifimanager FOTA MQTT (IOT Essential Code base with wifimanager, ElegantOTA, & MQTT)

Hi, Welcome to weekend project with Stonez56

This week's Arduino episode #37, "Essential IoT Code Base- Wifimanager FOTA + MQTT"

Here is the source code: https://stonez56.blogspot.com/2022/08/android-36-iot-wifimanager-fota-mqtt.html 


Today, I will show how to combine three commonly used IoT libraries;

WiFimanager, AsyncElegantOTA, and MQTT To become a common IoT code base. So, for our future projects, ESP8266 or ESP32, would have these basic functions.

Let's first look at these three libraries:

  • Wifimanager = Wi-Fi password management, no need to re-burn the code to change the Wi-Fi SSID & password
  • FOTA = Use Wi-Fi to update ESP32 code, you can burn code without connecting to USB
  • MQTT = Streamlined and lightweight communication protocol (Message Queueing Telemetry Transport)


This episode will only introduce how to integrate MQTT into Wifimanager + AsyncElegantFOTA.

To learn how to start Wifimanager + AsyncElegantOTA, Please watch Android #27 Wifimanager + OTA for ESP32/ESP8266 (ESPAsyncWifimanager / ESPAsyncElegantOTA)) https://youtu.be/UlRLTvl4DRc 


==References==

Arduino Library URL:


==Sample code URL==

ESPAsync_WiFiManager minimal: https://github.com/khoih-prog/ESPAsync_WiFiManager/blob/master/examples/Async_AutoConnect_ESP32_minimal/Async_AutoConnect_ESP32_minimal.ino 


ESP32 Async OTA : https://github.com/ayushsharma82/AsyncElegantOTA/blob/master/examples/ESP32_Async_Demo/ESP32_Async_Demo.ino 


If you don't have enough time, you can also select the part you want to watch from the timeline below!

Video Timeline: 00:00 Start 01:39 Demonstration of project results 01:57 mqttgo.io MQTT server, free, fast, & stable 05:52 Install three libraries 07:14 Added two ESP32 PINs as MQTT example 07:41 Encrypt the firmware update (ElegantOTA) page 11:44 Explain how the MQTT callback function works 13:07 Control ESP32 I/O pins with MQTT 15:16 Future program can be written from here

=====中文版本======

大家好, 歡迎收看本週的Weekend project with Stonez56。 

本周要進行的是 Arduino 第36集,"IoT 基本程式庫 - Wifimanager FOTA + MQTT”

今天來跟大家介紹如何把 一般的 IoT 專案常用到的三個程式庫,  WiFiManager 以及WiFi 韌體更新FOTA (Firmware Over the Air), 再加上 MQTT 三個整合在一起, 變成一個常用的 Code base.  往後你的 ESP32 IoT 專案呢, 就可以俱備這些基本功能了! 


  • Wifimanager = WiFi 密碼管理, 不用重新燒 Code 改 Wifi SSID & 密碼
  • FOTA = 用Wi-Fi更新ESP32程式碼, 不用接USB就可以燒Code
  • MQTT = 精簡輕量化的通訊協定(Message Queueing Telemetry Transport)


本集僅會介紹如何把 MQTT 整合到 Wifimanager + AsyncElegantFOTA

若想了解如何整合 Wifimanager + AsyncElegantOTA, 

請觀看 Arduino #26 AsyncWifimanager ElegantOTA ESP32 (WiFi 密碼管理+ WiFi 韌體更新) https://youtu.be/zepkinJ46Zg  




==參考資料==

Arduino Library URL: 


==Sample code URL==


如果時間不夠的朋友, 也可以從以下的時間軸挑選想看的部份即可! 

影片時間軸:

影片時間軸: 00:00 Start 01:39 專案成果示範 01:57 mqttgo.io 快速免費的 MQTT 伺服器 05:52 安裝三支程式庫 07:14 加入兩個 ESP32 PIN做為MQTT範例 07:41 為韌體更新(ElegantOTA)頁面加密 11:44 說明MQTT callback 函數運作方式 13:07 MQTT由此控制ESP32 PIN 15:16 把你的程式可以寫在這裡


IoT基本程式庫原始程式:


  1. /**
  2. * Arduino code base for IoT Projects
  3. * By: Stonez56 aka Kevin Chen 2022-08-16
  4. *
  5. * This source code combined three most common Arduino libraries for IoT Projects,
  6. * ESPAsync_Wifimanager, AsyncElegantOTA, & Pubsubclient MQTT Client.
  7. *
  8. * 1. ESPAsync_WiFiManager: https://github.com/khoih-prog/ESPAsync_WiFiManager
  9. * 2. AsyncElegantOTA: https://github.com/ayushsharma82/AsyncElegantOTA
  10. * 3. Pubsubclient MQTT Client: https://github.com/knolleary/pubsubclient
  11. *
  12. * YouTube video: https://youtu.be/giFHp9RSMvQ
  13. * Source code is available my blog: https://stonez56.blogspot.com/2022/08/android-36-iot-wifimanager-fota-mqtt.html
  14. **/
  15.  
  16. /*
  17. * Define Relay pins as examples to send/receive MQTT messages
  18. * **/
  19. #define RELAY_PIN_1 12
  20. #define RELAY_PIN_2 14
  21.  
  22. /**
  23. * Perform OTAs for ESP8266 / ESP32 Elegantly with password protection!
  24. * https://github.com/ayushsharma82/AsyncElegantOTA
  25. * **/
  26. #include <AsyncElegantOTA.h>
  27. const char *FOTA_USERNAME = "un";
  28. const char *FOTA_PASSWORD = "pw";
  29.  
  30. /**
  31. * Add MQTT client here` PubSubClient V2.8 by Nick O'Leary
  32. * https://github.com/knolleary/pubsubclient
  33. */
  34. #include <WiFiClient.h>
  35. #include <PubSubClient.h>
  36. #define MSG_BUFFER_SIZE (1024)
  37. char msg[MSG_BUFFER_SIZE];
  38.  
  39. /** Taiwan No. 1 Free MQTT Server!! **/
  40. const char *mqtt_server = "mqttgo.io";
  41. const int mqtt_port = 1883;
  42.  
  43. /****************************************************************************************************************************
  44. Async_AutoConnect_ESP32_minimal.ino
  45. For ESP8266 / ESP32 boards
  46. Built by Khoi Hoang https://github.com/khoih-prog/ESPAsync_WiFiManager
  47. Licensed under MIT license
  48. *****************************************************************************************************************************/
  49. #if !(defined(ESP32))
  50. #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting.
  51. #endif
  52. #include <ESPAsync_WiFiManager.h>
  53. AsyncWebServer webServer(80);
  54.  
  55. //Start DNS server
  56. DNSServer dnsServer;
  57.  
  58. //MQTT - Start WiFi client and connect to MQTT server
  59. WiFiClient espClient;
  60. PubSubClient mqtt_client(espClient);
  61.  
  62. //Define device name
  63. String DEVICE_NAME = "Dual_Relay_Switch";
  64. String home_page_message = "";
  65.  
  66. void setup()
  67. {
  68. Serial.begin(115200);
  69. pinMode(RELAY_PIN_1, OUTPUT);
  70. pinMode(RELAY_PIN_2, OUTPUT);
  71.  
  72. while (!Serial)
  73. ;
  74. delay(200);
  75. Serial.print("\nAsyncWifimanager started on " + String(ARDUINO_BOARD) + "\n");
  76.  
  77. //Initialize ESPAsyncWifimanager instance and assign Wi-Fi Client name "AsyncAutoConnect"!
  78. //This name and IP address can be checked from the router
  79. ESPAsync_WiFiManager ESPAsync_wifiManager(&webServer, &dnsServer, "Dual_Relay_Switch");
  80.  
  81. //####### RESET SAVED WIFI SETTINGS #############
  82. //ESPAsync_wifiManager.resetSettings();
  83.  
  84. //ESPAsync_wifiManager.setAPStaticIPConfig(IPAddress(192, 168, 132, 1), IPAddress(192, 168, 132, 1), IPAddress(255, 255, 255, 0));
  85. //ESPAsync_wifiManager.autoConnect("Stonez_ESP32S", "AP-NAME", "AP-PASSWORD");
  86. ESPAsync_wifiManager.autoConnect("Dual_Switch_ESP32S");
  87. if (WiFi.status() == WL_CONNECTED)
  88. {
  89. Serial.print(DEVICE_NAME);
  90. Serial.print(" is on Local IP: ");
  91. Serial.println(WiFi.localIP());
  92. }
  93. else
  94. {
  95. Serial.println(ESPAsync_wifiManager.getStatus(WiFi.status()));
  96. }
  97.  
  98. //Setup home page access content when visite
  99. home_page_message = "<!DOCTYPE html><html><head><title>" + DEVICE_NAME
  100. + "</title></head><body><p><h2> Hi! This is " + DEVICE_NAME + "</h2>"
  101. + "To update firmware, <a href='/update'>Click here!!</a><br/><span>Username & Password required!</span></p><body></html>";
  102.  
  103. webServer.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
  104. { request->send(200, "text/html", home_page_message); });
  105.  
  106. //AsyncElegantOTA.begin(&webServer); // Start ElegantOTA WITHOUT username & password
  107. AsyncElegantOTA.begin(&webServer, FOTA_USERNAME, FOTA_PASSWORD); // Start ElegantOTA with username & password
  108. webServer.begin();
  109. Serial.println("AsyncElegantOTA server started @URL/update");
  110.  
  111. //MQTT starts here!
  112. mqtt_client.setServer(mqtt_server, mqtt_port);
  113. mqtt_client.setCallback(callback);
  114. }
  115.  
  116. /**
  117. //When MQTT lost connection, this function will be called to reconnect MQTT//
  118. * Modified to accept multiple MQTT topics
  119. * https://www.baldengineer.com/multiple-mqtt-topics-pubsubclient.html
  120. */
  121. void callback(char *topic, byte *payload, unsigned int length)
  122. {
  123. //Print message received
  124. Serial.print("Message arrived [");
  125. Serial.print(topic);
  126. Serial.print("] ");
  127. for (int i = 0; i < length; i++)
  128. {
  129. Serial.print((char)payload[i]);
  130. }
  131. Serial.println();
  132.  
  133. //Process multiple topics here//
  134. payload[length] = '\0';
  135. String message = (char*)payload;
  136. if (strcmp(topic, "studio/humd_switch") == 0)
  137. {
  138. if(message == "true"){
  139. digitalWrite(RELAY_PIN_1, HIGH);
  140. Serial.println("humd_switch true");
  141. }
  142. if(message == "false"){
  143. digitalWrite(RELAY_PIN_1, LOW);
  144. Serial.println("humd_switch false");
  145. }
  146. }
  147. if (strcmp(topic, "studio/humd_switch2") == 0)
  148. {
  149. if(message == "true"){
  150. digitalWrite(RELAY_PIN_2, HIGH);
  151. Serial.println("humd_switch2 true");
  152. }
  153. if(message == "false"){
  154. digitalWrite(RELAY_PIN_2, LOW);
  155. Serial.println("humd_switch2 false");
  156. }
  157. }
  158. }
  159.  
  160. //============= MQTT ===================
  161. //When MQTT lost connection, this function will be called to reconnect MQTT//
  162. void reconnect(){
  163. //Loop while MQTT connected
  164. while (!mqtt_client.connected())
  165. {
  166. Serial.print("Attempting MQTT connection... ");
  167. // Create a random client ID
  168. String clientId = "Stonez_ESP32Client-";
  169. clientId += String(random(0xffff), HEX);
  170. // Attempt to connect
  171. if (mqtt_client.connect(clientId.c_str()))
  172. {
  173. Serial.print("connected to ");
  174. Serial.print(mqtt_server);
  175. // Once connected, publish an announcement...
  176. mqtt_client.publish("outTopic", "Hello world");
  177. // ... and resubscribe
  178. mqtt_client.subscribe("studio/humd_switch");
  179. mqtt_client.subscribe("studio/humd_switch2");
  180. }
  181. else
  182. {
  183. Serial.print("failed, rc=");
  184. Serial.print(mqtt_client.state());
  185. Serial.println(" try again in 5 seconds");
  186. // Wait 5 seconds before retrying
  187. delay(5000);
  188. }
  189. }
  190. }
  191. void loop() {
  192. //============= MQTT ===================
  193. //if can't connect to MQTT server, then re-connect
  194. if (!mqtt_client.connected())
  195. { reconnect(); }
  196. //constantly check MQTT to see for messages sending/receiving
  197. mqtt_client.loop();
  198.  
  199. /**
  200. * Write your own code here....
  201. *
  202. */
  203. }

Async_AutoConnect_ESP32_minimal.ino

  1. /****************************************************************************************************************************
  2. Async_AutoConnect_ESP32_minimal.ino
  3. For ESP8266 / ESP32 boards
  4. Built by Khoi Hoang https://github.com/khoih-prog/ESPAsync_WiFiManager
  5. Licensed under MIT license
  6. *****************************************************************************************************************************/
  7. #if !(defined(ESP32) )
  8. #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting.
  9. #endif
  10. #include <ESPAsync_WiFiManager.h> //https://github.com/khoih-prog/ESPAsync_WiFiManager
  11. AsyncWebServer webServer(80);
  12. DNSServer dnsServer;
  13.  
  14. void setup()
  15. {
  16. // put your setup code here, to run once:
  17. Serial.begin(115200); while (!Serial); delay(200);
  18. Serial.print("\nStarting Async_AutoConnect_ESP32_minimal on " + String(ARDUINO_BOARD)); Serial.println(ESP_ASYNC_WIFIMANAGER_VERSION);
  19. ESPAsync_WiFiManager ESPAsync_wifiManager(&webServer, &dnsServer, "AutoConnectAP");
  20. //ESPAsync_wifiManager.resetSettings(); //reset saved settings
  21. ESPAsync_wifiManager.setAPStaticIPConfig(IPAddress(192,168,132,1), IPAddress(192,168,132,1), IPAddress(255,255,255,0));
  22. ESPAsync_wifiManager.autoConnect("AutoConnectAP");
  23. if (WiFi.status() == WL_CONNECTED) { Serial.print(F("Connected. Local IP: ")); Serial.println(WiFi.localIP()); }
  24. else { Serial.println(ESPAsync_wifiManager.getStatus(WiFi.status())); }
  25. }
  26.  
  27. void loop() { }

Async_AutoConnect_ESP8266_minimal.ino

  1. /****************************************************************************************************************************
  2. Async_AutoConnect_ESP8266_minimal.ino
  3. For ESP8266 / ESP32 boards
  4. Built by Khoi Hoang https://github.com/khoih-prog/ESPAsync_WiFiManager
  5. Licensed under MIT license
  6. *****************************************************************************************************************************/
  7. #if !( defined(ESP8266) )
  8. #error This code is intended to run on ESP8266 platform! Please check your Tools->Board setting.
  9. #endif
  10. #include <ESPAsync_WiFiManager.h> //https://github.com/khoih-prog/ESPAsync_WiFiManager
  11. AsyncWebServer webServer(80);
  12. DNSServer dnsServer;
  13.  
  14. void setup()
  15. {
  16. // put your setup code here, to run once:
  17. Serial.begin(115200); while (!Serial); delay(200);
  18. Serial.print("\nStarting Async_AutoConnect_ESP8266_minimal on " + String(ARDUINO_BOARD)); Serial.println(ESP_ASYNC_WIFIMANAGER_VERSION);
  19. ESPAsync_WiFiManager ESPAsync_wifiManager(&webServer, &dnsServer, "AutoConnectAP");
  20. //ESPAsync_wifiManager.resetSettings(); //reset saved settings
  21. //ESPAsync_wifiManager.setAPStaticIPConfig(IPAddress(192,168,186,1), IPAddress(192,168,186,1), IPAddress(255,255,255,0));
  22. ESPAsync_wifiManager.autoConnect("AutoConnectAP");
  23. if (WiFi.status() == WL_CONNECTED) { Serial.print(F("Connected. Local IP: ")); Serial.println(WiFi.localIP()); }
  24. else { Serial.println(ESPAsync_wifiManager.getStatus(WiFi.status())); }
  25. }
  26.  
  27. void loop() { }
  28.  
  29.