Whenever i try to use the 2 cores of my esp, one for OTA and one for the main task, core 0 keeps crashing.
For now just to test, the 'main' code is just an LED on pin 25 going on and off every 5 seconds.
I tried increasing the stack size, but this had zero effect. I'm pretty sure the problem lies with the OTA part of the code as the led turns on and the ESP connects to the wifi correctly.
When i try to use OTA without a separate task on the other core, everything works perfectly.
The error is: "Guru Meditation Error: Core 0 panic'ed (IllegalInstruction)."
Then the ESP32 reboots and crashes again.
This is my code:
#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include <Update.h>
const char* host = "ota32";
const char* ssid = "FrisQuiz";
const char* password = "frisquiz2024";
WebServer server(80);
// Define task handles
TaskHandle_t otaTaskHandle = NULL;
// Define the GPIO pin for the LED
const int ledPin = 25;
/*
* Your main task function
*/
void mainTask(void* pvParameters) {
pinMode(ledPin, OUTPUT);
while (1) {
// Your main task code goes here
digitalWrite(ledPin, HIGH);
Serial.println("Led ON");
delay(5000);
digitalWrite(ledPin, LOW);
Serial.println("Led OFF");
delay(5000);
}
}
void otaUpdateTask(void* pvParameters) {
Serial.println("Entering otaUpdateTask");
// server.handleClient();
delay(1);
}
/*
* Login page
*/
const char* loginIndex =
"<form name='loginForm'>"
"<table width='20%' bgcolor='A09F9F' align='center'>"
"<tr>"
"<td colspan=2>"
"<center><font size=4><b>ESP32 Login Page</b></font></center>"
"<br>"
"</td>"
"<br>"
"<br>"
"</tr>"
"<tr>"
"<td>Username:</td>"
"<td><input type='text' size=25 name='userid'><br></td>"
"</tr>"
"<br>"
"<br>"
"<tr>"
"<td>Password:</td>"
"<td><input type='Password' size=25 name='pwd'><br></td>"
"<br>"
"<br>"
"</tr>"
"<tr>"
"<td><input type='submit' onclick='check(this.form)' value='Login'></td>"
"</tr>"
"</table>"
"</form>"
"<script>"
"function check(form)"
"{"
"if(form.userid.value=='FrisQuizAdmin' && form.pwd.value=='FrisQuiz2024!')"
"{"
"window.open('/serverIndex')"
"}"
"else"
"{"
" alert('Error Password or Username')/*displays error message*/"
"}"
"}"
"</script>";
/*
* Server Index Page
*/
const char* serverIndex =
"<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>"
"<form method='POST' action='#' enctype='multipart/form-data' id='upload_form'>"
"<input type='file' name='update'>"
"<input type='submit' value='Update'>"
"</form>"
"<div id='prg'>progress: 0%</div>"
"<script>"
"$('form').submit(function(e){"
"e.preventDefault();"
"var form = $('#upload_form')[0];"
"var data = new FormData(form);"
" $.ajax({"
"url: '/update',"
"type: 'POST',"
"data: data,"
"contentType: false,"
"processData:false,"
"xhr: function() {"
"var xhr = new window.XMLHttpRequest();"
"xhr.upload.addEventListener('progress', function(evt) {"
"if (evt.lengthComputable) {"
"var per = evt.loaded / evt.total;"
"$('#prg').html('progress: ' + Math.round(per*100) + '%');"
"}"
"}, false);"
"return xhr;"
"},"
"success:function(d, s) {"
"console.log('success!')"
"},"
"error: function (a, b, c) {"
"}"
"});"
"});"
"</script>";
/*
* setup function
*/
void setup(void) {
Serial.begin(115200);
// Connect to WiFi network
WiFi.begin(ssid, password);
Serial.println("");
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
// Set static IP address
IPAddress staticIP(192, 168, 88, 33); // Replace with the desired static IP
IPAddress gateway(192, 168, 88, 1); // Replace with your gateway IP
IPAddress subnet(255, 255, 255, 0); // Replace with your subnet mask
WiFi.config(staticIP, gateway, subnet);
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
// Create a task for OTA updates on Core 0
xTaskCreatePinnedToCore(
otaUpdateTask,
"otaTask",
16384,
NULL,
1,
&otaTaskHandle,
0);
// Create your main task on Core 1
xTaskCreatePinnedToCore(
mainTask, // Task function
"mainTask", // Task name
8192, // Stack size
NULL, // Parameters
1, // Priority (higher number means higher priority)
NULL, // Task handle (not needed for the main task)
1 // Core to run the task on (Core 1)
);
// Rest of your setup code
/*use mdns for host name resolution*/
if (!MDNS.begin(host)) { //http://esp32.local
Serial.println("Error setting up MDNS responder!");
while (1) {
delay(1000);
}
}
Serial.println("mDNS responder started");
server.on("/", HTTP_GET, []() {
server.sendHeader("Connection", "close");
server.send(200, "text/html", loginIndex);
});
server.on("/serverIndex", HTTP_GET, []() {
server.sendHeader("Connection", "close");
server.send(200, "text/html", serverIndex);
});
server.on(
"/update", HTTP_POST, []() {
server.sendHeader("Connection", "close");
server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
ESP.restart();
},
[]() {
HTTPUpload& upload = server.upload();
if (upload.status == UPLOAD_FILE_START) {
Serial.printf("Update: %s\n", upload.filename.c_str());
if (!Update.begin(UPDATE_SIZE_UNKNOWN)) {
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)) {
Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
} else {
Update.printError(Serial);
}
}
});
server.begin();
}
void loop(void) {
server.handleClient();
delay(1);
}