// FactoryTestをWebからダウンロードして書き込む // 参考:https://lang-ship.com/blog/work/m5stickc-web-update-ota/ #include <M5StickCPlus.h> #include <WiFi.h> #include <Update.h> const char *ssid = "ics-ap"; // 802.11b/g (2.4GHz)only. 5GHz is not supported. const char *password = "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 setup() { M5.begin(); M5.Lcd.setRotation(3); lcdprintln(" -- WebOTA --\n\n wifi connecting...", ORANGE, 0); WiFi.begin(ssid, password); // 接続開始 while (WiFi.status() != WL_CONNECTED) { // 接続中... M5.Beep.tone(2000); delay(200); M5.Beep.mute(); delay(1000); M5.Lcd.print("."); } // 接続完了!! M5.Beep.tone(4000); lcdprintln(" Wifi Connected!\n ", GREEN, 0); String gotip = WiFi.localIP().toString(); // m5デバイスのIPアドレス M5.Lcd.println(gotip); delay(1500); M5.Beep.mute(); String host = "cit.istlab.info"; int port = 80; String bin = "/f/M5StickCPlus_FactoryTest2022.ino.bin"; execOTA(host, port, bin); } void loop() { } // 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.Beep.tone(4000); lcdprintln("\n\n OTA Done. \n shutdown now", GREENYELLOW, 0); delay(2000); M5.Beep.mute(); Serial.println("OTA done!"); if (Update.isFinished()) { Serial.println("Update successfully completed. Rebooting."); // ESP.restart(); M5.Axp.Write1Byte(0x32, M5.Axp.Read8bit(0x32) | 0x80); // 電源OFF } 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(); } }