Reputation: 21
I'm trying to upload a script to my ESP32 DOIT board through Arduino IDE. tl;dr: I'm trying to get a string from a webform and print it on a 0.96" OLED display.
The code I'm using is a combination of two scripts: the first one was a tutorial about hosting a webserver with input html forms in an ESP32 and the second was the OLED SSD1306 example from the Adafruit Library.
The final code I'm using is:
#include <Arduino.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
AsyncWebServer server(80);
// I REPLACED WITH MY NETWORK CREDENTIALS
const char* ssid = "my_ssid";
const char* password = "mypassword";
const char* PARAM_INPUT_1 = "input1";
// HTML web page to handle 3 input fields (input1, input2, input3)
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html><head>
<title>ESP Input Form</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head><body>
<form action="/get">
input1: <input type="text" name="input1">
<input type="submit" value="Submit">
</form><br>
</body></html>)rawliteral";
void notFound(AsyncWebServerRequest *request) {
request->send(404, "text/plain", "Not found");
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("WiFi Failed!");
return;
}
Serial.println();
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
// Send web page with input fields to client
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html);
});
// Send a GET request to <ESP_IP>/get?input1=<inputMessage>
server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputMessage;
String inputParam;
// GET input1 value on <ESP_IP>/get?input1=<inputMessage>
if (request->hasParam(PARAM_INPUT_1)) {
inputMessage = request->getParam(PARAM_INPUT_1)->value();
inputParam = PARAM_INPUT_1;
}
else {
inputMessage = "No message sent";
inputParam = "none";
}
Serial.println(inputMessage);
request->send(200, "text/html", "HTTP GET request sent to your ESP on input field ("
+ inputParam + ") with value: " + inputMessage +
"<br><a href=\"/\">Return to Home Page</a>");
delay(2000);
display.clearDisplay();
display.setTextSize(5);
display.setTextColor(WHITE);
display.setCursor(0, 10);
display.println(inputMessage);
display.display();
delay(5000);
display.clearDisplay();
display.display();
});
server.onNotFound(notFound);
server.begin();
}
void loop() {
}
The code uploads just fine, but in Serial Monitor I get the message:
Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x400dafd2 PS : 0x00060d30 A0 : 0x800d2add A1 : 0x3ffb27a0
A2 : 0x3ffc2d6c A3 : 0x000001ff A4 : 0x00000000 A5 : 0x00000001
A6 : 0x0000ffff A7 : 0x0000007f A8 : 0x800daf9f A9 : 0x3ffb2780
A10 : 0x3ffc2f10 A11 : 0x00000040 A12 : 0x4014bb80 A13 : 0x00000006
A14 : 0x000000ff A15 : 0x4014bb80 SAR : 0x0000000a EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000000 LBEG : 0x40089a95 LEND : 0x40089aa5 LCOUNT : 0xfffffffe
Backtrace:0x400dafcf:0x3ffb27a00x400d2ada:0x3ffb27d0 0x400dd3b2:0x3ffb2820
ELF file SHA256: 0000000000000000
Rebooting...
I tried 3 of my ESP32 boards and everytime I get the same message. When I remove the part where I print my string on the display, there's (obviously) no error.
Can you please point out how to overcome this problem? Why using each part of my code seperately works, but combining them doesn't work?
Thank you in advance!
Upvotes: 1
Views: 1001
Reputation: 21
It seems that this famous project does exactly what I was trying to do and it works like a charm.
Upvotes: -1
Reputation: 7044
Your code is using ESPAsyncWebServer.
Your callback for "/get" calls delay()
. This is explicitly forbidden in the ESPAsyncWebServer README:
You can not use yield or delay or any function that uses them inside the callbacks
Your callback also does quite a bit of computation, calling 3rd party libraries that you can't be sure are safe to call here.
You need to rewrite the callback. Instead of doing work there, save the message you want to display in a variable and set a boolean variable indicating there's work to be done. Then in loop()
, when the boolean is true, do the work that the callback did and clear the flag indicating there was work to be done.
For instance, your new code might look something like this:
boolean show_message = false;
String input_message;
void setup() {
...
server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputParam;
// GET input1 value on <ESP_IP>/get?input1=<inputMessage>
if (request->hasParam(PARAM_INPUT_1)) {
inputMessage = request->getParam(PARAM_INPUT_1)->value();
inputParam = PARAM_INPUT_1;
}
else {
inputMessage = "No message sent";
inputParam = "none";
}
Serial.println(inputMessage);
request->send(200, "text/html", "HTTP GET request sent to your ESP on input field ("
+ inputParam + ") with value: " + inputMessage +
"<br><a href=\"/\">Return to Home Page</a>");
show_message = true;
}
...
}
void loop() {
if(show_message) {
// code to do the work goes here
show_message = false;
}
}
Upvotes: 2