1. Introduction
This tutorial is similar to Demo 34 but without using sdcard. It means firmware will be flashed to ESP directly from HTTP downloading process. Here is the model of this demo:
Refer Demo 7 to connect ESP32 pins with sdcard module. And Demo 1 to connect ESP to LED.
3. Software
I made the library in github. Just download, install it and run example esp32httpota2. Change the Wifi ssid, password and IP of MQTT server according to yours. The code will be explained below.
In order to start fota updating process, using the Python code below
and type "1" to publish FOTA command to ESP. The ESP will receive the
command, parse it and starting FOTA process. Change the url and md5 value according to yours.
The library is simple. It only has 1 interface that is start with input is DlInfo structure. When calling this function, it will block the loop() function. We must initialize the structure before using it. The structure includes:
- url: is the http url of the firmware file.
- md5: is the md5 checksum of the firmware file.
- startDownloadCallback: is the function that will be invoked before starting downloading. I left it empty in this demo.
- endDownloadCallback: is the function that will be invoked after downloading was finished. I left it empty in this demo.
- progressCallback: is the function that will be invoked to show the progress of downloading and flashing process.
- errorCallback: is the function that will be invoked to show the error of downloading and flashing process.
The functions: saveData, readData, progress, error, startDl, endDl, startFl, endFl will be invoked by the library in the update process. They are assigned to the members of DlInfo structure.
The function receiveCallback will be invoked whenever ESP received the MQTT command. It will check if the topic is OTA_TOPIC then parsing the payload to get url and md5 value of firmware file. After that, it change the state of system to Fota_e to start updating process.
After finishing the whole process, the code "client.publish(OTA_TOPIC, "ok");" will publish message "ok" back to Python application.
When the system is in Running_e, it just listen the MQTT command.
4. Result
This tutorial is similar to Demo 34 but without using sdcard. It means firmware will be flashed to ESP directly from HTTP downloading process. Here is the model of this demo:
Figure: model of demo
2. HardwareRefer Demo 7 to connect ESP32 pins with sdcard module. And Demo 1 to connect ESP to LED.
3. Software
I made the library in github. Just download, install it and run example esp32httpota2. Change the Wifi ssid, password and IP of MQTT server according to yours. The code will be explained below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | #include <WiFi.h> #include <HttpFOTA.h> #include <PubSubClient.h> typedef enum { Runnning_e = 0x01, Fota_e }SysState; const char* ssid = "dd-wrt"; const char* password = "0000000000"; const char* mqtt_server = "192.168.1.107"; char url[100]; char md5[50]; WiFiClient espClient; PubSubClient client(espClient); SysState state = Runnning_e; /* topics */ #define OTA_TOPIC "smarthome/room1/ota" void progress(DlState state, int percent){ Serial.printf("state = %d - percent = %d\n", state, percent); } void receivedCallback(char* topic, byte* payload, unsigned int length) { if(strncmp(OTA_TOPIC, topic, strlen(OTA_TOPIC)) == 0){ memset(url, 0, 100); memset(md5, 0, 50); char *tmp = strstr((char *)payload, "url:"); char *tmp1 = strstr((char *)payload, ","); memcpy(url, tmp+strlen("url:"), tmp1-(tmp+strlen("url:"))); char *tmp2 = strstr((char *)payload, "md5:"); memcpy(md5, tmp2+strlen("md5:"), length-(tmp2+strlen("md5:")-(char *)&payload[0])); Serial.printf("started fota url: %s\n", url); Serial.printf("started fota md5: %s\n", md5); state = Fota_e; } } void mqttconnect() { /* Loop until reconnected */ while (!client.connected()) { Serial.print("MQTT connecting ..."); /* client ID */ String clientId = "ESP32Client"; /* connect now */ if (client.connect(clientId.c_str())) { Serial.println("connected"); /* subscribe topic */ client.subscribe(OTA_TOPIC); } else { Serial.print("failed, status code ="); Serial.print(client.state()); Serial.println("try again in 5 seconds"); /* Wait 5 seconds before retrying */ delay(5000); } } } void error(char *message){ printf("%s\n", message); } void startDl(void){ } void endDl(void){ } void setup() { // put your setup code here, to run once: // put your setup code here, to run once: Serial.begin(115200); Serial.print("Connecting to "); Serial.print(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.print("WiFi connected, IP address: "); Serial.println(WiFi.localIP()); /* configure the MQTT server with IPaddress and port */ client.setServer(mqtt_server, 1883); /* this receivedCallback function will be invoked when client received subscribed topic */ client.setCallback(receivedCallback); } void loop() { switch(state) { case Runnning_e: /* if client was disconnected then try to reconnect again */ if (!client.connected()) { mqttconnect(); } /* this function will listen for incomming subscribed topic-process-invoke receivedCallback */ client.loop(); break; case Fota_e: DlInfo info; info.url = url; info.md5 = md5; info.startDownloadCallback = startDl; info.endDownloadCallback = endDl; info.progressCallback = progress; info.errorCallback = error; httpFOTA.start(info); client.publish(OTA_TOPIC, "ok"); break; default: break; } } |
The library is simple. It only has 1 interface that is start with input is DlInfo structure. When calling this function, it will block the loop() function. We must initialize the structure before using it. The structure includes:
- url: is the http url of the firmware file.
- md5: is the md5 checksum of the firmware file.
- startDownloadCallback: is the function that will be invoked before starting downloading. I left it empty in this demo.
- endDownloadCallback: is the function that will be invoked after downloading was finished. I left it empty in this demo.
- progressCallback: is the function that will be invoked to show the progress of downloading and flashing process.
- errorCallback: is the function that will be invoked to show the error of downloading and flashing process.
The functions: saveData, readData, progress, error, startDl, endDl, startFl, endFl will be invoked by the library in the update process. They are assigned to the members of DlInfo structure.
The function receiveCallback will be invoked whenever ESP received the MQTT command. It will check if the topic is OTA_TOPIC then parsing the payload to get url and md5 value of firmware file. After that, it change the state of system to Fota_e to start updating process.
After finishing the whole process, the code "client.publish(OTA_TOPIC, "ok");" will publish message "ok" back to Python application.
When the system is in Running_e, it just listen the MQTT command.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | from random import randint import thread import sys try: import paho.mqtt.client as mqtt except ImportError: import os import inspect cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],"../src"))) if cmd_subfolder not in sys.path: sys.path.insert(0, cmd_subfolder) import paho.mqtt.client as mqtt server = "192.168.1.107"; topic = "smarthome/room1/ota" def on_connect(mqttc, obj, flags, rc): print("rc: "+str(rc)) def on_message(mqttc, obj, msg): print(msg.topic+" "+str(msg.qos)+" "+str(msg.payload)) def on_publish(mqttc, obj, mid): print("mid: "+str(mid)) def on_subscribe(mqttc, obj, mid, granted_qos): print("Subscribed: "+str(mid)+" "+str(granted_qos)) def on_log(mqttc, obj, level, string): print(string) mqttc = mqtt.Client() mqttc.on_message = on_message mqttc.on_connect = on_connect mqttc.on_publish = on_publish mqttc.on_subscribe = on_subscribe mqttc.connect(server, 1883, 60) mqttc.subscribe(topic, 0) def fotaControl( threadName, delay): while True: val = raw_input('Enter 1 to update firmware OTA ') if(val == "1"): mqttc.publish(topic, "url:http://192.168.1.107/phphello/led.bin,md5:6bd07139c21f572370242905c4465056") try: thread.start_new_thread( fotaControl, ("Fota Control", 0, ) ) except: print "Error: unable to start thread" mqttc.loop_forever() |
6 Comments
Anyone have ideas?
Thanks for the awesome guide.
Is their any license information available for your library?
Have a nice day
how can I check or calculate the MD5?
"C:\Program Files (x86)\Arduino\libraries\esp32/esp_log.h:21:25: fatal error: rom/ets_sys.h: No such file"
i tried to reinstal it but still it shwing the same eror
thank you for your help.