Arduino OTA upload firmware from a server to ESP32

I created a local server and I need to upload a .bin file to the local server and then the ESP32 has to switch the firmware to that file, How I can achive the comunication between the local server and the esp correctly? This is the /update endpoint in the ESP code:

void SetupServer() {

  server.on("/update", HTTP_POST, []() {
      server.sendHeader("Connection", "close");
      server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
      ESP.restart();
  }, []() {
    HTTPUpload & upload = server.upload();
    if (upload.status == UPLOAD_FILE_START) {
      Serial.printf("Update: %s\n", upload.filename.c_str());
      if (!Update.begin(UPDATE_SIZE_UNKNOWN)) {
        Update.printError(Serial);
      }
    } else if (upload.status == UPLOAD_FILE_WRITE) {
      if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
        Update.printError(Serial);
      }
    } else if (upload.status == UPLOAD_FILE_END) {
      if (Update.end(true)) {
        Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
      } else {
        Update.printError(Serial);
      }
    }
  });

This is the endpoint of the local server, I try to comunicate with the ESP through url: 'http://192.168.4.1/update'(the esp endpoint) in the ajax thing and it seems like it comunicates but the firmware dosn't change

<div class="container mt-5 mb-5 px-10 ">
    <div class="row">
        <div class="col-md-6 offset-md-3 text-center">
            <h2>Actualizar Firmware</h2><br>
            <form action="/update" method="POST" enctype="multipart/form-data" id='upload_form' role="form">
                <div class="form-group"> 
                    <input type="file" name="binfile" class="form-control" required><br>
                    <button type="submit" class="btn btn-secondary">Actualizar</button>
                </div><br>
                <div id='prg'>Progress: 0%</div>
            </form>
            {% if message  %}
                    <p class="alert alert-danger">{{ message }}</p>
            {% endif %}
        </div>
    </div>
</div>

<script>
$('form').submit(function(e){
    e.preventDefault();
    var form = $('#upload_form')[0];
    var data = new FormData(form);
    $.ajax({
    url: 'http://192.168.4.1/update',
    type: 'POST',
    data: data,
    contentType: false,
    processData:false,
    xhr: function() {
        var xhr = new window.XMLHttpRequest();
        xhr.upload.addEventListener('progress', function(evt) {
            if (evt.lengthComputable) {
                var per = evt.loaded / evt.total;
                $('#prg').html('progress: ' + Math.round(per*100) + '%');
            }
        }, false);
        return xhr;
    },
    success:function(d, s) {
        console.log('success!')
    },
    error: function (a, b, c) {

    }
    })
})
</script>

Upvotes: 0

Views: 1195

Answers (1)

Michael Ward
Michael Ward

Reputation: 67

Are you trying to make the ESP32 download new firmware from a server?
If so, you will need to create a wifi client and download the file to the SPI file system.
For this you need: WifiClient.h and SPIFFS.h

After the download has finished, you copy the file to the firmware location.
For this you need: Update.h

In my case, I stored my .bin file on github in the same repo as my code. To access that you need a secure client. I used: WifiClientSecure.h which lets you access public webites, even those that require a username and password.

It really was a mamoth task to get it all working, but worth it in the end. Let me know if you need any more help getting off the ground.

Upvotes: -1

Related Questions