Page 1 of 1

OTA Webserver upload works only once

Posted: Fri Nov 03, 2023 8:36 pm
by Techgraphix
When i program my ESP32 WROOM 32 clock with ArduinoOTA/examples/OTAWebUpdater (over the USB) and reboot it i can acces it in my browser with 192.168.178.101... enter name and password (default admin admin), select a bin file (in this case the same OTAWebUpdater, only changed the color for the requester) and update it, the file is tranfered 100% within a few seconds.. but when i repeat that it will only be transfered for about 60% . The ESP32 does a reset and starts the old program (with the old gray color). So the update is not done.
As the OTAWebUpdater uses 60% of program storage, i think it will try to upload in what is left of program memory before that will be activated. That might explain why i can't upload a program for the second time.
Am i right or is there something else, and more important: How can i solve it?

Re: OTA Webserver upload works only once

Posted: Sat Nov 04, 2023 6:27 am
by lbernstone
I'm not a fan of sending files like that without giving it an expected size. Try this code instead:

Code: Select all

// literal string
const char* indexHtml = R"literal(
  <!DOCTYPE html>
  <link rel="icon" href='/favicon.ico' sizes="any">
  <link rel="icon" href="/favicon.svg" type="image/svg+xml">
  <body style='width:480px'>
    <h2>ESP Firmware Update</h2>
    <form method='POST' enctype='multipart/form-data' id='upload-form'>
      <input type='file' id= 'file' name='update'>
      <input type='submit' value='Update'>
    </form>
    <br>
    <div id='prg' style='width:0;color:white;text-align:center'>0%</div>
    </body>
    <script>
    var prg = document.getElementById('prg');
    var form = document.getElementById('upload-form');
    form.addEventListener('submit', el=>{
      prg.style.backgroundColor = 'blue'; 
      el.preventDefault();
      var data = new FormData(form);
      var req = new XMLHttpRequest();
      var fsize = document.getElementById('file').files[0].size;
      req.open('POST', '/update?size=' + fsize);  
      req.upload.addEventListener('progress', p=>{
        let w = Math.round(p.loaded/p.total*100) + '%';
          if(p.lengthComputable){
             prg.innerHTML = w;
             prg.style.width = w;
          }
          if(w == '100%') prg.style.backgroundColor = 'black'; 
      });
      req.send(data);
     });
    </script>
)literal";

void handleUpdateEnd() {
  server.sendHeader("Connection", "close");
  if (Update.hasError()) {
    server.send(502, "text/plain", Update.errorString());
  } else {
    server.sendHeader("Refresh", "10");
    server.sendHeader("Location","/");
    server.send(307);
    ESP.restart();
  }
}

void handleUpdate() {
  size_t fsize = UPDATE_SIZE_UNKNOWN;
  if (server.hasArg("size")) fsize = server.arg("size").toInt();
  HTTPUpload& upload = server.upload();
  if (upload.status == UPLOAD_FILE_START) {
    log_i("Update: %s, %d", upload.filename.c_str(), upload.totalSize);
    if (!Update.begin(fsize)) {
      otaDone = 0;
      Update.printError(Serial);
     }
  } else if (upload.status == UPLOAD_FILE_WRITE) {
    if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
      Update.printError(Serial);
    } else {
      otaDone = 100UL * Update.progress() / Update.size();
    }
  } else if (upload.status == UPLOAD_FILE_END) {
    if (Update.end(true)) {
      log_w("Update Success: %u\nRebooting...\n", upload.totalSize);
    } else {
      log_e("%s", Update.errorString());
      otaDone = 0;
    }
  }
}

server.on("/root", HTTP_GET, []() {server.send(200, "text/html", indexHtml);});
server.on("/update", HTTP_POST, [](){handleUpdateEnd();}, [](){handleUpdate();});

Re: OTA Webserver upload works only once

Posted: Sat Nov 04, 2023 8:59 am
by Techgraphix
Thanks, but this code can't be compiled. Is it just a part? Normally i expect to see a setup(){} and a loop(){}, aswell as some includes.
My programmingskills are not that good that i understand everything ;)

Re: OTA Webserver upload works only once

Posted: Sat Nov 04, 2023 8:58 pm
by Techgraphix
Solved: in the background was a Watchdogtimer running, that did a reset after 8 seconds no "heartbeat"
Since i delete the task as soon as the upload starts, i have no problems uploading..
:)

Re: OTA Webserver upload works only once

Posted: Tue Dec 12, 2023 11:05 pm
by antonins
Hi Techgraphix,

could you be more explicit in how you reset watchdog ?

I have a problem which could be similar.

Thanks for your help,
Antonin

Re: OTA Webserver upload works only once

Posted: Thu Dec 14, 2023 8:05 am
by Techgraphix
I have no access to my computer for a few months as i'm abroad now..
Anyway, i use the esp-wdt.h. in the setup i set it to 8sec and at the end of the loop{} i give it a reset (something like espwdt.reset() ). When i enter the upload i disable the wdt.. after the upload it has a new program and wdt starts again.
You can try to disable your wdt temporary to see if the upload works then..
If so, do as i did and kill the wdt as soon as you enter the upload procedure.

Re: OTA Webserver upload works only once

Posted: Thu Dec 14, 2023 9:59 am
by antonins
Thanks for your reply !

I tried to remove watchdog to perform some test but it wasn't solved my issue.

Have a nice day

Re: OTA Webserver upload works only once

Posted: Thu Dec 14, 2023 2:25 pm
by Techgraphix
Have you tried OTAwebupdater.ino? (This is in the examples) adjust the networkname and password.
If this does not work either, check if you selected the right format for the memory configuration.. you need to have two memory parts to upload a new code
You have to set that in the IDE where you select the board.
As i have no computer here, i can't tell you exactly where and how..