Last active
October 24, 2018 17:52
-
-
Save MkLHX/93530466c859172b81f35022cab7cd14 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
*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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
*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()); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Arduino.h" | |
#include "ota_update.h" | |
#include "WiFi.h" | |
#define FW_VERSION "0.0.66" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
*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