LilyGo-T-Call-SIM800
LilyGo-T-Call-SIM800 copied to clipboard
ESP32 LilyGo GSM module OTA possibilities
Hello. I am using this module to learn how to use GSM modules. I have been experimenting with the example codes and I have learnt the basic working principles. The big project that I am going to be working on next will involve the GSM and the GPS module.
I am very interested in how to perform a OTA over the GSM since the there will be very limited WIFI availability where my device will be used. At some point, I may want to update the firmware, fix bugs, so I the probably the easiest way to be to use the GSM and do the OTA over the GSM.
I have noticed the update_firmware under the example codes but there is nothing there. Perhaps anyone has made any progress and could share their knowledge and ideas with me? I appreciate any help! Thanks in advance
see tinygsm examples on how to open a tcp connection and use it, and see esp32 https ota examples https://github.com/espressif/arduino-esp32/tree/master/libraries/Update/examples/HTTPS_OTA_Update
see also here https://github.com/vshymanskyy/TinyGSM/issues/152
Hi, I have the same problem. How did you solve?
I did a skectch and work fine, is any are interested I can share ti, but I dont know how to make the server to store the bin file. I did the sketch using the TTGO CALL SIM800L github GSM tiny OTA example. If someone has and server example I will apreciate it, my idea is to store the bin file on my web server.
Hello. Here is the code to perform OTA over the GSM:
#include <Update.h>
#define TINY_GSM_MODEM_SIM800
// Increase RX buffer
#define TINY_GSM_RX_BUFFER 1030
const char apn[] = "omnitel";
const char user[] = "omni";
const char pass[] = "omni";
#define MODEM_RST 5
#define MODEM_PWRKEY 4
#define MODEM_POWER_ON 23
#define MODEM_TX 27
#define MODEM_RX 26
#define LED_GPIO 13
#define LED_ON HIGH
#define LED_OFF LOW
#define SerialAT Serial1
#include <TinyGsmClient.h>
#include <CRC32.h>
#include "FS.h"
#include "SPIFFS.h"
#ifdef DUMP_AT_COMMANDS
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, Serial);
TinyGsm modem(debugger);
#else
TinyGsm modem(SerialAT);
#endif
TinyGsmClient client(modem);
const char server[] = "myesptestserver.ddns.net";
const int port = 80;
const char resource[] = "/esp.bin"; //here de bin file
uint32_t knownCRC32 = 0x6f50d767;
uint32_t knownFileSize = 1024; // In case server does not send it
void setup()
{
SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
// Set console baud rate
Serial.begin(115200);
setupModem();
delay(10);
if (!SPIFFS.begin(true))
{
Serial.println("SPIFFS Mount Failed");
return;
}
SPIFFS.format();
listDir(SPIFFS, "/", 0);
// Set GSM module baud rate
delay(3000);
// Restart takes quite some time
// To skip it, call init() instead of restart()
Serial.println("Initializing modem...");
modem.restart();
String modemInfo = modem.getModemInfo();
Serial.print("Modem: ");
Serial.println(modemInfo);
// Unlock your SIM card with a PIN
//modem.simUnlock("1234");
}
void loop()
{
Serial.print("Waiting for network...");
if (!modem.waitForNetwork())
{
Serial.println(" fail");
delay(10000);
return;
}
Serial.println(" OK");
Serial.print("Connecting to ");
Serial.print(apn);
if (!modem.gprsConnect(apn, user, pass))
{
Serial.println(" fail");
delay(10000);
return;
}
Serial.println(" OK");
Serial.print("Connecting to ");
Serial.print(server);
// if you get a connection, report back via serial:
if (!client.connect(server, port))
{
Serial.println(" fail");
delay(10000);
return;
}
Serial.println(" OK");
// Make a HTTP request:
client.print(String("GET ") + resource + " HTTP/1.0\r\n");
client.print(String("Host: ") + server + "\r\n");
client.print("Connection: close\r\n\r\n");
long timeout = millis();
while (client.available() == 0)
{
if (millis() - timeout > 5000L)
{
Serial.println(">>> Client Timeout !");
client.stop();
delay(10000L);
return;
}
}
Serial.println("Reading header");
uint32_t contentLength = knownFileSize;
File file = SPIFFS.open("/update.bin", FILE_APPEND);
while (client.available())
{
String line = client.readStringUntil('\n');
line.trim();
//Serial.println(line); // Uncomment this to show response header
line.toLowerCase();
if (line.startsWith("content-length:"))
{
contentLength = line.substring(line.lastIndexOf(':') + 1).toInt();
}
else if (line.length() == 0)
{
break;
}
}
timeout = millis();
uint32_t readLength = 0;
CRC32 crc;
unsigned long timeElapsed = millis();
printPercent(readLength, contentLength);
while (readLength < contentLength && client.connected() && millis() - timeout < 10000L)
{
int i = 0;
while (client.available())
{
// read file data to spiffs
if (!file.print(char(client.read())))
{
Serial.println("Appending file");
}
//Serial.print((char)c); // Uncomment this to show data
//crc.update(c);
readLength++;
if (readLength % (contentLength / 13) == 0)
{
printPercent(readLength, contentLength);
}
timeout = millis();
}
}
file.close();
printPercent(readLength, contentLength);
timeElapsed = millis() - timeElapsed;
Serial.println();
client.stop();
Serial.println("stop client");
modem.gprsDisconnect();
Serial.println("gprs disconnect");
Serial.println();
float duration = float(timeElapsed) / 1000;
/*
Serial.print("Tamaño de Archivo: ");
Serial.println(contentLength);
Serial.print("Leido: ");
Serial.println(readLength);
Serial.print("Calculado. CRC32: 0x");
Serial.println(crc.finalize(), HEX);
Serial.print("Conocido CRC32: 0x");
Serial.println(knownCRC32, HEX);
Serial.print("Bajado en: ");
Serial.print(duration);
Serial.println("s");
Serial.println("Se genera una espera de 3 segundos");
for (int i = 0; i < 3; i++)
{
Serial.print(String(i) + "...");
delay(1000);
}
*/
//readFile(SPIFFS, "/update.bin");
updateFromFS();
// Do nothing forevermore
while (true)
{
delay(1000);
}
}
void appendFile(fs::FS &fs, const char *path, const char *message)
{
Serial.printf("Appending to file: %s\n", path);
File file = fs.open(path, FILE_APPEND);
if (!file)
{
Serial.println("Failed to open file for appending");
return;
}
if (file.print(message))
{
Serial.println("APOK");
}
else
{
Serial.println("APX");
}
}
void readFile(fs::FS &fs, const char *path)
{
Serial.printf("Reading file: %s\n", path);
File file = fs.open(path);
if (!file || file.isDirectory())
{
Serial.println("Failed to open file for reading");
return;
}
Serial.print("Read from file: ");
while (file.available())
{
Serial.write(file.read());
delayMicroseconds(100);
}
}
void writeFile(fs::FS &fs, const char *path, const char *message)
{
Serial.printf("Writing file: %s\n", path);
File file = fs.open(path, FILE_WRITE);
if (!file)
{
Serial.println("Failed to open file for writing");
return;
}
if (file.print(message))
{
Serial.println("File written");
}
else
{
Serial.println("Write failed");
}
}
void listDir(fs::FS &fs, const char *dirname, uint8_t levels)
{
Serial.printf("Listing directory: %s\n", dirname);
File root = fs.open(dirname);
if (!root)
{
Serial.println("Failed to open directory");
return;
}
if (!root.isDirectory())
{
Serial.println("Not a directory");
return;
}
File file = root.openNextFile();
while (file)
{
if (file.isDirectory())
{
Serial.print(" DIR : ");
Serial.println(file.name());
if (levels)
{
listDir(fs, file.name(), levels - 1);
}
}
else
{
Serial.print(" FILE: ");
Serial.print(file.name());
Serial.print(" SIZE: ");
Serial.println(file.size());
}
file = root.openNextFile();
}
}
void deleteFile(fs::FS &fs, const char *path)
{
Serial.printf("Deleting file: %s\n", path);
if (fs.remove(path))
{
Serial.println("File deleted");
}
else
{
Serial.println("Delete failed");
}
}
void updateFromFS()
{
File updateBin = SPIFFS.open("/update.bin");
if (updateBin)
{
if (updateBin.isDirectory())
{
Serial.println("Directory error");
updateBin.close();
return;
}
size_t updateSize = updateBin.size();
if (updateSize > 0)
{
Serial.println("Starting update");
performUpdate(updateBin, updateSize);
}
else
{
Serial.println("Error, archivo vacío");
}
updateBin.close();
// whe finished remove the binary from sd card to indicate end of the process
//fs.remove("/update.bin");
}
else
{
Serial.println("no such binary");
}
}
void performUpdate(Stream &updateSource, size_t updateSize)
{
if (Update.begin(updateSize))
{
size_t written = Update.writeStream(updateSource);
if (written == updateSize)
{
Serial.println("Writes : " + String(written) + " successfully");
}
else
{
Serial.println("Written only : " + String(written) + "/" + String(updateSize) + ". Retry?");
}
if (Update.end())
{
Serial.println("OTA finished!");
if (Update.isFinished())
{
Serial.println("Restart ESP device!");
ESP.restart();
}
else
{
Serial.println("OTA not fiished");
}
}
else
{
Serial.println("Error occured #: " + String(Update.getError()));
}
}
else
{
Serial.println("Cannot beggin update");
}
}
void printPercent(uint32_t readLength, uint32_t contentLength)
{
// If we know the total length
if (contentLength != -1)
{
Serial.print("\r ");
Serial.print((100.0 * readLength) / contentLength);
Serial.print('%');
}
else
{
Serial.println(readLength);
}
}
void setupModem()
{
#ifdef MODEM_RST
// Keep reset high
pinMode(MODEM_RST, OUTPUT);
digitalWrite(MODEM_RST, HIGH);
#endif
pinMode(MODEM_PWRKEY, OUTPUT);
pinMode(MODEM_POWER_ON, OUTPUT);
// Turn on the Modem power first
digitalWrite(MODEM_POWER_ON, HIGH);
// Pull down PWRKEY for more than 1 second according to manual requirements
digitalWrite(MODEM_PWRKEY, HIGH);
delay(100);
digitalWrite(MODEM_PWRKEY, LOW);
delay(1000);
digitalWrite(MODEM_PWRKEY, HIGH);
// Initialize the indicator as an output
pinMode(LED_GPIO, OUTPUT);
digitalWrite(LED_GPIO, LED_OFF);
}
Make sure to change accordingle the following lines of code:
const char apn[] = "omnitel";
const char user[] = "omni";
const char pass[] = "omni";
and
const char server[] = "myesptestserver.ddns.net";
const int port = 80;
const char resource[] = "/esp.bin"; //here de bin file
For storing the bin files, you have multiple choises.
- Use Raspberry pi as a server ( I have created a simple apache server where I uploaded my binary file, and then I can access that server through the following sketch.
However, for testing it maybe be easier to setup Xampp on windows machine just to see whether you can get it to work. 2. Create an apache or simmilar server on your windows machine ( probably the simplest method would be to use Xampp as it does everything for you. In the xampp folder you will have htdocs folder where you can put your binary. and you can access that binary by using my sketch or your own sketch
const char server[] = "myesptestserver.ddns.net"; // ip of server or web address
const int port = 80;
const char resource[] = "/esp.bin"; // put your binary file name
Let me know if you have any more questions
Hello. Here is the code to perform OTA over the GSM:
#include <Update.h> #define TINY_GSM_MODEM_SIM800 // Increase RX buffer #define TINY_GSM_RX_BUFFER 1030 const char apn[] = "omnitel"; const char user[] = "omni"; const char pass[] = "omni"; #define MODEM_RST 5 #define MODEM_PWRKEY 4 #define MODEM_POWER_ON 23 #define MODEM_TX 27 #define MODEM_RX 26 #define LED_GPIO 13 #define LED_ON HIGH #define LED_OFF LOW #define SerialAT Serial1 #include <TinyGsmClient.h> #include <CRC32.h> #include "FS.h" #include "SPIFFS.h" #ifdef DUMP_AT_COMMANDS #include <StreamDebugger.h> StreamDebugger debugger(SerialAT, Serial); TinyGsm modem(debugger); #else TinyGsm modem(SerialAT); #endif TinyGsmClient client(modem); const char server[] = "myesptestserver.ddns.net"; const int port = 80; const char resource[] = "/esp.bin"; //here de bin file uint32_t knownCRC32 = 0x6f50d767; uint32_t knownFileSize = 1024; // In case server does not send it void setup() { SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX); // Set console baud rate Serial.begin(115200); setupModem(); delay(10); if (!SPIFFS.begin(true)) { Serial.println("SPIFFS Mount Failed"); return; } SPIFFS.format(); listDir(SPIFFS, "/", 0); // Set GSM module baud rate delay(3000); // Restart takes quite some time // To skip it, call init() instead of restart() Serial.println("Initializing modem..."); modem.restart(); String modemInfo = modem.getModemInfo(); Serial.print("Modem: "); Serial.println(modemInfo); // Unlock your SIM card with a PIN //modem.simUnlock("1234"); } void loop() { Serial.print("Waiting for network..."); if (!modem.waitForNetwork()) { Serial.println(" fail"); delay(10000); return; } Serial.println(" OK"); Serial.print("Connecting to "); Serial.print(apn); if (!modem.gprsConnect(apn, user, pass)) { Serial.println(" fail"); delay(10000); return; } Serial.println(" OK"); Serial.print("Connecting to "); Serial.print(server); // if you get a connection, report back via serial: if (!client.connect(server, port)) { Serial.println(" fail"); delay(10000); return; } Serial.println(" OK"); // Make a HTTP request: client.print(String("GET ") + resource + " HTTP/1.0\r\n"); client.print(String("Host: ") + server + "\r\n"); client.print("Connection: close\r\n\r\n"); long timeout = millis(); while (client.available() == 0) { if (millis() - timeout > 5000L) { Serial.println(">>> Client Timeout !"); client.stop(); delay(10000L); return; } } Serial.println("Reading header"); uint32_t contentLength = knownFileSize; File file = SPIFFS.open("/update.bin", FILE_APPEND); while (client.available()) { String line = client.readStringUntil('\n'); line.trim(); //Serial.println(line); // Uncomment this to show response header line.toLowerCase(); if (line.startsWith("content-length:")) { contentLength = line.substring(line.lastIndexOf(':') + 1).toInt(); } else if (line.length() == 0) { break; } } timeout = millis(); uint32_t readLength = 0; CRC32 crc; unsigned long timeElapsed = millis(); printPercent(readLength, contentLength); while (readLength < contentLength && client.connected() && millis() - timeout < 10000L) { int i = 0; while (client.available()) { // read file data to spiffs if (!file.print(char(client.read()))) { Serial.println("Appending file"); } //Serial.print((char)c); // Uncomment this to show data //crc.update(c); readLength++; if (readLength % (contentLength / 13) == 0) { printPercent(readLength, contentLength); } timeout = millis(); } } file.close(); printPercent(readLength, contentLength); timeElapsed = millis() - timeElapsed; Serial.println(); client.stop(); Serial.println("stop client"); modem.gprsDisconnect(); Serial.println("gprs disconnect"); Serial.println(); float duration = float(timeElapsed) / 1000; /* Serial.print("Tamaño de Archivo: "); Serial.println(contentLength); Serial.print("Leido: "); Serial.println(readLength); Serial.print("Calculado. CRC32: 0x"); Serial.println(crc.finalize(), HEX); Serial.print("Conocido CRC32: 0x"); Serial.println(knownCRC32, HEX); Serial.print("Bajado en: "); Serial.print(duration); Serial.println("s"); Serial.println("Se genera una espera de 3 segundos"); for (int i = 0; i < 3; i++) { Serial.print(String(i) + "..."); delay(1000); } */ //readFile(SPIFFS, "/update.bin"); updateFromFS(); // Do nothing forevermore while (true) { delay(1000); } } void appendFile(fs::FS &fs, const char *path, const char *message) { Serial.printf("Appending to file: %s\n", path); File file = fs.open(path, FILE_APPEND); if (!file) { Serial.println("Failed to open file for appending"); return; } if (file.print(message)) { Serial.println("APOK"); } else { Serial.println("APX"); } } void readFile(fs::FS &fs, const char *path) { Serial.printf("Reading file: %s\n", path); File file = fs.open(path); if (!file || file.isDirectory()) { Serial.println("Failed to open file for reading"); return; } Serial.print("Read from file: "); while (file.available()) { Serial.write(file.read()); delayMicroseconds(100); } } void writeFile(fs::FS &fs, const char *path, const char *message) { Serial.printf("Writing file: %s\n", path); File file = fs.open(path, FILE_WRITE); if (!file) { Serial.println("Failed to open file for writing"); return; } if (file.print(message)) { Serial.println("File written"); } else { Serial.println("Write failed"); } } void listDir(fs::FS &fs, const char *dirname, uint8_t levels) { Serial.printf("Listing directory: %s\n", dirname); File root = fs.open(dirname); if (!root) { Serial.println("Failed to open directory"); return; } if (!root.isDirectory()) { Serial.println("Not a directory"); return; } File file = root.openNextFile(); while (file) { if (file.isDirectory()) { Serial.print(" DIR : "); Serial.println(file.name()); if (levels) { listDir(fs, file.name(), levels - 1); } } else { Serial.print(" FILE: "); Serial.print(file.name()); Serial.print(" SIZE: "); Serial.println(file.size()); } file = root.openNextFile(); } } void deleteFile(fs::FS &fs, const char *path) { Serial.printf("Deleting file: %s\n", path); if (fs.remove(path)) { Serial.println("File deleted"); } else { Serial.println("Delete failed"); } } void updateFromFS() { File updateBin = SPIFFS.open("/update.bin"); if (updateBin) { if (updateBin.isDirectory()) { Serial.println("Directory error"); updateBin.close(); return; } size_t updateSize = updateBin.size(); if (updateSize > 0) { Serial.println("Starting update"); performUpdate(updateBin, updateSize); } else { Serial.println("Error, archivo vacío"); } updateBin.close(); // whe finished remove the binary from sd card to indicate end of the process //fs.remove("/update.bin"); } else { Serial.println("no such binary"); } } void performUpdate(Stream &updateSource, size_t updateSize) { if (Update.begin(updateSize)) { size_t written = Update.writeStream(updateSource); if (written == updateSize) { Serial.println("Writes : " + String(written) + " successfully"); } else { Serial.println("Written only : " + String(written) + "/" + String(updateSize) + ". Retry?"); } if (Update.end()) { Serial.println("OTA finished!"); if (Update.isFinished()) { Serial.println("Restart ESP device!"); ESP.restart(); } else { Serial.println("OTA not fiished"); } } else { Serial.println("Error occured #: " + String(Update.getError())); } } else { Serial.println("Cannot beggin update"); } } void printPercent(uint32_t readLength, uint32_t contentLength) { // If we know the total length if (contentLength != -1) { Serial.print("\r "); Serial.print((100.0 * readLength) / contentLength); Serial.print('%'); } else { Serial.println(readLength); } } void setupModem() { #ifdef MODEM_RST // Keep reset high pinMode(MODEM_RST, OUTPUT); digitalWrite(MODEM_RST, HIGH); #endif pinMode(MODEM_PWRKEY, OUTPUT); pinMode(MODEM_POWER_ON, OUTPUT); // Turn on the Modem power first digitalWrite(MODEM_POWER_ON, HIGH); // Pull down PWRKEY for more than 1 second according to manual requirements digitalWrite(MODEM_PWRKEY, HIGH); delay(100); digitalWrite(MODEM_PWRKEY, LOW); delay(1000); digitalWrite(MODEM_PWRKEY, HIGH); // Initialize the indicator as an output pinMode(LED_GPIO, OUTPUT); digitalWrite(LED_GPIO, LED_OFF); }
Make sure to change accordingle the following lines of code:
const char apn[] = "omnitel"; const char user[] = "omni"; const char pass[] = "omni";
and
const char server[] = "myesptestserver.ddns.net"; const int port = 80; const char resource[] = "/esp.bin"; //here de bin file
For storing the bin files, you have multiple choises.
- Use Raspberry pi as a server ( I have created a simple apache server where I uploaded my binary file, and then I can access that server through the following sketch.
However, for testing it maybe be easier to setup Xampp on windows machine just to see whether you can get it to work. 2. Create an apache or simmilar server on your windows machine ( probably the simplest method would be to use Xampp as it does everything for you. In the xampp folder you will have htdocs folder where you can put your binary. and you can access that binary by using my sketch or your own sketch
const char server[] = "myesptestserver.ddns.net"; // ip of server or web address const int port = 80; const char resource[] = "/esp.bin"; // put your binary file name
Let me know if you have any more questions
This firmware below make ota from Github. I try mix your code with this, but I yet cant:
#include <WiFi.h> #include <HTTPClient.h> #include <HTTPUpdate.h> #include <WiFiClientSecure.h> #include "cert.h"
const char * ssid = "home_wifi"; const char * password = "helloworld";
String FirmwareVer = { "2.2" }; #define URL_fw_Version "https://raw.githubusercontent.com/programmer131/ESP8266_ESP32_SelfUpdate/master/esp32_ota/bin_version.txt" #define URL_fw_Bin "https://raw.githubusercontent.com/programmer131/ESP8266_ESP32_SelfUpdate/master/esp32_ota/fw.bin"
//#define URL_fw_Version "http://cade-make.000webhostapp.com/version.txt" //#define URL_fw_Bin "http://cade-make.000webhostapp.com/firmware.bin"
void connect_wifi(); void firmwareUpdate(); int FirmwareVersionCheck();
unsigned long previousMillis = 0; // will store last time LED was updated unsigned long previousMillis_2 = 0; const long interval = 60000; const long mini_interval = 1000; void repeatedCall() { static int num=0; unsigned long currentMillis = millis(); if ((currentMillis - previousMillis) >= interval) { // save the last time you blinked the LED previousMillis = currentMillis; if (FirmwareVersionCheck()) { firmwareUpdate(); } } if ((currentMillis - previousMillis_2) >= mini_interval) { previousMillis_2 = currentMillis; Serial.print("idle loop..."); Serial.print(num++); Serial.print(" Active fw version:"); Serial.println(FirmwareVer); if(WiFi.status() == WL_CONNECTED) { Serial.println("wifi connected"); } else { connect_wifi(); } } }
struct Button { const uint8_t PIN; uint32_t numberKeyPresses; bool pressed; };
Button button_boot = { 0, 0, false }; /void IRAM_ATTR isr(void arg) { Button* s = static_cast<Button*>(arg); s->numberKeyPresses += 1; s->pressed = true; }*/
void IRAM_ATTR isr() { button_boot.numberKeyPresses += 1; button_boot.pressed = true; }
void setup() { pinMode(button_boot.PIN, INPUT); attachInterrupt(button_boot.PIN, isr, RISING); Serial.begin(115200); Serial.print("Active firmware version:"); Serial.println(FirmwareVer); pinMode(LED_BUILTIN, OUTPUT); connect_wifi(); } void loop() { if (button_boot.pressed) { //to connect wifi via Android esp touch app Serial.println("Firmware update Starting.."); firmwareUpdate(); button_boot.pressed = false; } repeatedCall(); }
void connect_wifi() { Serial.println("Waiting for WiFi"); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); }
void firmwareUpdate(void) { WiFiClientSecure client; client.setCACert(rootCACertificate); httpUpdate.setLedPin(LED_BUILTIN, LOW); t_httpUpdate_return ret = httpUpdate.update(client, URL_fw_Bin);
switch (ret) { case HTTP_UPDATE_FAILED: Serial.printf("HTTP_UPDATE_FAILD Error (%d): %s\n", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str()); break;
case HTTP_UPDATE_NO_UPDATES: Serial.println("HTTP_UPDATE_NO_UPDATES"); break;
case HTTP_UPDATE_OK: Serial.println("HTTP_UPDATE_OK"); break; } } int FirmwareVersionCheck(void) { String payload; int httpCode; String fwurl = ""; fwurl += URL_fw_Version; fwurl += "?"; fwurl += String(rand()); Serial.println(fwurl); WiFiClientSecure * client = new WiFiClientSecure;
if (client) { client -> setCACert(rootCACertificate);
// Add a scoping block for HTTPClient https to make sure it is destroyed before WiFiClientSecure *client is
HTTPClient https;
if (https.begin( * client, fwurl))
{ // HTTPS
Serial.print("[HTTPS] GET...\n");
// start connection and send HTTP header
delay(100);
httpCode = https.GET();
delay(100);
if (httpCode == HTTP_CODE_OK) // if version received
{
payload = https.getString(); // save received version
} else {
Serial.print("error in downloading version file:");
Serial.println(httpCode);
}
https.end();
}
delete client;
}
if (httpCode == HTTP_CODE_OK) // if version received
{
payload.trim();
if (payload.equals(FirmwareVer)) {
Serial.printf("\nDevice already on latest firmware version:%s\n", FirmwareVer);
return 0;
}
else
{
Serial.println(payload);
Serial.println("New firmware detected");
return 1;
}
}
return 0;
}
Hello. Have you managed to get examples from Arduino IDE working? They have an example sketch that performs an OTA over the http?
From the first glance, your code looks fine. What error are you getting?
On Sun, 16 May 2021, 04:26 eueduardo3, @.***> wrote:
Hello. Here is the code to perform OTA over the GSM:
#include <Update.h>
#define TINY_GSM_MODEM_SIM800
// Increase RX buffer
#define TINY_GSM_RX_BUFFER 1030
const char apn[] = "omnitel";
const char user[] = "omni";
const char pass[] = "omni";
#define MODEM_RST 5
#define MODEM_PWRKEY 4
#define MODEM_POWER_ON 23
#define MODEM_TX 27
#define MODEM_RX 26
#define LED_GPIO 13
#define LED_ON HIGH
#define LED_OFF LOW
#define SerialAT Serial1
#include <TinyGsmClient.h>
#include <CRC32.h>
#include "FS.h"
#include "SPIFFS.h"
#ifdef DUMP_AT_COMMANDS
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, Serial);
TinyGsm modem(debugger);
#else
TinyGsm modem(SerialAT);
#endif
TinyGsmClient client(modem);
const char server[] = "myesptestserver.ddns.net";
const int port = 80;
const char resource[] = "/esp.bin"; //here de bin file
uint32_t knownCRC32 = 0x6f50d767;
uint32_t knownFileSize = 1024; // In case server does not send it
void setup()
{
SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX); // Set console baud rate Serial.begin(115200); setupModem(); delay(10); if (!SPIFFS.begin(true)) { Serial.println("SPIFFS Mount Failed"); return; } SPIFFS.format(); listDir(SPIFFS, "/", 0); // Set GSM module baud rate delay(3000); // Restart takes quite some time // To skip it, call init() instead of restart() Serial.println("Initializing modem..."); modem.restart(); String modemInfo = modem.getModemInfo(); Serial.print("Modem: "); Serial.println(modemInfo); // Unlock your SIM card with a PIN //modem.simUnlock("1234");
}
void loop()
{
Serial.print("Waiting for network..."); if (!modem.waitForNetwork()) { Serial.println(" fail"); delay(10000); return; } Serial.println(" OK"); Serial.print("Connecting to "); Serial.print(apn); if (!modem.gprsConnect(apn, user, pass)) { Serial.println(" fail"); delay(10000); return; } Serial.println(" OK"); Serial.print("Connecting to "); Serial.print(server); // if you get a connection, report back via serial: if (!client.connect(server, port)) { Serial.println(" fail"); delay(10000); return; } Serial.println(" OK"); // Make a HTTP request: client.print(String("GET ") + resource + " HTTP/1.0\r\n"); client.print(String("Host: ") + server + "\r\n"); client.print("Connection: close\r\n\r\n"); long timeout = millis(); while (client.available() == 0) { if (millis() - timeout > 5000L) { Serial.println(">>> Client Timeout !"); client.stop(); delay(10000L); return; } } Serial.println("Reading header"); uint32_t contentLength = knownFileSize; File file = SPIFFS.open("/update.bin", FILE_APPEND); while (client.available()) { String line = client.readStringUntil('\n'); line.trim(); //Serial.println(line); // Uncomment this to show response header line.toLowerCase(); if (line.startsWith("content-length:")) { contentLength = line.substring(line.lastIndexOf(':') + 1).toInt(); } else if (line.length() == 0) { break; } } timeout = millis(); uint32_t readLength = 0; CRC32 crc; unsigned long timeElapsed = millis(); printPercent(readLength, contentLength); while (readLength < contentLength && client.connected() && millis() - timeout < 10000L) { int i = 0; while (client.available()) { // read file data to spiffs if (!file.print(char(client.read()))) { Serial.println("Appending file"); } //Serial.print((char)c); // Uncomment this to show data //crc.update(c); readLength++; if (readLength % (contentLength / 13) == 0) { printPercent(readLength, contentLength); } timeout = millis(); } } file.close(); printPercent(readLength, contentLength); timeElapsed = millis() - timeElapsed; Serial.println(); client.stop(); Serial.println("stop client"); modem.gprsDisconnect(); Serial.println("gprs disconnect"); Serial.println(); float duration = float(timeElapsed) / 1000;
/*
Serial.print("Tamaño de Archivo: "); Serial.println(contentLength); Serial.print("Leido: "); Serial.println(readLength); Serial.print("Calculado. CRC32: 0x"); Serial.println(crc.finalize(), HEX); Serial.print("Conocido CRC32: 0x"); Serial.println(knownCRC32, HEX); Serial.print("Bajado en: "); Serial.print(duration); Serial.println("s"); Serial.println("Se genera una espera de 3 segundos"); for (int i = 0; i < 3; i++) { Serial.print(String(i) + "..."); delay(1000); }
*/
//readFile(SPIFFS, "/update.bin"); updateFromFS(); // Do nothing forevermore while (true) { delay(1000); }
}
void appendFile(fs::FS &fs, const char *path, const char *message)
{
Serial.printf("Appending to file: %s\n", path); File file = fs.open(path, FILE_APPEND); if (!file) { Serial.println("Failed to open file for appending"); return; } if (file.print(message)) { Serial.println("APOK"); } else { Serial.println("APX"); }
}
void readFile(fs::FS &fs, const char *path)
{
Serial.printf("Reading file: %s\n", path); File file = fs.open(path); if (!file || file.isDirectory()) { Serial.println("Failed to open file for reading"); return; } Serial.print("Read from file: "); while (file.available()) { Serial.write(file.read()); delayMicroseconds(100); }
}
void writeFile(fs::FS &fs, const char *path, const char *message)
{
Serial.printf("Writing file: %s\n", path); File file = fs.open(path, FILE_WRITE); if (!file) { Serial.println("Failed to open file for writing"); return; } if (file.print(message)) { Serial.println("File written"); } else { Serial.println("Write failed"); }
}
void listDir(fs::FS &fs, const char *dirname, uint8_t levels)
{
Serial.printf("Listing directory: %s\n", dirname); File root = fs.open(dirname); if (!root) { Serial.println("Failed to open directory"); return; } if (!root.isDirectory()) { Serial.println("Not a directory"); return; } File file = root.openNextFile(); while (file) { if (file.isDirectory()) { Serial.print(" DIR : "); Serial.println(file.name()); if (levels) { listDir(fs, file.name(), levels - 1); } } else { Serial.print(" FILE: "); Serial.print(file.name()); Serial.print(" SIZE: "); Serial.println(file.size()); } file = root.openNextFile(); }
}
void deleteFile(fs::FS &fs, const char *path)
{
Serial.printf("Deleting file: %s\n", path); if (fs.remove(path)) { Serial.println("File deleted"); } else { Serial.println("Delete failed"); }
}
void updateFromFS()
{
File updateBin = SPIFFS.open("/update.bin"); if (updateBin) { if (updateBin.isDirectory()) { Serial.println("Directory error"); updateBin.close(); return; } size_t updateSize = updateBin.size(); if (updateSize > 0) { Serial.println("Starting update"); performUpdate(updateBin, updateSize); } else { Serial.println("Error, archivo vacío"); } updateBin.close(); // whe finished remove the binary from sd card to indicate end of the process //fs.remove("/update.bin"); } else { Serial.println("no such binary"); }
}
void performUpdate(Stream &updateSource, size_t updateSize)
{
if (Update.begin(updateSize)) { size_t written = Update.writeStream(updateSource); if (written == updateSize) { Serial.println("Writes : " + String(written) + " successfully"); } else { Serial.println("Written only : " + String(written) + "/" + String(updateSize) + ". Retry?"); } if (Update.end()) { Serial.println("OTA finished!"); if (Update.isFinished()) { Serial.println("Restart ESP device!"); ESP.restart(); } else { Serial.println("OTA not fiished"); } } else { Serial.println("Error occured #: " + String(Update.getError())); } } else { Serial.println("Cannot beggin update"); }
}
void printPercent(uint32_t readLength, uint32_t contentLength)
{
// If we know the total length if (contentLength != -1) { Serial.print("\r "); Serial.print((100.0 * readLength) / contentLength); Serial.print('%'); } else { Serial.println(readLength); }
}
void setupModem()
{
#ifdef MODEM_RST
// Keep reset high pinMode(MODEM_RST, OUTPUT); digitalWrite(MODEM_RST, HIGH);
#endif
pinMode(MODEM_PWRKEY, OUTPUT); pinMode(MODEM_POWER_ON, OUTPUT); // Turn on the Modem power first digitalWrite(MODEM_POWER_ON, HIGH); // Pull down PWRKEY for more than 1 second according to manual requirements digitalWrite(MODEM_PWRKEY, HIGH); delay(100); digitalWrite(MODEM_PWRKEY, LOW); delay(1000); digitalWrite(MODEM_PWRKEY, HIGH); // Initialize the indicator as an output pinMode(LED_GPIO, OUTPUT); digitalWrite(LED_GPIO, LED_OFF);
}
Make sure to change accordingle the following lines of code:
const char apn[] = "omnitel";
const char user[] = "omni";
const char pass[] = "omni";
and
const char server[] = "myesptestserver.ddns.net";
const int port = 80;
const char resource[] = "/esp.bin"; //here de bin file
For storing the bin files, you have multiple choises.
- Use Raspberry pi as a server ( I have created a simple apache server where I uploaded my binary file, and then I can access that server through the following sketch.
However, for testing it maybe be easier to setup Xampp on windows machine just to see whether you can get it to work. 2. Create an apache or simmilar server on your windows machine ( probably the simplest method would be to use Xampp as it does everything for you. In the xampp folder you will have htdocs folder where you can put your binary. and you can access that binary by using my sketch or your own sketch
const char server[] = "myesptestserver.ddns.net"; // ip of server or web address
const int port = 80;
const char resource[] = "/esp.bin"; // put your binary file name
Let me know if you have any more questions
This firmware below make ota from Github. I try mix your code with this, but I yet cant:
#include <WiFi.h> #include <HTTPClient.h> #include <HTTPUpdate.h> #include <WiFiClientSecure.h> #include "cert.h"
const char * ssid = "home_wifi"; const char * password = "helloworld";
String FirmwareVer = { "2.2" }; #define URL_fw_Version " https://raw.githubusercontent.com/programmer131/ESP8266_ESP32_SelfUpdate/master/esp32_ota/bin_version.txt " #define URL_fw_Bin " https://raw.githubusercontent.com/programmer131/ESP8266_ESP32_SelfUpdate/master/esp32_ota/fw.bin "
//#define URL_fw_Version "http://cade-make.000webhostapp.com/version.txt" //#define URL_fw_Bin "http://cade-make.000webhostapp.com/firmware.bin"
void connect_wifi(); void firmwareUpdate(); int FirmwareVersionCheck();
unsigned long previousMillis = 0; // will store last time LED was updated unsigned long previousMillis_2 = 0; const long interval = 60000; const long mini_interval = 1000; void repeatedCall() { static int num=0; unsigned long currentMillis = millis(); if ((currentMillis - previousMillis) >= interval) { // save the last time you blinked the LED previousMillis = currentMillis; if (FirmwareVersionCheck()) { firmwareUpdate(); } } if ((currentMillis - previousMillis_2) >= mini_interval) { previousMillis_2 = currentMillis; Serial.print("idle loop..."); Serial.print(num++); Serial.print(" Active fw version:"); Serial.println(FirmwareVer); if(WiFi.status() == WL_CONNECTED) { Serial.println("wifi connected"); } else { connect_wifi(); } } }
struct Button { const uint8_t PIN; uint32_t numberKeyPresses; bool pressed; };
Button button_boot = { 0, 0, false }; /void IRAM_ATTR isr(void arg) { Button* s = static_cast<Button*>(arg); s->numberKeyPresses += 1; s->pressed = true; }*/
void IRAM_ATTR isr() { button_boot.numberKeyPresses += 1; button_boot.pressed = true; }
void setup() { pinMode(button_boot.PIN, INPUT); attachInterrupt(button_boot.PIN, isr, RISING); Serial.begin(115200); Serial.print("Active firmware version:"); Serial.println(FirmwareVer); pinMode(LED_BUILTIN, OUTPUT); connect_wifi(); } void loop() { if (button_boot.pressed) { //to connect wifi via Android esp touch app Serial.println("Firmware update Starting.."); firmwareUpdate(); button_boot.pressed = false; } repeatedCall(); }
void connect_wifi() { Serial.println("Waiting for WiFi"); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); }
void firmwareUpdate(void) { WiFiClientSecure client; client.setCACert(rootCACertificate); httpUpdate.setLedPin(LED_BUILTIN, LOW); t_httpUpdate_return ret = httpUpdate.update(client, URL_fw_Bin);
switch (ret) { case HTTP_UPDATE_FAILED: Serial.printf("HTTP_UPDATE_FAILD Error (%d): %s\n", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str()); break;
case HTTP_UPDATE_NO_UPDATES: Serial.println("HTTP_UPDATE_NO_UPDATES"); break;
case HTTP_UPDATE_OK: Serial.println("HTTP_UPDATE_OK"); break; } } int FirmwareVersionCheck(void) { String payload; int httpCode; String fwurl = ""; fwurl += URL_fw_Version; fwurl += "?"; fwurl += String(rand()); Serial.println(fwurl); WiFiClientSecure * client = new WiFiClientSecure;
if (client) { client -> setCACert(rootCACertificate);
// Add a scoping block for HTTPClient https to make sure it is destroyed before WiFiClientSecure *client is
HTTPClient https;
if (https.begin( * client, fwurl))
{ // HTTPS
Serial.print("[HTTPS] GET...\n");
// start connection and send HTTP header
delay(100);
httpCode = https.GET();
delay(100);
if (httpCode == HTTP_CODE_OK) // if version received
{
payload = https.getString(); // save received version
} else {
Serial.print("error in downloading version file:"); Serial.println(httpCode);
}
https.end();
}
delete client;
}
if (httpCode == HTTP_CODE_OK) // if version received { payload.trim(); if (payload.equals(FirmwareVer)) { Serial.printf("\nDevice already on latest firmware version:%s\n", FirmwareVer); return 0; } else { Serial.println(payload); Serial.println("New firmware detected"); return 1; } } return 0; }
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/Xinyuan-LilyGO/LilyGo-T-Call-SIM800/issues/132#issuecomment-841750277, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFJU62XWVDQKYUMSHUPJMODTN4NMZANCNFSM42SG5BMA .
I tried to use your script to try to OTA a file hosted on GitHub, but I couldn't. In this example that I posted, it is okay to OTA a file through github through Wifi, but I was unable to do that using a gsm modem through the TinyGsmClient library
That is really weird. I have created an apache server using xampp and can do an OTA from there. What error are you getting? Are you using esp32 with spiffs fs partition? Do you know where your code gets stuck
On Sun, 16 May 2021, 23:38 eueduardo3, @.***> wrote:
I tried to use your script to try to OTA a file hosted on GitHub, but I couldn't. In this example that I posted, it is okay to OTA a file through github through Wifi, but I was unable to do that using a gsm modem through the TinyGsmClient library
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/Xinyuan-LilyGO/LilyGo-T-Call-SIM800/issues/132#issuecomment-841874314, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFJU62U5PEISOCCM36IP2OTTOAUNPANCNFSM42SG5BMA .
That is really weird. I have created an apache server using xampp and can do an OTA from there. What error are you getting? Are you using esp32 with spiffs fs partition? Do you know where your code gets stuck … On Sun, 16 May 2021, 23:38 eueduardo3, @.***> wrote: I tried to use your script to try to OTA a file hosted on GitHub, but I couldn't. In this example that I posted, it is okay to OTA a file through github through Wifi, but I was unable to do that using a gsm modem through the TinyGsmClient library — You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub <#132 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFJU62U5PEISOCCM36IP2OTTOAUNPANCNFSM42SG5BMA .
Now it worked! Thank you very much for making your code available and helping me. I changed the server and it worked. I was using 000webhost. And it was certainly my mistake, I was not sure how to correctly make the file available for download. Switching from server to another site / server with free hosting worked. Thank you very much for your attention in trying to help me. I wish success for your projects.
I did a skectch and work fine, is any are interested I can share ti, but I dont know how to make the server to store the bin file. I did the sketch using the TTGO CALL SIM800L github GSM tiny OTA example. If someone has and server example I will apreciate it, my idea is to store the bin file on my web server.
Hi, could you share your code? I'm having lots of issues trying any other code
Thank you
I did a skectch and work fine, is any are interested I can share ti, but I dont know how to make the server to store the bin file. I did the sketch using the TTGO CALL SIM800L github GSM tiny OTA example. If someone has and server example I will apreciate it, my idea is to store the bin file on my web server.
Hi, could you share your code? I'm having lots of issues trying any other code
Thank you
Hey. Have you tried the OTA over GSM code that I have posted above? It would be a good start if you can get that to work, then you can modify it as you wish. Make sure you have some sort of webserver available where you going to store your binary file for the OTA. Myself, I have downloaded XAMPP on windows and store my binary files there, but there are many options available.
Hi, I tried your code, but it always reaches 90% and then it gives me an error. I have a private webserver, but I also tried altervista, I always have the same problem.
Could this be an issue due to the size of a binary you are trying to flash? OTA has some limitations especially if its a huge binary. Have you tried to play with changing the size of OTA ? Also, you can eliminate this by trying to flash some led blink or small binary program.
Does it return you any error message?
Yes, I tried with small 100k files but I have the same error. My bin is 660k
Yes, I tried with small 100k files but I have the same error. My bin is 660k
I see. Thats unfortunate.. What GSM are you using? Have you tried to just read the whole binary file and not do the OTA and see if you can read the whole binary? Instead of updateFromFS try to read your binary
readFile(SPIFFS, "/update.bin");
//updateFromFS(); // comment this out
Hi krupis, thank you very much for your support. I found the problem. It was a mistake in my code. The update took place while the mqtt communication was still active. I have stopped all active clients first, then I start the update process and everything works. Thanks so much!
Glad you found the issue.
Hello. Here is the code to perform OTA over the GSM:
#include <Update.h> #define TINY_GSM_MODEM_SIM800 // Increase RX buffer #define TINY_GSM_RX_BUFFER 1030 const char apn[] = "omnitel"; const char user[] = "omni"; const char pass[] = "omni"; #define MODEM_RST 5 #define MODEM_PWRKEY 4 #define MODEM_POWER_ON 23 #define MODEM_TX 27 #define MODEM_RX 26 #define LED_GPIO 13 #define LED_ON HIGH #define LED_OFF LOW #define SerialAT Serial1 #include <TinyGsmClient.h> #include <CRC32.h> #include "FS.h" #include "SPIFFS.h" #ifdef DUMP_AT_COMMANDS #include <StreamDebugger.h> StreamDebugger debugger(SerialAT, Serial); TinyGsm modem(debugger); #else TinyGsm modem(SerialAT); #endif TinyGsmClient client(modem); const char server[] = "myesptestserver.ddns.net"; const int port = 80; const char resource[] = "/esp.bin"; //here de bin file uint32_t knownCRC32 = 0x6f50d767; uint32_t knownFileSize = 1024; // In case server does not send it void setup() { SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX); // Set console baud rate Serial.begin(115200); setupModem(); delay(10); if (!SPIFFS.begin(true)) { Serial.println("SPIFFS Mount Failed"); return; } SPIFFS.format(); listDir(SPIFFS, "/", 0); // Set GSM module baud rate delay(3000); // Restart takes quite some time // To skip it, call init() instead of restart() Serial.println("Initializing modem..."); modem.restart(); String modemInfo = modem.getModemInfo(); Serial.print("Modem: "); Serial.println(modemInfo); // Unlock your SIM card with a PIN //modem.simUnlock("1234"); } void loop() { Serial.print("Waiting for network..."); if (!modem.waitForNetwork()) { Serial.println(" fail"); delay(10000); return; } Serial.println(" OK"); Serial.print("Connecting to "); Serial.print(apn); if (!modem.gprsConnect(apn, user, pass)) { Serial.println(" fail"); delay(10000); return; } Serial.println(" OK"); Serial.print("Connecting to "); Serial.print(server); // if you get a connection, report back via serial: if (!client.connect(server, port)) { Serial.println(" fail"); delay(10000); return; } Serial.println(" OK"); // Make a HTTP request: client.print(String("GET ") + resource + " HTTP/1.0\r\n"); client.print(String("Host: ") + server + "\r\n"); client.print("Connection: close\r\n\r\n"); long timeout = millis(); while (client.available() == 0) { if (millis() - timeout > 5000L) { Serial.println(">>> Client Timeout !"); client.stop(); delay(10000L); return; } } Serial.println("Reading header"); uint32_t contentLength = knownFileSize; File file = SPIFFS.open("/update.bin", FILE_APPEND); while (client.available()) { String line = client.readStringUntil('\n'); line.trim(); //Serial.println(line); // Uncomment this to show response header line.toLowerCase(); if (line.startsWith("content-length:")) { contentLength = line.substring(line.lastIndexOf(':') + 1).toInt(); } else if (line.length() == 0) { break; } } timeout = millis(); uint32_t readLength = 0; CRC32 crc; unsigned long timeElapsed = millis(); printPercent(readLength, contentLength); while (readLength < contentLength && client.connected() && millis() - timeout < 10000L) { int i = 0; while (client.available()) { // read file data to spiffs if (!file.print(char(client.read()))) { Serial.println("Appending file"); } //Serial.print((char)c); // Uncomment this to show data //crc.update(c); readLength++; if (readLength % (contentLength / 13) == 0) { printPercent(readLength, contentLength); } timeout = millis(); } } file.close(); printPercent(readLength, contentLength); timeElapsed = millis() - timeElapsed; Serial.println(); client.stop(); Serial.println("stop client"); modem.gprsDisconnect(); Serial.println("gprs disconnect"); Serial.println(); float duration = float(timeElapsed) / 1000; /* Serial.print("Tamaño de Archivo: "); Serial.println(contentLength); Serial.print("Leido: "); Serial.println(readLength); Serial.print("Calculado. CRC32: 0x"); Serial.println(crc.finalize(), HEX); Serial.print("Conocido CRC32: 0x"); Serial.println(knownCRC32, HEX); Serial.print("Bajado en: "); Serial.print(duration); Serial.println("s"); Serial.println("Se genera una espera de 3 segundos"); for (int i = 0; i < 3; i++) { Serial.print(String(i) + "..."); delay(1000); } */ //readFile(SPIFFS, "/update.bin"); updateFromFS(); // Do nothing forevermore while (true) { delay(1000); } } void appendFile(fs::FS &fs, const char *path, const char *message) { Serial.printf("Appending to file: %s\n", path); File file = fs.open(path, FILE_APPEND); if (!file) { Serial.println("Failed to open file for appending"); return; } if (file.print(message)) { Serial.println("APOK"); } else { Serial.println("APX"); } } void readFile(fs::FS &fs, const char *path) { Serial.printf("Reading file: %s\n", path); File file = fs.open(path); if (!file || file.isDirectory()) { Serial.println("Failed to open file for reading"); return; } Serial.print("Read from file: "); while (file.available()) { Serial.write(file.read()); delayMicroseconds(100); } } void writeFile(fs::FS &fs, const char *path, const char *message) { Serial.printf("Writing file: %s\n", path); File file = fs.open(path, FILE_WRITE); if (!file) { Serial.println("Failed to open file for writing"); return; } if (file.print(message)) { Serial.println("File written"); } else { Serial.println("Write failed"); } } void listDir(fs::FS &fs, const char *dirname, uint8_t levels) { Serial.printf("Listing directory: %s\n", dirname); File root = fs.open(dirname); if (!root) { Serial.println("Failed to open directory"); return; } if (!root.isDirectory()) { Serial.println("Not a directory"); return; } File file = root.openNextFile(); while (file) { if (file.isDirectory()) { Serial.print(" DIR : "); Serial.println(file.name()); if (levels) { listDir(fs, file.name(), levels - 1); } } else { Serial.print(" FILE: "); Serial.print(file.name()); Serial.print(" SIZE: "); Serial.println(file.size()); } file = root.openNextFile(); } } void deleteFile(fs::FS &fs, const char *path) { Serial.printf("Deleting file: %s\n", path); if (fs.remove(path)) { Serial.println("File deleted"); } else { Serial.println("Delete failed"); } } void updateFromFS() { File updateBin = SPIFFS.open("/update.bin"); if (updateBin) { if (updateBin.isDirectory()) { Serial.println("Directory error"); updateBin.close(); return; } size_t updateSize = updateBin.size(); if (updateSize > 0) { Serial.println("Starting update"); performUpdate(updateBin, updateSize); } else { Serial.println("Error, archivo vacío"); } updateBin.close(); // whe finished remove the binary from sd card to indicate end of the process //fs.remove("/update.bin"); } else { Serial.println("no such binary"); } } void performUpdate(Stream &updateSource, size_t updateSize) { if (Update.begin(updateSize)) { size_t written = Update.writeStream(updateSource); if (written == updateSize) { Serial.println("Writes : " + String(written) + " successfully"); } else { Serial.println("Written only : " + String(written) + "/" + String(updateSize) + ". Retry?"); } if (Update.end()) { Serial.println("OTA finished!"); if (Update.isFinished()) { Serial.println("Restart ESP device!"); ESP.restart(); } else { Serial.println("OTA not fiished"); } } else { Serial.println("Error occured #: " + String(Update.getError())); } } else { Serial.println("Cannot beggin update"); } } void printPercent(uint32_t readLength, uint32_t contentLength) { // If we know the total length if (contentLength != -1) { Serial.print("\r "); Serial.print((100.0 * readLength) / contentLength); Serial.print('%'); } else { Serial.println(readLength); } } void setupModem() { #ifdef MODEM_RST // Keep reset high pinMode(MODEM_RST, OUTPUT); digitalWrite(MODEM_RST, HIGH); #endif pinMode(MODEM_PWRKEY, OUTPUT); pinMode(MODEM_POWER_ON, OUTPUT); // Turn on the Modem power first digitalWrite(MODEM_POWER_ON, HIGH); // Pull down PWRKEY for more than 1 second according to manual requirements digitalWrite(MODEM_PWRKEY, HIGH); delay(100); digitalWrite(MODEM_PWRKEY, LOW); delay(1000); digitalWrite(MODEM_PWRKEY, HIGH); // Initialize the indicator as an output pinMode(LED_GPIO, OUTPUT); digitalWrite(LED_GPIO, LED_OFF); }
Make sure to change accordingle the following lines of code:
const char apn[] = "omnitel"; const char user[] = "omni"; const char pass[] = "omni";
and
const char server[] = "myesptestserver.ddns.net"; const int port = 80; const char resource[] = "/esp.bin"; //here de bin file
For storing the bin files, you have multiple choises.
- Use Raspberry pi as a server ( I have created a simple apache server where I uploaded my binary file, and then I can access that server through the following sketch.
However, for testing it maybe be easier to setup Xampp on windows machine just to see whether you can get it to work. 2. Create an apache or simmilar server on your windows machine ( probably the simplest method would be to use Xampp as it does everything for you. In the xampp folder you will have htdocs folder where you can put your binary. and you can access that binary by using my sketch or your own sketch
const char server[] = "myesptestserver.ddns.net"; // ip of server or web address const int port = 80; const char resource[] = "/esp.bin"; // put your binary file name
Let me know if you have any more questions
@krupis Hi krupis, I'm ok with esp32 coding side. But I have no idea to configure xamp server and where to store the .bin file in the server. How can I do this? Can you share any reference for this? Thanks in advance.
@Mohamed-ali1998 Hey mate. The binary should be stored inside htdocs folder where you have installed XAMP. There should be no additionall setup required apart from starting the XAMPP services. Also, keep in mind that in order to perfrom GSM OTA, you will need to port forward the IP address. I have used some free domain service. The reason is because the GSM is not connected to your home network and will not be able to reach your local computer IP address.
@krupis Hi krupis. I used our own server. That's working fine. Thank you so much.
@krupis Hi everyone. I tried @krupis solution but have some issues (it seems to work but...):
Setup
- Zorin OS 15.3
- Arduino IDE 1.8.15
- Board: DOIT ESP32 DEVKIT V1
- File size: 198944 byte
I use the secure version ( TinyGSMClientSecure) of TinyGSM due to our server configs..
The .bin file download stop at 99.34% (~197630) and start the update. So it failed and return Error 9 (UPDATE_ERROR_ACTIVATE). Below is the print on serial monitor
17:32:39.384 -> Reading header
17:32:40.382 ->
0.00%
7.69%
15.38%
23.08%
30.77%
38.46%
46.15%
53.84%
61.54%
69.23%
76.92%
84.61%
92.31%
99.33%
17:36:54.214 -> stop client
17:36:54.580 -> gprs disconnect
17:36:54.580 ->
17:36:54.580 -> Starting update
17:36:57.475 -> Writes : 197621 successfully
17:36:57.608 -> E (311078) esp_image: Checksum failed. Calculated 0x54 read 0xff
17:36:57.675 -> Error occured #: 9
17:36:57.675 -> END
So a help or an idea about ? Thanks and great code!
@TawalMc Hello. I dont think I can help you with this issue but @gunter72 had a simillar problem.
Before you do anything else, I would try 2 things
- Try with small binary
- Isolate the rest of your code just to confirm if GSM OTA part is working. If it does, then start adding your other code bit by bit and see which part cause the issues.
Nj
On Fri, Oct 15, 2021, 6:33 PM krupis @.***> wrote:
Hello. I dont think I can help you with this issue but @gunter72 https://github.com/gunter72 had a simillar problem.
Before you do anything else, I would try 2 things
- Try with small binary
- Isolate the rest of your code just to confirm if GSM OTA part is working. If it does, then start adding your other code bit by bit and see which part cause the issues.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/Xinyuan-LilyGO/LilyGo-T-Call-SIM800/issues/132#issuecomment-944475980, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHXC4BBKQPEF6GYYQ3X6TMLUHBQXTANCNFSM42SG5BMA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.
@TawalMc Hello. I dont think I can help you with this issue but @gunter72 had a simillar problem.
Before you do anything else, I would try 2 things
- Try with small binary
- Isolate the rest of your code just to confirm if GSM OTA part is working. If it does, then start adding your other code bit by bit and see which part cause the issues.
Thanks. I'll try them. Good
@TawalMc Hello. I dont think I can help you with this issue but @gunter72 had a simillar problem. Before you do anything else, I would try 2 things
- Try with small binary
- Isolate the rest of your code just to confirm if GSM OTA part is working. If it does, then start adding your other code bit by bit and see which part cause the issues.
Thanks. I'll try them. Good
Hello, i am getting same error#9, any luck ?
f
@TawalMc Hello. I dont think I can help you with this issue but @gunter72 had a simillar problem. Before you do anything else, I would try 2 things
- Try with small binary
- Isolate the rest of your code just to confirm if GSM OTA part is working. If it does, then start adding your other code bit by bit and see which part cause the issues.
Thanks. I'll try them. Good
Hello, i am getting same error#9, any luck ?
I get same error sometimes.Sometime it works.Could you find any solution?
f
@TawalMc Hello. I dont think I can help you with this issue but @gunter72 had a simillar problem. Before you do anything else, I would try 2 things
- Try with small binary
- Isolate the rest of your code just to confirm if GSM OTA part is working. If it does, then start adding your other code bit by bit and see which part cause the issues.
Thanks. I'll try them. Good
Hello, i am getting same error#9, any luck ?
I get same error sometimes.Sometime it works.Could you find any solution?
in my case the success rate was so high (2 fails out of 20) few hours after midnight, so I deduced It is due to network being hogged during the day
in my case the success rate was so high (2 fails out of 20) few hours after midnight, so I deduced It is due to network being hogged during the day
this morning I upload the code and it updated but after that I created new bin file and it gave me error.The error is E (342241) esp_image: invalid segment length 0x2d832b6.
f
@TawalMc Hello. I dont think I can help you with this issue but @gunter72 had a simillar problem. Before you do anything else, I would try 2 things
- Try with small binary
- Isolate the rest of your code just to confirm if GSM OTA part is working. If it does, then start adding your other code bit by bit and see which part cause the issues.
Thanks. I'll try them. Good
Hello, i am getting same error#9, any luck ?
I get same error sometimes.Sometime it works.Could you find any solution?
in my case the success rate was so high (2 fails out of 20) few hours after midnight, so I deduced It is due to network being hogged during the day
Should I change these settings?