I have build a letterbox to use for geocaching.
i have manged to get it to work properly except for OTA.
I am using an MH-ET Live ESP-WROOM-32.
and using SPIFFS for imaging.
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1288
load:0x40078000,len:13872
load:0x40080400,len:4
ho 8 tail 4 room 4
load:0x40080404,len:3048
entry 0x40080590
[ 3][D][esp32-hal-cpu.c:264] setCpuFrequencyMhz(): PLL: 480 / 2 = 240 Mhz, APB: 80000000 Hz
=========== Before Setup Start ===========
Chip Info:
------------------------------------------
Model : ESP32
Package : D0WD-Q5
Revision : 1.44
Cores : 2
Frequency : 240 MHz
Embedded Flash : No
Embedded PSRAM : No
2.4GHz WiFi : Yes
Classic BT : Yes
BT Low Energy : Yes
IEEE 802.15.4 : No
------------------------------------------
INTERNAL Memory Info:
------------------------------------------
Total Size : 343756 B ( 335.7 KB)
Free Bytes : 313464 B ( 306.1 KB)
Allocated Bytes : 23212 B ( 22.7 KB)
Minimum Free Bytes: 308084 B ( 300.9 KB)
Largest Free Block: 110580 B ( 108.0 KB)
------------------------------------------
Flash Info:
------------------------------------------
Chip Size : 4194304 B (4 MB)
Block Size : 65536 B ( 64.0 KB)
Sector Size : 4096 B ( 4.0 KB)
Page Size : 256 B ( 0.2 KB)
Bus Speed : 80 MHz
Bus Mode : DIO
------------------------------------------
Partitions Info:
------------------------------------------
nvs : addr: 0x00009000, size: 20.0 KB, type: DATA, subtype: NVS
otadata : addr: 0x0000E000, size: 8.0 KB, type: DATA, subtype: OTA
app0 : addr: 0x00010000, size: 1920.0 KB, type: APP, subtype: OTA_0
app1 : addr: 0x001F0000, size: 1920.0 KB, type: APP, subtype: OTA_1
spiffs : addr: 0x003D0000, size: 128.0 KB, type: DATA, subtype: SPIFFS
coredump : addr: 0x003F0000, size: 64.0 KB, type: DATA, subtype: COREDUMP
------------------------------------------
Software Info:
------------------------------------------
Compile Date/Time : Jun 4 2024 20:24:43
Compile Host OS : windows
ESP-IDF Version : v5.1.4-51-g442a798083-dirty
Arduino Version : 3.0.0
------------------------------------------
Board Info:
------------------------------------------
Arduino Board : MH_ET_LIVE_ESP32MINIKIT
Arduino Variant : mhetesp32minikit
Arduino FQBN : esp32:esp32:mhetesp32minikit:FlashFreq=80,PartitionScheme=min_spiffs,UploadSpeed=921600,DebugLevel=debug,EraseFlash=all
============ Before Setup End ============
Setup started.
AP IP address: 192.168.4.1
[ 621][D][AP.cpp:88] _onApArduinoEvent(): Arduino AP Event: 19 - AP_START
HTTP server started
=========== After Setup Start ============
INTERNAL Memory Info:
------------------------------------------
Total Size : 343756 B ( 335.7 KB)
Free Bytes : 256312 B ( 250.3 KB)
Allocated Bytes : 77172 B ( 75.4 KB)
Minimum Free Bytes: 255632 B ( 249.6 KB)
Largest Free Block: 110580 B ( 108.0 KB)
------------------------------------------
GPIO Info:
------------------------------------------
GPIO : BUS_TYPE[bus/unit][chan]
--------------------------------------
1 : UART_TX[0]
3 : UART_RX[0]
14 : GPIO
25 : GPIO
26 : GPIO
27 : GPIO
============ After Setup End =============
This is my sketch
#include <WiFi.h>
#include <WebServer.h>
#include <SPIFFS.h>
#include <Update.h>
const char* ssid = "Geocache_WiFi";
const char* password = "password";
WebServer server(80);
#define RED_PIN 14
#define GREEN_PIN 27
#define BLUE_PIN 26
#define COIL_PIN 25
const String correctCode = "313";
unsigned long coilActivatedTime = 0;
bool coilActivated = false;
bool shouldRestart = false;
unsigned long restartTimer = 0;
void handleRoot() {
String page = "<html><head><style>";
page += "body { font-size: 24px; }";
page += "h1 { font-size: 36px; }";
page += "p { font-size: 24px; }";
page += "</style></head><body>";
page += "<h1>Geocache Access Point</h1>";
page += "<p>Voer het kenteken in van de auto van Donald Duck om de cache te openen:</p>";
page += "<form action='/check' method='POST'><input name='code' type='text'><input type='submit'></form>";
page += "<br><img src='/image.jpg' alt='Geocache Image'>";
page += "<script>";
page += "if(window.location.hostname !== '192.168.4.1') { window.location.href = 'http://192.168.4.1'; }";
page += "</script>";
page += "</body></html>";
server.send(200, "text/html", page);
}
void handleImage() {
File file = SPIFFS.open("/image.jpg", "r");
if (!file) {
server.send(404, "text/plain", "File not found");
return;
}
server.streamFile(file, "image/jpeg");
file.close();
}
void handleSuccessImage() {
File file = SPIFFS.open("/success.jpg", "r");
if (!file) {
server.send(404, "text/plain", "File not found");
return;
}
server.streamFile(file, "image/jpeg");
file.close();
}
void handleOopsImage() {
File file = SPIFFS.open("/oops.jpg", "r");
if (!file) {
server.send(404, "text/plain", "File not found");
return;
}
server.streamFile(file, "image/jpeg");
file.close();
}
void handleCheck() {
if (server.hasArg("code") && server.arg("code") == correctCode) {
digitalWrite(GREEN_PIN, HIGH);
digitalWrite(RED_PIN, LOW);
digitalWrite(BLUE_PIN, LOW);
digitalWrite(COIL_PIN, HIGH);
coilActivatedTime = millis();
coilActivated = true;
String page = "<html><body style='font-size:24px;'>";
page += "<h1>Correct code!</h1>";
page += "<p>Gefeliciteerd!<br>De cache is nu geopend en wordt gereset na 30 seconden.<br>Zou u de klep voorzichtig willen sluiten.</p>";
page += "<img src='/success.jpg' alt='Success Image'>";
page += "<br><br><a href='/'>Terug</a>";
page += "</body></html>";
server.send(200, "text/html", page);
} else {
String page = "<html><body style='font-size:24px;'>";
page += "<h1>Incorrect code!</h1>";
page += "<p>Probeer het opnieuw.</p>";
page += "<form action='/check' method='POST'><input name='code' type='text'><input type='submit'></form>";
page += "<img src='/oops.jpg' alt='Oops Image'>";
page += "<br><br><a href='/'>Terug</a>";
page += "</body></html>";
server.send(200, "text/html", page);
}
}
void handleOTAUpdate() {
String page = "<html><body style='font-size:24px;'>";
page += "<h1>OTA Update</h1>";
page += "<form method='POST' action='/update' enctype='multipart/form-data'>";
page += "<input type='file' name='update'>";
page += "<input type='submit' value='Update'>";
page += "</form>";
page += "</body></html>";
server.send(200, "text/html", page);
}
void handleUpdate() {
HTTPUpload& upload = server.upload();
if (upload.status == UPLOAD_FILE_START) {
if (!Update.begin(UPDATE_SIZE_UNKNOWN)) { // start with max available size
Update.printError(Serial);
}
} else if (upload.status == UPLOAD_FILE_WRITE) {
if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
Update.printError(Serial);
}
} else if (upload.status == UPLOAD_FILE_END) {
if (Update.end(true)) { // true to set the size to the current progress
server.sendHeader("Connection", "close");
server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
shouldRestart = true;
restartTimer = millis();
} else {
Update.printError(Serial);
}
} else {
Update.printError(Serial);
server.sendHeader("Connection", "close");
server.send(200, "text/plain", "FAIL");
}
}
void setup() {
pinMode(RED_PIN, OUTPUT);
pinMode(GREEN_PIN, OUTPUT);
pinMode(BLUE_PIN, OUTPUT);
pinMode(COIL_PIN, OUTPUT);
Serial.begin(115200);
if (!SPIFFS.begin(true)) {
return;
}
WiFi.softAP(ssid, password);
IPAddress IP = WiFi.softAPIP();
server.on("/", handleRoot);
server.on("/image.jpg", handleImage); // Serve the image from SPIFFS
server.on("/success.jpg", handleSuccessImage); // Serve the success image from SPIFFS
server.on("/oops.jpg", handleOopsImage); // Serve the oops image from SPIFFS
server.on("/check", HTTP_POST, handleCheck);
server.on("/ota-update", handleOTAUpdate);
server.on("/update", HTTP_POST, handleUpdate);
server.begin();
}
void loop() {
static unsigned long lastBlink = 0;
static bool ledState = false;
unsigned long currentMillis = millis();
// Check if any devices are connected
if (WiFi.softAPgetStationNum() > 0) {
if (!coilActivated) {
// Blink the blue LED if a device is connected and the coil is not activated
if (currentMillis - lastBlink >= 250) {
lastBlink = currentMillis;
ledState = !ledState;
digitalWrite(BLUE_PIN, ledState ? HIGH : LOW);
digitalWrite(RED_PIN, LOW);
digitalWrite(GREEN_PIN, LOW);
}
}
} else {
// Blink the red LED if no devices are connected
if (currentMillis - lastBlink >= 500) {
lastBlink = currentMillis;
ledState = !ledState;
digitalWrite(RED_PIN, ledState ? HIGH : LOW);
digitalWrite(BLUE_PIN, LOW);
digitalWrite(GREEN_PIN, LOW);
}
}
// Check if the coil has been activated for more than 30 seconds
if (coilActivated && (currentMillis - coilActivatedTime >= 30000)) {
digitalWrite(COIL_PIN, LOW);
digitalWrite(GREEN_PIN, LOW);
coilActivated = false;
}
// Handle OTA restart after blinking LEDs
if (shouldRestart) {
if (currentMillis - restartTimer >= 10000) {
ESP.restart();
} else {
// Blink blue and green LEDs alternately to indicate successful OTA update
if (currentMillis - lastBlink >= 250) {
lastBlink = currentMillis;
ledState = !ledState;
digitalWrite(GREEN_PIN, ledState ? HIGH : LOW);
digitalWrite(BLUE_PIN, !ledState ? HIGH : LOW);
}
}
}
server.handleClient();
}
The page "192.168.4.1/ota-update" is working, i can select the *.bin file.
only when i press the button "update" the bin file dus not getting flashed.
Can some one of you can help mee with this??