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:
- First, I use the HTTPS protocol to receive the file from a GitHub repository.
- 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.
- 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 .