Project OTA update Atmega2560 with SIM7600

I am currently working on a project to update the ATmega2560 using an SD card. My issue is that the hex file I received from the SIM7600 is not being stored correctly on the SD card. To be more clear, here are the steps I am following to handle the storage of the file on the SD card:

  1. First, I use the HTTPS protocol to receive the file from a GitHub repository.
  2. While receiving each chunk, I store it on the SD card. However, I noticed that each chunk includes extra spaces and the word "OK." I tried to implement an algorithm to clean each chunk, but I still encounter issues every time I receive the file.
  3. The file is not cleaned properly and includes some unwanted data.

Here is a part of the file I received from the SIM7600:

OK

:100000000C9465010C9496010C9496010C94960145
:100010000C9496010C9496010C9496010C94960104
:100020000C9496010C9496010C9496010C949601F4
:100030000C9496010C9496010C9496010C949601E4
:100040000C9496010C9496010C9496010C949601D4
:100050000C9496010C9496010C9496010C94CC1877
:100060000C9496010C94A0190C9476190C9496019A
:100070000C9496010C9496010C9496010C949601A4
:100080000C9496010C9496010C9496010C94960194
:100090000C9440190C9416190C9496010C94D619D2
:1000A0000C9496010C9496010C9496010C94960174
:1000B0000C9496010C9496010C9

OK

496010C94960164
:1000C0000C9496010C9496010C9496010C94960154
:1000D0000C9496010C9496010C9496010C94960144
:1000E0000C9496010C9432020C940D0F0C94A70200
:1000F0000C948B0D0C94210D0C9428020C94050388
:100100000C941A020C941E020C94F21D0C9416020C
:100110000C943E020C94E7010C94D80D0C94F01A48
:100120000C94820D0C94E3020C9424020C94A6020D
:100130000C94D4020C9447030C94F7020C94BB0D5E
:100140000C942C020C94EC010C9410020C941B0BDC
:100150000C94AB0D0C94FE010C9406020C949403C9
:100160000C94170F0C9436020C9402020C943A0271
:100170000C9

OK

40C026364696E6F70737578585B0041
:100180007C3C3E5E2B3D3F2F5B5D3B2C2A225C007E
:1001900000000B0C030A0D0E0F09080405020000F5
:1001A000000000000000000000000000000000004F
:1001B0000000000000000000000000001312110009
:1001C000000000000000000000000000000000002F
:1001D000000000000000000000000000000000001F
:1001E00000000000000000002200250028002B0075
:1001F0002E003100340002010000050108010B014E
:1002000000002100240027002A002D0030003300C8
:1002100001010000040107010A01050505050705A4
:1002200008080808020202020A0A08080404040

OK

472
:10023000010101010101010103030303030303039E
:10024000040707070C0C0C0C0C0C0C0C020202022D
:1002500006060606060606060B0B0B0B0B0B0B0B16
:10026000050505080807070404040A0A0A0A0A0A19
:1002700001021020200808102040102040800201B8
:10028000020108040201010204081020408080409D
:10029000201008040201800402018040201008049C
:1002A000020108040201010204081020408001023A
:1002B0000408102040800440800480081010204072
:1002C000040810204080F01AF21D11241FBECFEF49
:1002D000D1E2DEBFCDBF00E00CBF2AE0A0E6B6E071
:1002E00001C01D92A638B20

and here is my code of handling the chunks :

