├── README.md └── WebOTA.ino /README.md: -------------------------------------------------------------------------------- 1 | # webota-esp32 2 | 3 | Full tutorial: https://www.teachmemicro.com/update-esp32-firmware-external-web-server/ 4 | 5 | 6 | Notes: 7 | - doesn't support https remote location for firmware file (for now) 8 | -------------------------------------------------------------------------------- /WebOTA.ino: -------------------------------------------------------------------------------- 1 | /* WebOTA.ino 2 | * 3 | * by Roland Pelayo 4 | * 5 | * Update ESP32 firmware via external web server 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | // location of firmware file on external web server 13 | // change to your actual .bin location 14 | #define HOST "http://server.com/esp32fw.bin" 15 | 16 | HTTPClient client; 17 | // Your WiFi credentials 18 | const char* ssid = "Your WiFi SSID"; 19 | const char* password = "Your WiFi Password"; 20 | // Global variables 21 | int totalLength; //total size of firmware 22 | int currentLength = 0; //current size of written firmware 23 | 24 | void setup() { 25 | Serial.begin(9600); 26 | // Start WiFi connection 27 | WiFi.mode(WIFI_MODE_STA); 28 | WiFi.begin(ssid, password); 29 | while (WiFi.status() != WL_CONNECTED) { 30 | delay(500); 31 | Serial.print("."); 32 | } 33 | 34 | Serial.println(""); 35 | Serial.println("WiFi connected"); 36 | Serial.println("IP address: "); 37 | Serial.println(WiFi.localIP()); 38 | // Connect to external web server 39 | client.begin(HOST); 40 | // Get file, just to check if each reachable 41 | int resp = client.GET(); 42 | Serial.print("Response: "); 43 | Serial.println(resp); 44 | // If file is reachable, start downloading 45 | if(resp == 200){ 46 | // get length of document (is -1 when Server sends no Content-Length header) 47 | totalLength = client.getSize(); 48 | // transfer to local variable 49 | int len = totalLength; 50 | // this is required to start firmware update process 51 | Update.begin(UPDATE_SIZE_UNKNOWN); 52 | Serial.printf("FW Size: %u\n",totalLength); 53 | // create buffer for read 54 | uint8_t buff[128] = { 0 }; 55 | // get tcp stream 56 | WiFiClient * stream = client.getStreamPtr(); 57 | // read all data from server 58 | Serial.println("Updating firmware..."); 59 | while(client.connected() && (len > 0 || len == -1)) { 60 | // get available data size 61 | size_t size = stream->available(); 62 | if(size) { 63 | // read up to 128 byte 64 | int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size)); 65 | // pass to function 66 | updateFirmware(buff, c); 67 | if(len > 0) { 68 | len -= c; 69 | } 70 | } 71 | delay(1); 72 | } 73 | }else{ 74 | Serial.println("Cannot download firmware file. Only HTTP response 200: OK is supported. Double check firmware location #defined in HOST."); 75 | } 76 | client.end(); 77 | 78 | } 79 | 80 | void loop() {} 81 | 82 | // Function to update firmware incrementally 83 | // Buffer is declared to be 128 so chunks of 128 bytes 84 | // from firmware is written to device until server closes 85 | void updateFirmware(uint8_t *data, size_t len){ 86 | Update.write(data, len); 87 | currentLength += len; 88 | // Print dots while waiting for update to finish 89 | Serial.print('.'); 90 | // if current length of written firmware is not equal to total firmware size, repeat 91 | if(currentLength != totalLength) return; 92 | Update.end(true); 93 | Serial.printf("\nUpdate Success, Total Size: %u\nRebooting...\n", currentLength); 94 | // Restart ESP32 to see changes 95 | ESP.restart(); 96 | } 97 | --------------------------------------------------------------------------------