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
VIDEO
==參考資料== 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基本程式庫原始程式:
/** * Arduino code base for IoT Projects * By: Stonez56 aka Kevin Chen 2022-08-16 * * This source code combined three most common Arduino libraries for IoT Projects, * ESPAsync_Wifimanager, AsyncElegantOTA, & Pubsubclient MQTT Client. * * 1. ESPAsync_WiFiManager: https://github.com/khoih-prog/ESPAsync_WiFiManager * 2. AsyncElegantOTA: https://github.com/ayushsharma82/AsyncElegantOTA * 3. Pubsubclient MQTT Client: https://github.com/knolleary/pubsubclient * * YouTube video: https://youtu.be/giFHp9RSMvQ * Source code is available my blog: https://stonez56.blogspot.com/2022/08/android-36-iot-wifimanager-fota-mqtt.html **/ /* * Define Relay pins as examples to send/receive MQTT messages * **/ #define RELAY_PIN_1 12 #define RELAY_PIN_2 14 /** * Perform OTAs for ESP8266 / ESP32 Elegantly with password protection! * https://github.com/ayushsharma82/AsyncElegantOTA * **/ #include <AsyncElegantOTA.h> const char * FOTA_USERNAME = "un" ; const char * FOTA_PASSWORD = "pw" ; /** * Add MQTT client here` PubSubClient V2.8 by Nick O'Leary * https://github.com/knolleary/pubsubclient */ #include <WiFiClient.h> #include <PubSubClient.h> #define MSG_BUFFER_SIZE ( 1024 ) char msg [ MSG_BUFFER_SIZE ]; /** Taiwan No. 1 Free MQTT Server!! **/ const char * mqtt_server = "mqttgo.io" ; const int mqtt_port = 1883 ; /**************************************************************************************************************************** Async_AutoConnect_ESP32_minimal.ino For ESP8266 / ESP32 boards Built by Khoi Hoang https://github.com/khoih-prog/ESPAsync_WiFiManager Licensed under MIT license *****************************************************************************************************************************/ #if !(defined(ESP32)) #error This code is intended to run on the ESP32 platform ! Please check your Tools -> Board setting . #endif #include <ESPAsync_WiFiManager.h> AsyncWebServer webServer ( 80 ); //Start DNS server DNSServer dnsServer ; //MQTT - Start WiFi client and connect to MQTT server WiFiClient espClient ; PubSubClient mqtt_client ( espClient ); //Define device name String DEVICE_NAME = "Dual_Relay_Switch" ; String home_page_message = "" ; void setup () { Serial . begin ( 115200 ); pinMode ( RELAY_PIN_1 , OUTPUT ); pinMode ( RELAY_PIN_2 , OUTPUT ); while (! Serial ) ; delay ( 200 ); Serial . print ( "\nAsyncWifimanager started on " + String ( ARDUINO_BOARD ) + "\n" ); //Initialize ESPAsyncWifimanager instance and assign Wi-Fi Client name "AsyncAutoConnect"! //This name and IP address can be checked from the router ESPAsync_WiFiManager ESPAsync_wifiManager (& webServer , & dnsServer , "Dual_Relay_Switch" ); //####### RESET SAVED WIFI SETTINGS ############# //ESPAsync_wifiManager.resetSettings(); //ESPAsync_wifiManager.setAPStaticIPConfig(IPAddress(192, 168, 132, 1), IPAddress(192, 168, 132, 1), IPAddress(255, 255, 255, 0)); //ESPAsync_wifiManager.autoConnect("Stonez_ESP32S", "AP-NAME", "AP-PASSWORD"); ESPAsync_wifiManager . autoConnect ( "Dual_Switch_ESP32S" ); if ( WiFi . status () == WL_CONNECTED ) { Serial . print ( DEVICE_NAME ); Serial . print ( " is on Local IP: " ); Serial . println ( WiFi . localIP ()); } else { Serial . println ( ESPAsync_wifiManager . getStatus ( WiFi . status ())); } //Setup home page access content when visite home_page_message = "<!DOCTYPE html><html><head><title>" + DEVICE_NAME + "</title></head><body><p><h2> Hi! This is " + DEVICE_NAME + "</h2>" + "To update firmware, <a href='/update'>Click here!!</a><br/><span>Username & Password required!</span></p><body></html>" ; webServer . on ( "/" , HTTP_GET , []( AsyncWebServerRequest * request ) { request -> send ( 200 , "text/html" , home_page_message ); }); //AsyncElegantOTA.begin(&webServer); // Start ElegantOTA WITHOUT username & password AsyncElegantOTA . begin (& webServer , FOTA_USERNAME , FOTA_PASSWORD ); // Start ElegantOTA with username & password webServer . begin (); Serial . println ( "AsyncElegantOTA server started @URL/update" ); //MQTT starts here! mqtt_client . setServer ( mqtt_server , mqtt_port ); mqtt_client . setCallback ( callback ); } /** //When MQTT lost connection, this function will be called to reconnect MQTT// * Modified to accept multiple MQTT topics * https://www.baldengineer.com/multiple-mqtt-topics-pubsubclient.html */ void callback ( char * topic , byte * payload , unsigned int length ) { //Print message received Serial . print ( "Message arrived [" ); Serial . print ( topic ); Serial . print ( "] " ); for ( int i = 0 ; i < length ; i ++) { Serial . print (( char ) payload [ i ]); } Serial . println (); //Process multiple topics here// payload [ length ] = '\0' ; String message = ( char *) payload ; if ( strcmp ( topic , "studio/humd_switch" ) == 0 ) { if ( message == "true" ){ digitalWrite ( RELAY_PIN_1 , HIGH ); Serial . println ( "humd_switch true" ); } if ( message == "false" ){ digitalWrite ( RELAY_PIN_1 , LOW ); Serial . println ( "humd_switch false" ); } } if ( strcmp ( topic , "studio/humd_switch2" ) == 0 ) { if ( message == "true" ){ digitalWrite ( RELAY_PIN_2 , HIGH ); Serial . println ( "humd_switch2 true" ); } if ( message == "false" ){ digitalWrite ( RELAY_PIN_2 , LOW ); Serial . println ( "humd_switch2 false" ); } } } //============= MQTT =================== //When MQTT lost connection, this function will be called to reconnect MQTT// void reconnect (){ //Loop while MQTT connected while (! mqtt_client . connected ()) { Serial . print ( "Attempting MQTT connection... " ); // Create a random client ID String clientId = "Stonez_ESP32Client-" ; clientId += String ( random ( 0xffff ), HEX ); // Attempt to connect if ( mqtt_client . connect ( clientId . c_str ())) { Serial . print ( "connected to " ); Serial . print ( mqtt_server ); // Once connected, publish an announcement... mqtt_client . publish ( "outTopic" , "Hello world" ); // ... and resubscribe mqtt_client . subscribe ( "studio/humd_switch" ); mqtt_client . subscribe ( "studio/humd_switch2" ); } else { Serial . print ( "failed, rc=" ); Serial . print ( mqtt_client . state ()); Serial . println ( " try again in 5 seconds" ); // Wait 5 seconds before retrying delay ( 5000 ); } } } void loop () { //============= MQTT =================== //if can't connect to MQTT server, then re-connect if (! mqtt_client . connected ()) { reconnect (); } //constantly check MQTT to see for messages sending/receiving mqtt_client . loop (); /** * Write your own code here.... * */ }
Async_AutoConnect_ESP32_minimal.ino
/**************************************************************************************************************************** Async_AutoConnect_ESP32_minimal.ino For ESP8266 / ESP32 boards Built by Khoi Hoang https://github.com/khoih-prog/ESPAsync_WiFiManager Licensed under MIT license *****************************************************************************************************************************/ #if !(defined(ESP32) ) #error This code is intended to run on the ESP32 platform ! Please check your Tools -> Board setting . #endif #include <ESPAsync_WiFiManager.h> //https://github.com/khoih-prog/ESPAsync_WiFiManager AsyncWebServer webServer ( 80 ); DNSServer dnsServer ; void setup () { // put your setup code here, to run once: Serial . begin ( 115200 ); while (! Serial ); delay ( 200 ); Serial . print ( "\nStarting Async_AutoConnect_ESP32_minimal on " + String ( ARDUINO_BOARD )); Serial . println ( ESP_ASYNC_WIFIMANAGER_VERSION ); ESPAsync_WiFiManager ESPAsync_wifiManager (& webServer , & dnsServer , "AutoConnectAP" ); //ESPAsync_wifiManager.resetSettings(); //reset saved settings ESPAsync_wifiManager . setAPStaticIPConfig ( IPAddress ( 192 , 168 , 132 , 1 ), IPAddress ( 192 , 168 , 132 , 1 ), IPAddress ( 255 , 255 , 255 , 0 )); ESPAsync_wifiManager . autoConnect ( "AutoConnectAP" ); if ( WiFi . status () == WL_CONNECTED ) { Serial . print ( F ( "Connected. Local IP: " )); Serial . println ( WiFi . localIP ()); } else { Serial . println ( ESPAsync_wifiManager . getStatus ( WiFi . status ())); } } void loop () { }
Async_AutoConnect_ESP8266_minimal.ino
/**************************************************************************************************************************** Async_AutoConnect_ESP8266_minimal.ino For ESP8266 / ESP32 boards Built by Khoi Hoang https://github.com/khoih-prog/ESPAsync_WiFiManager Licensed under MIT license *****************************************************************************************************************************/ #if !( defined(ESP8266) ) #error This code is intended to run on ESP8266 platform ! Please check your Tools -> Board setting . #endif #include <ESPAsync_WiFiManager.h> //https://github.com/khoih-prog/ESPAsync_WiFiManager AsyncWebServer webServer ( 80 ); DNSServer dnsServer ; void setup () { // put your setup code here, to run once: Serial . begin ( 115200 ); while (! Serial ); delay ( 200 ); Serial . print ( "\nStarting Async_AutoConnect_ESP8266_minimal on " + String ( ARDUINO_BOARD )); Serial . println ( ESP_ASYNC_WIFIMANAGER_VERSION ); ESPAsync_WiFiManager ESPAsync_wifiManager (& webServer , & dnsServer , "AutoConnectAP" ); //ESPAsync_wifiManager.resetSettings(); //reset saved settings //ESPAsync_wifiManager.setAPStaticIPConfig(IPAddress(192,168,186,1), IPAddress(192,168,186,1), IPAddress(255,255,255,0)); ESPAsync_wifiManager . autoConnect ( "AutoConnectAP" ); if ( WiFi . status () == WL_CONNECTED ) { Serial . print ( F ( "Connected. Local IP: " )); Serial . println ( WiFi . localIP ()); } else { Serial . println ( ESPAsync_wifiManager . getStatus ( WiFi . status ())); } } void loop () { }