Post topics, source code that relate to the Arduino Platform

User avatar
By Bootalito
#70219 I'm having trouble getting the updater to properly update my sketch. I've created a very basic updater program to show what I'm doing in my real program and it has the same issue that it doesn't seem to work. Everything seems to work fine (no errors from Updater.h) but when it reboots it just goes into a boot loop.

Here is the example program that just hosts one webpage that asks to upload a file
Code: Select all#include <FS.h> //SPIFFS File system
#include <ESP8266WiFi.h>
#include "ESPAsyncTCP.h"
#include "ESPAsyncWebServer.h"

#define HTTPPORT 80
const char* ssid = "SSID";
const char* password = "PASSWORD";

AsyncWebServer HTTPserver(HTTPPORT);

void HTTPRoot(AsyncWebServerRequest *request) {

   String w= F("\
              Upload a simple test program<p>\n\
              <form method='POST' action='/update' enctype='multipart/form-data'>\n\
                <input type='file' accept='.bin' name='update' value='Select File'><p>\n\
                <input type='submit' value='Upload and Update'>\n\
              </form>\n");

   AsyncResponseStream *response = request->beginResponseStream("text/html");
   response->print(w);
   request->send(response);

}

void update(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) {
   if (!index) { //UPLOAD Start
      Serial.setDebugOutput(true);
      Serial.printf("Update: %s\n", filename.c_str());
      uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
      Update.runAsync(true);
      if (!Update.begin(maxSketchSpace)) {//start with max available size
         Update.printError(Serial);
         request->send(200, F("text/html"), F("Error: Max size exceeded"));
      }
   } else if(final) { //Upload finished
      Serial.println(F("File Finished Uploading"));
      if (Update.end(true)) { //true to set the size to the current progress
         Serial.print(F("Update Success: Restarting..."));         
         ESP.restart();
      }
      else {
         Update.printError(Serial);
      }
      Serial.setDebugOutput(false);
      
   }
   //Write the Data to flash
   if (Update.write(data, len) != len) {
      Update.printError(Serial);
      request->send(200, F("text/html"), F("Error: Updated size did not match file uploaded"));
   }

   Serial.print(".");
}//===============================================================================================


void setup()
{

   Serial.begin(115200);
   WiFi.begin(ssid, password);
   Serial.printf("connecting to: %s\n\r", ssid);
   if (WiFi.waitForConnectResult() != WL_CONNECTED) {
      Serial.printf("STA: Failed!\n");
      WiFi.disconnect(false);
      delay(1000);
      WiFi.begin(ssid, password);
   }
   Serial.print("connected:"); Serial.println(WiFi.localIP().toString());
   

   HTTPserver.on("/", HTTPRoot);
      HTTPserver.on("/update", HTTP_POST, [](AsyncWebServerRequest *request) {
      request->send(200);
   }, update);
   HTTPserver.begin();
}



void loop()
{
   //do nothing

}



Here is a link to a Hello World program that you can use to test the update (just repeats "Hello World" via serial once a second):
https://www.dropbox.com/s/nj7c6ix723pwo8e/HelloWorld.WeMos.160MHz.Flash4MB.SPIFFS1MB.bin?dl=0

EDIT: deleted compiled program that would have only worked with my SSID and password. Spelling
Last edited by Bootalito on Fri Sep 22, 2017 6:16 pm, edited 1 time in total.
User avatar
By Bootalito
#70238 OK. So I've added the MD5 verification and it is failing. Here is a new program that includes an MD5 checksum check:

Code: Select all#include <FS.h> //SPIFFS File system
#include <ESP8266WiFi.h>
#include "ESPAsyncTCP.h"
#include "ESPAsyncWebServer.h"

const char* ssid = "SSID";
const char* password = "PASSWORD";

AsyncWebServer HTTPserver(80);

void HTTPRoot(AsyncWebServerRequest *request) {

   String w= F("\
              Upload a simple test program<p>\n\
              <form method='POST' action='/update' enctype='multipart/form-data'>\n\
                <input type='file' accept='.bin' name='update' value='Select File'><p>\n\
                <input type='submit' value='Upload and Update'>\n\
              </form>\n");

   AsyncResponseStream *response = request->beginResponseStream("text/html");
   response->print(w);
   request->send(response);

}

void update(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) {
   if (!index) { //UPLOAD Start
      Serial.setDebugOutput(true);
      //WiFiUDP::stopAll();
      Serial.printf("Update: %s\n", filename.c_str());
      uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
      Update.runAsync(true);
      Update.setMD5("5EAD17D0BF2DA78FF0FBB41B0D5F53C7");
      if (!Update.begin(maxSketchSpace)) {//start with max available size
         Update.printError(Serial);
         request->send(200, F("text/html"), F("Error: Max size exceeded"));
      }
   } else if(final) { //Upload finished
      Serial.println(F("File Finished Uploading"));
      if (Update.end(true)) { //true to set the size to the current progress
         Serial.print(F("Update Success: Restarting..."));         
         ESP.restart();
      }
      else {
         Update.printError(Serial);
      }
      Serial.setDebugOutput(false);
      
   }
   //Write the Data to flash
   if (Update.write(data, len) != len) {
      Update.printError(Serial);
      request->send(200, F("text/html"), F("Error: Updated size did not match file uploaded"));
   }

   Serial.print(".");
}//===============================================================================================


void setup()
{

   Serial.begin(115200);
   WiFi.begin(ssid, password);
   Serial.printf("connecting to: %s\n\r", ssid);
   if (WiFi.waitForConnectResult() != WL_CONNECTED) {
      Serial.printf("STA: Failed!\n");
      WiFi.disconnect(false);
      delay(1000);
      WiFi.begin(ssid, password);
   }
   Serial.print("connected at "); Serial.println(WiFi.localIP().toString());
   

   HTTPserver.on("/", HTTPRoot);
      HTTPserver.on("/update", HTTP_POST, [](AsyncWebServerRequest *request) {
      request->send(200);
   }, update);
   HTTPserver.begin();
}



void loop()
{
   //do nothing

}


Again here is a link to a Hello World program that you can use to test the update (just repeats "Hello World" via serial once a second):
https://www.dropbox.com/s/nj7c6ix723pwo ... B.bin?dl=0
This has an MD5 checksum of 5EAD17D0BF2DA78FF0FBB41B0D5F53C7. However the program is calculating a checksum of b8cee333dd3c4f2b3d439ba6c52839f2 and failing.

Why would the upload have a different checksum?
User avatar
By Bootalito
#70253 Figured it out:
The way I wrote the code I did not actually finish writing the last chunk

Needed to add
Code: Select all      if (Update.write(data, len) != len) {
         Update.printError(Serial);
         request->send(200, F("text/html"), F("Error: Updated size did not match file uploaded"));
      }

After
Code: Select all} else if(final) { //Upload finished
User avatar
By Jones20
#86290 Hi, I am still getting error in md5 mismatch. Binary file md5 is not matching with calculated md5 inside esp. Please guide the mistake.