Reputation: 31
So I was trying to create a webserver for lighting up multiple LEDs with an ESP32. The server would send a GET request when a button was held down. This worked previously with only one LED and one button on the HTML page. This code is that, just with more buttons and variables. However, when I upload it to the ESP32 and open Serial Window, I get this:
rst:0xc (SW_CPU_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:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:10944
load:0x40080400,len:6388
entry 0x400806b4
Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x40081041 PS : 0x00060330 A0 : 0x800d1222 A1 : 0x3ffb1f40
A2 : 0x00000004 A3 : 0x00000002 A4 : 0x0800001c A5 : 0x00000003
A6 : 0x00000003 A7 : 0x00000000 A8 : 0x3f401e08 A9 : 0xffffffff
A10 : 0xff4e0000 A11 : 0x00000048 A12 : 0x08000000 A13 : 0x00000003
A14 : 0xffffffff A15 : 0x00000000 SAR : 0x0000001a EXCCAUSE: 0x0000001c
EXCVADDR: 0xff4e0000 LBEG : 0x00000000 LEND : 0x00000000 LCOUNT : 0x00000000
ELF file SHA256: 0000000000000000
Backtrace: 0x40081041:0x3ffb1f40 0x400d121f:0x3ffb1f60 0x400dc8f6:0x3ffb1fb0 0x40089a52:0x3ffb1fd0
Rebooting...
I don't know what this means or what I've done wrong. I've tried:
1 - minimizing the variables (adding unsigned, const, etc. to the prefix of variables)
2 - putting the variables into a local function's scope
Could somebody please help? It would be very much appreciated if you did. (I'm totally new to Arduino programming so I wouldn't know what to do). Here's the code:
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <ArduinoOTA.h>
// Replace with your network credentials
const char* ssid = "SSID_HERE";
const char* password = "PASSWORD_HERE";
const unsigned int outputfw = 2;
const unsigned int outputlt = 4;
const unsigned int outputrt = 7;
const unsigned int outputbw = 6;
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
<title>ESP Web Server</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html {font-family: Arial; display: inline-block; text-align: center;}
h2 {font-size: 3.0rem;}
p {font-size: 3.0rem;}
body {max-width: 600px; margin:0px auto; padding-bottom: 25px;}
.switch {position: relative; display: inline-block; width: 120px; height: 68px}
.switch input {display: none}
.slider {position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; border-radius: 34px}
.slider:before {position: absolute; content: ""; height: 52px; width: 52px; left: 8px; bottom: 8px; background-color: #fff; -webkit-transition: .4s; transition: .4s; border-radius: 68px}
input:checked+.slider {background-color: #2196F3}
input:checked+.slider:before {-webkit-transform: translateX(52px); -ms-transform: translateX(52px); transform: translateX(52px)}
</style>
</head>
<body>
<h2>ESP Web Server</h2>
%BUTTONPLACEHOLDER%
<script>function toggleCheckbox(state, dir) {
console.log("Mouse is ")
console.log(state)
var xhr = new XMLHttpRequest();
if(state){ xhr.open("GET", "/update?" + dir + "=" + state, true); }
else { xhr.open("GET", "/update?" + dir + "=" + state, true); }
xhr.send();
}
document.getElementById("fw").addEventListener("mousedown", function(event) {
toggleCheckbox(true, "fw");
console.log("mouse down.f");
}, false);
document.getElementById("fw").addEventListener("mouseup", function(event) {
toggleCheckbox(false, "fw");
console.log("mouse up.f")
}, false);
document.getElementById("bw").addEventListener("mousedown", function(event) {
toggleCheckbox(true, "bw");
console.log("mouse down.b");
}, false);
document.getElementById("bw").addEventListener("mouseup", function(event) {
toggleCheckbox(false, "bw");
console.log("mouse up.b")
}, false);
document.getElementById("lt").addEventListener("mousedown", function(event) {
toggleCheckbox(true, "lt");
console.log("mouse down.l");
}, false);
document.getElementById("lt").addEventListener("mouseup", function(event) {
toggleCheckbox(false, "lt");
console.log("mouse up.l")
}, false);
document.getElementById("rt").addEventListener("mousedown", function(event) {
toggleCheckbox(true, "rt");
console.log("mouse down.r");
}, false);
document.getElementById("rt").addEventListener("mouseup", function(event) {
toggleCheckbox(false, "rt");
console.log("mouse up.r")
}, false);
</script>
</body>
</html>
)rawliteral";
// Replaces placeholder with button section in your web page
String processor(const String& var){
//Serial.println(var);
if(var == "BUTTONPLACEHOLDER"){
String buttons;
String outputStateValue = outputState();
//buttons+= "<h4>Output - GPIO 2 - State <span id=\"outputState\"></span></h4><label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleCheckbox(this)\" id=\"output\" " + outputStateValue + "><span class=\"slider\"></span></label>";
buttons = "<h4>output button gpio5 - <span id=\"outputState\"></span></h4><button id=\"fw\">forward</button><br><button id=\"lt\">left</button><button id=\"bw\">backward</button><button id=\"rt\">right</button>";
return buttons;
}
return String();
}
String outputState(){
if(digitalRead(outputfw)){
return "checked";
}
else {
return "";
}
return "";
}
void setup(){
// Serial port for debugging purposes
Serial.begin(115200);
pinMode(outputfw, OUTPUT);
pinMode(outputbw, OUTPUT);
pinMode(outputlt, OUTPUT);
pinMode(outputrt, OUTPUT);
digitalWrite(outputfw, LOW);
digitalWrite(outputbw, LOW);
digitalWrite(outputlt, LOW);
digitalWrite(outputrt, LOW);
// pinMode(buttonPin, INPUT);
// Connect to Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
// Print ESP Local IP Address
Serial.println(WiFi.localIP());
ArduinoOTA.begin();
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html, processor);
});
// Send a GET request to <ESP_IP>/update?<direction>=<inputMessage>
server.on("/update", HTTP_GET, [] (AsyncWebServerRequest *request) {
int ledState1 = LOW; // the current state of the output pin
int ledState2 = LOW;
int ledState3 = LOW;
int ledState4 = LOW;
String inputMessage;
String inputParam;
const char PARAM_INPUT_1[] = "fw";
const char PARAM_INPUT_2[] = "bw";
const char PARAM_INPUT_3[] = "lt";
const char PARAM_INPUT_4[] = "rt";
// GET input1 value on <ESP_IP>/update?state=<inputMessage>
if (request->hasParam(PARAM_INPUT_1)) {
inputMessage = request->getParam(PARAM_INPUT_1)->value();
inputParam = PARAM_INPUT_1;
digitalWrite(outputfw, inputMessage.toInt());
ledState1 = !ledState1;
}
else if (request->hasParam(PARAM_INPUT_2)) {
inputMessage = request->getParam(PARAM_INPUT_2)->value();
inputParam = PARAM_INPUT_2;
digitalWrite(outputbw, inputMessage.toInt());
ledState2 = !ledState2;
}
else if (request->hasParam(PARAM_INPUT_3)) {
inputMessage = request->getParam(PARAM_INPUT_3)->value();
inputParam = PARAM_INPUT_3;
digitalWrite(outputlt, inputMessage.toInt());
ledState3 = !ledState3;
}
if (request->hasParam(PARAM_INPUT_4)) {
inputMessage = request->getParam(PARAM_INPUT_4)->value();
inputParam = PARAM_INPUT_4;
digitalWrite(outputrt, inputMessage.toInt());
ledState4 = !ledState4;
}
else {
inputMessage = "No message sent";
inputParam = "none";
}
Serial.println(inputMessage);
request->send(200, "text/plain", "OK");
});
// Send a GET request to <ESP_IP>/state
server.on("/state", HTTP_GET, [] (AsyncWebServerRequest *request) {
request->send(200, "text/plain", String(digitalRead(outputfw)).c_str());
});
// Start server
server.begin();
}
void loop() {
ArduinoOTA.handle();
delay(2);}
Upvotes: 2
Views: 6650
Reputation: 7054
You're using GPIO pins that are connected to the ESP32's flash chip. When you reprogram those with pinMode()
you interfere with the ESP32's ability to read and write flash storage and it crashes.
const unsigned int outputfw = 2;
const unsigned int outputlt = 4;
const unsigned int outputrt = 7;
const unsigned int outputbw = 6;
Pins 6 and 7 are connected to the SPI flash chip. They're not generally safe to use in applications. They're also not usually expressed on ESP32 breakout boards.
Try rebuilding the firmware using safe pins like 13 and 14 instead of 6 and 7 and you'll find it doesn't crash the way it did.
Perhaps you confused the breakout board's pin numbering with GPIO pin numbering? You'll need to refer to the pinout for the board you're using to find the correct GPIO pin. ESP32 Arduino code will refer to GPIO pin numbers, not breakout board pin numbers.
There's a very useful reference for how ESP32 GPIO pins are used and which ones are safe for which purposes here.
Upvotes: 2