Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MkLHX/93530466c859172b81f35022cab7cd14 to your computer and use it in GitHub Desktop.
Save MkLHX/93530466c859172b81f35022cab7cd14 to your computer and use it in GitHub Desktop.
/**
*2018-10-24 Mickael Lehoux
*
*PlatformIO project
*//main.cpp
*
*ESP32's SD files are expose through HTTP web server
*
*/
#include "main.h"
#include "FS.h"
#include "SD.h"
#include "ESP32WebServer.h"
ESP32WebServer webServer(80);
// Functions declarations
void wifiManager(char *ssid, char *pwd);
void streamBinaryFile();
void streamFileFromSD(String uriParam);
void downloadBinaryFile();
void downloadFileFromSD(String uriParam);
// Define CS pin for the SD card module
#define SD_CS 5
void setup()
{
Serial.begin(115200);
// Connect to the WiFi
wifiManager("your_ssid", "your_password");
// SD card Initialization
// Make SD card always run -> add pull-up on MISO pin
#ifdef ESP32
//Serial.println(MISO);
pinMode(19, INPUT_PULLUP);
#endif
SD.begin(SD_CS);
if (!SD.begin(SD_CS))
{
Serial.println("Card Mount Failed");
delay(1000);
ESP.restart();
}
uint8_t cardType = SD.cardType();
if (cardType == CARD_NONE)
{
Serial.println("No SD card attached");
delay(1000);
ESP.restart();
}
Serial.println("Initializing SD card...");
if (!SD.begin(SD_CS))
{
Serial.println("ERROR - SD card initialization failed!");
delay(1000);
ESP.restart();
}
Serial.println("SD card initialized");
webServer.on("/streamBinaryFile", streamBinaryFile);
webServer.on("/downloadBinaryFile", downloadBinaryFile);
webServer.begin();
Serial.println("HTTP Server started");
}
void loop()
{
delay(1000);
Serial.print(".");
webServer.handleClient();
}
void wifiManager(char *ssid, char *pwd)
{
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, pwd);
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(F("."));
delay(250);
}
Serial.println();
Serial.print(F("Connected to Wifi : "));
Serial.println(WiFi.SSID());
Serial.print(F("WiFi IP address: "));
Serial.println(WiFi.localIP());
}
void streamBinaryFile()
{
Serial.println("streamBinaryFile function start");
// Check if there are some arguments from the GET request
if (webServer.args() > 0)
{
// Find uriParam argument from request
if (webServer.hasArg("uriParam"))
{
streamFileFromSD(String(webServer.arg(0)));
}
}
}
void streamFileFromSD(String uriParam)
{
Serial.println("streamFileFromSD function start");
// Read firmware binary file from SD Card
File firmwareFile = SD.open("/" + uriParam + "/firmware.bin", FILE_READ);
if (firmwareFile)
{
Serial.println("file is opened");
// If data is available and present
webServer.sendHeader("Content-Disposition", "attachment; filename=firmware.bin");
webServer.sendHeader("Connection", "close");*/
size_t dataSent = webServer.streamFile(firmwareFile, "application/octet-stream");
}
else
{
Serial.println("Error on openning file : /" + uriParam + "/firmware.bin");
}
return;
}
/**
*2018-10-24 Mickael Lehoux
*
*PlatformIO project
*//main.cpp
*
*Used to download firmware to ESP32 from and other ESP32 SD card
*Base on the example of arduino-ESP32 example Update
*https://github.com/espressif/arduino-esp32/tree/master/libraries/Update/examples
*
*/
#include "main.h"
#include "ESP32WebServer.h"
ESP32WebServer webServer(80);
void startUpdate();
void setup()
{
Serial.begin(115200);
wifiManager("your-ssid", "your_password");
webServer.on("/update", startUpdate);
webServer.begin();
}
void loop()
{
delay(1000);
Serial.print(".");
webServer.handleClient();
}
void startUpdate()
{
ota_update();
}
void wifiManager(char *ssid, char *pwd)
{
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, pwd);
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(F("."));
delay(250);
}
Serial.println();
Serial.print(F("Connected to Wifi : "));
Serial.println(WiFi.SSID());
Serial.print(F("WiFi IP address: "));
Serial.println(WiFi.localIP());
}
#include "Arduino.h"
#include "ota_update.h"
#include "WiFi.h"
#define FW_VERSION "0.0.66"
/**
*2018-10-24 Mickael Lehoux
*
*PlatformIO project
*//ota_update.cpp
*
*Base on the example of arduino-ESP32 example Update
*https://github.com/espressif/arduino-esp32/tree/master/libraries/Update/examples
*
#include "main.h"
#include "ota_update.h"
#include "Update.h"
int contentLength = 0;
bool isValidContentType = false;
// Utility to extract header value from headers
String getHeaderValue(String header, String headerName)
{
return header.substring(strlen(headerName.c_str()));
}
void ota_update()
{
Serial.println("Preparing to update");
String host = "other-esp32-ip-address";
String arg = "?uriParam=my-product";
String fwUrl = "/downloadBinaryFile" + arg;
WiFiClient client;
if (client.connect(host.c_str(), 80))
{
Serial.print("connected to : ");
Serial.println(host+fwUrl);
// Make a HTTP request to the server
client.println("GET " + fwUrl + " HTTP/1.1"); // change resource to get here
client.println("Host: " + host); // change resource host here
client.println("Cache-Control: no-cache");
client.println("Connection: close");
client.println();
while (client.connected())
{
Serial.println("Client available");
// read line till /n
String line = client.readStringUntil('\n');
// remove space, to check if the line is end of headers
line.trim();
// if the the line is empty,
// this is end of headers
// break the while and feed the
// remaining `client` to the
// Update.writeStream();
if (!line.length())
{
//headers ended
break; // and get the OTA started
}
// Check if the HTTP Response is 200
// else break and Exit Update
if (line.startsWith("HTTP/1.1"))
{
if (line.indexOf("200") < 0)
{
Serial.println("Got a non 200 status code from server. Exiting OTA Update.");
break;
}
}
// extract headers here
// Start with content length
if (line.startsWith("Content-Length: "))
{
contentLength = atoi((getHeaderValue(line, "Content-Length: ")).c_str());
Serial.println("Got " + String(contentLength) + " bytes from server");
}
// Next, the content type
if (line.startsWith("Content-Type: "))
{
String contentType = getHeaderValue(line, "Content-Type: ");
Serial.println("Got " + contentType + " payload.");
if (contentType == "application/octet-stream")
{
isValidContentType = true;
}
}
}
}
else
{
// Connect to S3 failed
// May be try?
// Probably a choppy network?
Serial.println("Connection to " + String(host) + " failed. Please check your setup");
// retry??
}
// Check what is the contentLength and if content type is `application/octet-stream`
Serial.println("contentLength : " + String(contentLength) + ", isValidContentType : " + String(isValidContentType));
// check contentLength and content type
if (contentLength && isValidContentType)
{
// Check if there is enough to OTA Update
bool canBegin = Update.begin(contentLength);
// If yes, begin
if (canBegin)
{
Serial.println("Begin OTA. This may take 2 - 5 mins to complete. Things might be quite for a while.. Patience!");
// No activity would appear on the Serial monitor
// So be patient. This may take 2 - 5mins to complete
size_t written = Update.writeStream(client);
if (written == contentLength)
{
Serial.println("Written : " + String(written) + " successfully");
}
else
{
Serial.println("Written only : " + String(written) + "/" + String(contentLength) + ". Retry?");
}
if (Update.end())
{
Serial.println("OTA done!");
if (Update.isFinished())
{
Serial.println("Update successfully completed. Rebooting.");
ESP.restart();
}
else
{
Serial.println("Update not finished? Something went wrong!");
}
}
else
{
Serial.println("Error Occurred. Error #: " + String(Update.getError()));
}
}
else
{
// not enough space to begin OTA
// Understand the partitions and
// space availability
Serial.println("Not enough space to begin OTA");
client.flush();
}
}
else
{
Serial.println("There was no content in the response");
client.flush();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment