// FactoryTestをWebからダウンロードして書き込む
// 参考:https://lang-ship.com/blog/work/m5stickc-web-update-ota/
#include <WiFi.h>
#include <Update.h>
const char *ssid0 = "ics-ap"; // 802.11b/g (2.4GHz)only. 5GHz is not supported.
const char *password0 = "jikkenics";
WiFiClient client;
void execOTA(String host, int port, String bin);
void lcdprintln(String mes, uint16_t color, int y)
{
if (y == 0)
M5.Lcd.fillScreen(color);
if (y < 999)
M5.Lcd.setCursor(0, y, 4);
M5.Lcd.setTextColor(BLACK, color);
M5.Lcd.println(mes);
}
void start_WebOTA()
{
// M5.begin();
// M5.Lcd.setRotation(3);
lcdprintln(" -- WebOTA --\n\n wifi connecting...", ORANGE, 0);
WiFi.begin(ssid0, password0); // 接続開始
int count = 50;
M5.Speaker.tone(2000, 200);
M5.delay(500);
while (WiFi.status() != WL_CONNECTED)
{ // 接続中...
M5.Speaker.tone(2000, 200);
M5.delay(200);
M5.delay(1000);
M5.Lcd.print(".");
count--;
if (count < 1)
{
break;
}
}
if (count > 0)
{
// 接続完了!!
M5.Speaker.tone(4000, 1500);
lcdprintln(" Wifi Connected!\n ", GREEN, 0);
String gotip = WiFi.localIP().toString(); // m5デバイスのIPアドレス
M5.Lcd.println(gotip);
String host = "cit.istlab.info";
int port = 80;
String bin = "/f/FactoryTest.ino.bin";
execOTA(host, port, bin);
} else {
wifi_down();
}
}
// Utility to extract header value from headers
String getHeaderValue(String header, String headerName)
{
return header.substring(strlen(headerName.c_str()));
}
// OTA Logic
void execOTA(String host, int port, String bin)
{
// Connection Succeed
Serial.println("");
Serial.println("Connected to Wi-Fi");
long contentLength = 0;
bool isValidContentType = false;
lcdprintln(" Downloading...", YELLOW, 0);
if (client.connect(host.c_str(), port))
{
Serial.println("Fetching Bin: " + String(bin));
client.print(String("GET ") + bin + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Cache-Control: no-cache\r\n" +
"Connection: close\r\n\r\n");
unsigned long timeout = millis();
while (client.available() == 0)
{
if (millis() - timeout > 5000)
{
Serial.println("Client Timeout !");
client.stop();
return;
}
}
while (client.available())
{
String line = client.readStringUntil('\n');
line.trim();
if (!line.length())
{
break;
}
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;
}
}
if (line.startsWith("Content-Length: "))
{
contentLength = atol((getHeaderValue(line, "Content-Length: ")).c_str());
Serial.println("Got " + String(contentLength) + " bytes from server");
}
if (line.startsWith("Content-Type: "))
{
String contentType = getHeaderValue(line, "Content-Type: ");
Serial.println("Got " + contentType + " payload.");
if (contentType == "application/octet-stream")
{
isValidContentType = true;
}
}
}
}
else
{
Serial.println("Connection to " + String(host) + " failed. Please check your setup");
}
Serial.println("contentLength : " + String(contentLength) + ", isValidContentType : " + String(isValidContentType));
if (contentLength && isValidContentType)
{
bool canBegin = Update.begin(contentLength);
if (canBegin)
{
lcdprintln(" Downloaded.\n Upgrading...(wait 2-3 min.)", GREENYELLOW, 999);
Serial.println("Begin OTA. This may take 2 - 5 mins to complete. Things might be quite for a while.. Patience!");
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())
{
M5.Speaker.tone(4000, 2000);
lcdprintln("\n\n OTA Done. \n shutdown now", GREENYELLOW, 0);
M5.delay(2000);
Serial.println("OTA done!");
if (Update.isFinished())
{
Serial.println("Update successfully completed. Rebooting.");
// ESP.restart();
esp_restart(); // 再起動
}
else
{
Serial.println("Update not finished? Something went wrong!");
}
}
else
{
Serial.println("Error Occurred. Error #: " + String(Update.getError()));
}
}
else
{
Serial.println("Not enough space to begin OTA");
client.flush();
}
}
else
{
Serial.println("There was no content in the response");
client.flush();
}
}