void GSM7600_download_file_from_Server(const char* URL, String filename) {
    Serial.println("Initializing HTTP...");
  
    sendATCommand("AT+HTTPINIT", 1000);

    Serial.println("Setting URL...");
    String Path_Command = "AT+HTTPPARA=\"URL\",\"" + String(URL) + "\"";
    sendATCommand(Path_Command, 1000);

    Serial.println("Starting HTTP GET request...");
    receive_response = sendATCommand("AT+HTTPACTION=0", 5000);
    delay(3000);  // Give time for response

    String actionResponse = "";
    int index = receive_response.indexOf("+HTTPACTION:");

    if (index != -1) {
    actionResponse = receive_response.substring(index);
    Serial.println("Extracted HTTPACTION response: " + actionResponse);
    
    if (sscanf(actionResponse.c_str(), "+HTTPACTION: %*d,%d,%d", &statusCode, &dataSize) == 2) {
        Serial.print("HTTP Status Code: ");
        Serial.println(statusCode);
        Serial.print("Data Size: ");
        Serial.println(dataSize);
    } else {
        Serial.println("Failed to parse response!");
        sendATCommand("AT+HTTPTERM", 500);
        return;
    }

    } else {
    Serial.println("HTTPACTION response not found!");
    sendATCommand("AT+HTTPTERM", 1000);
    return;
}
    
    if (statusCode != 200) {
        Serial.println("HTTP request failed. Terminating HTTP session.");
        sendATCommand("AT+HTTPTERM", 500);
        return;
    }
     // third change 
     Serial.print(" Total File Size: "); Serial.println(dataSize);
    
    //  Read data in chunks and store it properly
    uint32_t bytesRead = 0;
    File file = SD.open(filename, FILE_WRITE);
    
    String buffer = "";  // Stores partial lines to merge correctly
    while (bytesRead < dataSize) {
        uint32_t bytesToRead = min(512, dataSize - bytesRead);
        String readCommand = "AT+HTTPREAD=" + String(bytesRead) + "," + String(bytesToRead);
        
        Serial.print(" Reading chunk at offset: "); Serial.println(bytesRead);
        String httpData = sendATCommand(readCommand, 3000);

        //  **Process and clean data**
        String cleanedData = "";
        int index = 0;
        while (index < httpData.length()) {
            String line = httpData.substring(index, httpData.indexOf('\n', index));
            index = httpData.indexOf('\n', index) + 1;

            // **Skip unwanted lines**
            if (line.startsWith("+HTTPREAD") || line == "OK" || line.length() == 0) {
                continue;
            }

            // **Merge broken lines**
            if (line.startsWith(":") && line.length() < 43) {
                cleanedData += line;  // Store partial 
            }
            } else if (buffer.length() > 0) {
                buffer += line;  // Merge with previous broken part
                cleanedData += buffer + "\n";
                buffer = "";  // Reset buffer after merging
            } else {
                cleanedData += line + "\n";  // Normal complete line
            }
        }

        // **Write cleaned data to SD**
        if (cleanedData.length() > 0) {
            file.print(cleanedData);
            bytesRead += bytesToRead;
            Serial.print(" Bytes received so far: "); Serial.println(bytesRead);
        } else {
            Serial.println(" Missing data! Retrying...");
            delay(500); // Wait before retrying
        }
    }

    file.close();
    Serial.println(" Cleaned File downloaded and saved successfully.");
    sendATCommand("AT+HTTPTERM", 500);
}
 
#include <SPI.h>
#include <SD.h>
#include <Ethernet.h>
#define OTETHERNET
#include <ArduinoOTA.h>

void setup() {
  //Initialize serial:
  Serial.begin(9600);
  while (!Serial);

  // setup SD card
  Serial.print("Initializing SD card...");
  if (!SD.begin(SDCARD_SS_PIN)) {
    Serial.println("initialization failed!");
    // don't continue:
    while (true);
  }
  Serial.println("initialization done.");

  // start the OTEthernet library with SD based storage
  SDStorage.setUpdateFileName("FIRMWARE.BIN"); // for https://github.com/zevero/avr_boot/
  SDStorage.clear(); // AVR SD bootloaders don't delete the update file
   ArduinoOTA.begin(Ethernet.localIP(),"","",SDStorage);

}

void loop() {
  // check for updates
  ArduinoOTA.poll();

  // add your normal loop code below ...
}

note : this code is example from arduino OTA lib .

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.