OTA UPDATE with ESP32 GSM

PROJECT DETAIL

Hello,

In this project, we will remotely update an esp32 device with a quectel brand gsm module.

 

Remote updating is a great advantage, especially for our devices working in the field.

 

For example, if we have a device sending certain data to the server and we need to change the IP address of the server, the devices in the field will not work, so we need a remote update.

 

Let's talk about ota a little bit, there are many methods of updating ota, here are some examples;

 

  • Update with Wifi: This method limits us a little because there must be a wifi next to the working device and we need to send this wifi information to the device. Therefore, it is not a preferred method.
  • Updating via Bluetooth: This method can be preferred according to the options, a mobile application is required to use this method, and you also need to be near the device, so it is not a preferred method.
  • Update with gsm module: This method is mostly used when the currently used gsm module is used. For example, there is a company that sends data to the server and if you are using a gsm module, this method will be very healthy, you may need to go to the extra device and look for wifi from there, you will be able to update it.
  • Updating with SD card: It is the least used method, it is necessary to load the update file into the sd card and insert it into the device.

 

Let's come to our example, I will tell you how to update it with the GSM module, you can search for other methods.

 

Things to consider in my example;

  • A Quectel brand gsm model must be selected and it must have internal storage.
  • Esp32 Version should be selected as 2.0.7.
  • The .bin file created should be named update.bin.
  • EC25 RX and TX pins should be 26 and 27

In our example, it will start loading the bin file directly on the remote server.

We guarantee our file when downloading Quectel EC25 gsm module from remote server. We write the downloaded .bin file to the OTA section of our processor, taking 4000 bytes each time. After all the .bin file is finished, we verify the file and restart Esp32. That's it, let's get started :)

 

Arduino ide code:

#include "esp_ota_ops.h"
String server = "0.0.0.0";  //server ip adress
#define MODEM_TX 26
#define MODEM_RX 27

esp_ota_handle_t otaHandler = 0;
uint8_t tempp[4000];
char readd[4500];
int i, j, k, l, m, o, last, first, countfirst, countlast, error;
String count;
bool kontrol = true;
uint32_t sizee;
String fileSize;
#define SerialAT Serial1


void setup() {
  SerialAT.setRxBufferSize(4096);
  SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
  SerialAT.flush();
  ec25begin();
  ec25update();
}

void loop() {
  // put your main code here, to run repeatedly:
}


void ec25begin() {
  SerialAT.setRxBufferSize(4096);
  Serial.println("EC25 MODULE CONNECTING...");
  while (!SerialAT.findUntil("OK", "\n")) {
    SerialAT.println("AT");
    delay(1000);
  }
  Serial.println("EC25 MODULE-> CONNECTED");
}

void ec25update() {

  delay(1000);
  SerialAT.println("AT+QFCLOSE=1");
  delay(300);
  SerialAT.println("AT+QFCLOSE=2");
  delay(300);
  SerialAT.println("AT+QFCLOSE=3");
  delay(300);
  SerialAT.println("AT+QFCLOSE=4");
  delay(300);
  SerialAT.println("AT+QFDEL=\"*\"");
  delay(1000);
  SerialAT.println("AT+QHTTPURL=35");
  delay(1000);
  String Url = "http://" + server + "/update.bin";
  SerialAT.println(server);
  delay(1000);
  SerialAT.println("AT+QHTTPGET=80");
  delay(10000);
  String response = SerialAT.readString();
  Serial.println(response);

  if (response.indexOf("+QHTTPGET:") >= 0) {
    fileSize = getValue1(response, ',', 2);
    fileSize.trim();
    Serial.println(fileSize);
    SerialAT.println("AT+QHTTPREADFILE=\"UFS:update.bin\",80");
    delay(1500);
    do {
      SerialAT.println("AT+QFLST");
      delay(500);
    } while (!SerialAT.find(fileSize.c_str()));
    Serial.println("Download succes, writing flash...");
    SerialAT.println("AT+QFCLOSE=4");
    delay(500);
    SerialAT.println("AT+QFOPEN=\"Bootloder.bin\",0");
    delay(500);
    String temp = SerialAT.readString();
    delay(100);
    esp_ota_begin(esp_ota_get_next_update_partition(NULL), OTA_SIZE_UNKNOWN, &otaHandler);
    while (kontrol) {

      SerialAT.println("AT+QFREAD=4,4000");
      delay(500);
      i = 0;
      while (SerialAT.available() > 0) {
        char veri = SerialAT.read();
        readd[i++] = veri;
      }

      for (j = 0; j <= i; j++) {
        if ((readd[j] == 'C') && (readd[j + 1] == 'O') && (readd[j + 2] == 'N') && (readd[j + 3] == 'N') && (readd[j + 4] == 'E') && (readd[j + 5] == 'C') && (readd[j + 6] == 'T')) {
          countfirst = j + 8;
          if (readd[j + 9] == '\r')
            countlast = j + 9;
          else if (readd[j + 10] == '\r')
            countlast = j + 10;
          else if (readd[j + 11] == '\r')
            countlast = j + 11;
          else if (readd[j + 12] == '\r')
            countlast = j + 12;
          else if (readd[j + 13] == '\r')
            countlast = j + 13;
          else if (readd[j + 14] == '\r')
            countlast = j + 14;

          for (countfirst; countfirst <= countlast; countfirst++) {
            count += readd[countfirst];
          }
          sizee = sizee + count.toInt();
          Serial.print("UPLOAD: ");
          uint32_t sizee2 = sizee * 100;
          Serial.print((sizee2 / fileSize.toDouble()), 1);
          Serial.println("%");
          first = countlast + 2;
          break;
        }
      }
      for (k = 0; k <= i; k++) {
        if ((readd[k] == 'O') && (readd[k + 1] == 'K')) {
          last = k - 3;
        }
      }
      for (o = 0; o <= i; o++) {
        if ((readd[o] == '+') && (readd[o + 1] == 'C') && (readd[o + 2] == 'M') && (readd[o + 3] == 'E') && (readd[o + 4] == ' ' && (readd[o + 5] == 'E')) && (readd[o + 6] == 'R') && (readd[o + 7] == 'R') && (readd[o + 8] == 'O') && (readd[o + 9] == 'R')) {
          error = o;
        }
      }
      if (error > 0) {
        kontrol = false;
        break;
      }
      int eksi = first;
      for (first; first <= last; first++) {
        tempp[first - eksi] = readd[first];
      }
      if (esp_ota_write(otaHandler, tempp, 4000) != ESP_OK) {
        Serial.println("Upload Error");
        esp_restart();
      }
    }
    delay(5000);
  } else {
    Serial.println("Dosya indirilemedi...");
    ESP.restart();
  }
  esp_ota_end(otaHandler);
  Serial.println("");
  Serial.println("");
  Serial.println("");
  Serial.println("Bootloder Yuklendi.");
  Serial.println("");
  Serial.println("");
  Serial.println("");
  if (ESP_OK == esp_ota_set_boot_partition(esp_ota_get_next_update_partition(NULL))) {
    esp_restart();
  } else {
    Serial.println("Upload Error");
    esp_restart();
  }
}

String getValue1(String data, char separator, int index) {
  int found = 0;
  int strIndex[] = { 0, -1 };
  int maxIndex = data.length() - 1;

  for (int i = 0; i <= maxIndex && found <= index; i++) {
    if (data.charAt(i) == separator || i == maxIndex) {
      found++;
      strIndex[0] = strIndex[1] + 1;
      strIndex[1] = (i == maxIndex) ? i + 1 : i;
    }
  }
  return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
}
WhatsApp