Hi,
Good Day!
I have used your ESPAsyncWebSrv example to write to EEPROM instead of SPIFFS.
The webpage has six inputs; it stops working when I enter the sixth value. But when I re-boot the ESP32, the web page was accessible, and the sixth value had been accepted and written to the EEPROM. So I cannot understand why it crashes when it accepts the value and writes to EEPROM.
Hardware Beetle ESP32.
I am attaching my test code with this.
Thanks
Johan
code:
#include <BLEDevice.h>
#include <WiFi.h>
#include <FS.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebSrv.h>
#include <EEPROM.h>
const unsigned int MAX_M_LENGTH = 50;
// define the number of bytes you want to access
#define EEPROM_SIZE 274
//256
//EEPROM Locations save the variables
int OBMR_start=0;int OBML_start =18;int MACP_start = 36;int MACNP_start =54;int MACL_start =72;int MACF_start=90;
int MACF_end=108;
//Variables to read from EPROM ONBOOT
char OBMR[18];char OBML[18];char MACP[18]; char MACNP[18]; char MACL[18];char MACF[18];
const char* APssid = “MCSOB”;
const char* APpassword = “mcs22389”;
IPAddress secondaryDNS(8, 8, 4, 4); //optional
AsyncWebServer webserver(80);
boolean flg =false; // flg for wifi= false and BLE = true
const char* PARM_OBMR = “input_obmr”; // out of bed right PIR
const char* PARM_OBML = “input_obml”; // out of bed left PIR
const char* PARM_MP = “input_mp”; // Call Pendant
const char* PARM_MNP = “input_mnp”; //Neck Pendant
const char* PARM_ML = “input_ml”; // Light Pendant
const char* PARM_MF = “input_mf”; // Fall
// HTML web page to handle input fields
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″>
<script>
function submitMessage() {
alert(“Saved value to EPROM”);
setTimeout(function(){ document.location.reload(true); }, 500);
}
</script>
</head><body>
<form action=”/get” target=”hidden-form”>
Input OB MAC Right (current value %input_obmr%): <input type=”text” name=”input_obmr”>
<input type=”submit” value=”Submit” onclick=”submitMessage()”>
</form><br>
<form action=”/get” target=”hidden-form”>
Input OB MAC Left (current value %input_obml%): <input type=”text ” name=”input_obml”>
<input type=”submit” value=”Submit” onclick=”submitMessage()”>
</form><br>
<form action=”/get” target=”hidden-form”>
Input MAC Pendant (current value %input_mp%): <input type=”text ” name=”input_mp”>
<input type=”submit” value=”Submit” onclick=”submitMessage()”>
</form><br>
<form action=”/get” target=”hidden-form”>
Input MAC Neck Pendant (current value %input_mnp%): <input type=”text ” name=”input_mnp”>
<input type=”submit” value=”Submit” onclick=”submitMessage()”>
</form><br>
<form action=”/get” target=”hidden-form”>
Input MAC Light (current value %input_ml%): <input type=”text ” name=”input_ml”>
<input type=”submit” value=”Submit” onclick=”submitMessage()”>
</form><br>
<form action=”/get” target=”hidden-form”>
Input MAC Fall (current value %input_mf%): <input type=”text ” name=”input_mf”>
<input type=”submit” value=”Submit” onclick=”submitMessage()”>
</form>
<iframe style=”display:none” name=”hidden-form”></iframe>
</body></html>)rawliteral”;
void notFound(AsyncWebServerRequest *request) {
request->send(404, “text/plain”, “Not found”);
}
// Replaces placeholder with stored values
String processor(const String& var){
String str=”NONE”;
if(var == “input_obmr”){
char *obmr;
obmr = readStringFromEEPROM(OBMR_start,OBML_start);
if(isValidMacAddress(obmr)== 1){
return String(obmr);
}
else{
return str;
}
}
else if(var == “input_obml”){
char *obml;
obml = readStringFromEEPROM(OBML_start,MACP_start);
if(isValidMacAddress(obml)== 1){
return String(obml);
}
else{
return str;
}
}
else if(var == “input_mp”){
char *macp; macp = readStringFromEEPROM(MACP_start,MACNP_start);
if(isValidMacAddress(macp)== 1){
return String(macp);
}
else{
return str;
}
}
else if(var == “input_mnp”){
char *macnp; macnp = readStringFromEEPROM(MACNP_start,MACL_start);
if(isValidMacAddress(macnp)== 1){
return String(macnp);
}
else{
return str;
}
}
else if(var == “input_ml”){
char *macl; macl = readStringFromEEPROM(MACL_start,MACF_start);
if(isValidMacAddress(macl)== 1){
return String(macl);
}
else{
return str;
}
}
else if(var == “input_mf”){
char *macf; macf = readStringFromEEPROM(MACF_start,MACF_end);
if(isValidMacAddress(macf)== 1){
return String(macf);
}
else{
return str;
}
}
return String();
}
void process ();
void writeStringToEEPROM(int addrOffset, int endadres, const String &strToWrite);
const char * scanres;
int scanTime =5; //In seconds 5 good
BLEScan* pBLEScan;
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
//Serial.printf(“Advertised Device: %s \n”, advertisedDevice.toString().c_str());
scanres=advertisedDevice.toString().c_str();
// Serial.println(scanres);
char * macobr, *macobl, *macp, *macl, *macnp, *macf; char *alamstrob; char *alamstrwl;
if(isValidMacAddress(OBMR)== 1){
macobr = strstr (scanres,OBMR);
}
if(isValidMacAddress(OBML)== 1){
macobl = strstr (scanres,OBML);
}
alamstrob = strstr (scanres,”110aaaa”);
if(isValidMacAddress(MACP)== 1){
macp = strstr (scanres,MACP);
}
if(isValidMacAddress(MACL)== 1){
macl = strstr (scanres,MACL);
}
alamstrwl = strstr (scanres,”40aaaa”);
if(isValidMacAddress(MACNP)== 1){
macnp = strstr (scanres,MACNP);
}
if(isValidMacAddress(MACF)== 1){
macf = strstr(scanres,MACF);
}
if((macobr !=NULL || macobl != NULL) && alamstrob !=NULL){
Serial.println(F(macobr));
process();
}
else
if(macp !=NULL && alamstrwl !=NULL){
Serial.println(F(macp));
process();
}
else
if(macl !=NULL && alamstrwl !=NULL){
Serial.println(F(macl));
Serial.println(F(“LIGHT”));
}
else
if(macnp !=NULL){
Serial.println(F(macnp));
process();
}
else
if(macf !=NULL){
Serial.println(F(macf));
Serial.println(F(“F”));
process();
}
}
};
const int input =D3; int D3state;
const int led = D2;
void setup() {
//SerialPort.begin(115200, SERIAL_8N1, 16, 17);
Serial.begin(115200);
delay(1000);
EEPROM.begin(EEPROM_SIZE);
if(flg == true){
// Boot load valuse
char *obmr; obmr = readStringFromEEPROM(OBMR_start,OBML_start);
if(isValidMacAddress(obmr)== 1){
strcpy(OBMR,obmr);
}
else{
strcpy(OBMR,”NONE”);
}
delay(1);
char *obml; obml = readStringFromEEPROM(OBML_start,MACP_start);
if(isValidMacAddress(obml)== 1){
strcpy(OBML,obml);
}
else{
strcpy(OBML,”NONE”);
}
delay(1);
char *macp; macp = readStringFromEEPROM(MACP_start,MACNP_start);
if(isValidMacAddress(macp)== 1){
strcpy(MACP,macp);
}
else{
strcpy(MACP,”NONE”);
}
delay(1);
char *macnp; macnp = readStringFromEEPROM(MACNP_start,MACL_start);
if(isValidMacAddress(macnp)== 1){
strcpy(MACNP,macnp);
}
else{
strcpy(MACNP,”NONE”);
}
delay(1);
}
pinMode(led, OUTPUT); digitalWrite(led, LOW);
pinMode(D3,INPUT_PULLUP);
if(flg == false){
WiFi.mode(WIFI_AP);
IPAddress ap_ip(192,168,4,1);
IPAddress ap_mask(255,255,255,0);
IPAddress ap_dns(192,168,4,1);
IPAddress ap_gw(192,168,4,1);
WiFi.config(ap_ip,ap_dns,ap_gw,ap_mask);
WiFi.softAP(APssid, APpassword);
delay(1000);
// Send web page with input fields to client
webserver.on(“/”, HTTP_GET, [](AsyncWebServerRequest * request) {
request->send_P(200, “text/html”, index_html, processor);
});
// Send a GET request to <ESP_IP>/get?input1=<inputMessage>
webserver.on(“/get”, HTTP_GET, [] (AsyncWebServerRequest * request) {
String inputMessage;
if(request->hasParam(PARM_OBMR)){
inputMessage = request->getParam(PARM_OBMR)->value();
if(isValidMacAddress(inputMessage.c_str())== 1){
writeStringToEEPROM(OBMR_start,OBML_start, inputMessage);
}
}
else if (request->hasParam(PARM_OBML)) {
inputMessage = request->getParam(PARM_OBML)->value();
if(isValidMacAddress(inputMessage.c_str())== 1){
writeStringToEEPROM(OBML_start,MACP_start, inputMessage);
}
}
else if (request->hasParam(PARM_MP)) {
inputMessage = request->getParam(PARM_MP)->value();
if(isValidMacAddress(inputMessage.c_str())== 1){
writeStringToEEPROM(MACP_start,MACNP_start, inputMessage);
}
}
else if (request->hasParam(PARM_MNP)) {
inputMessage = request->getParam(PARM_MNP)->value();
if(isValidMacAddress(inputMessage.c_str())== 1){
writeStringToEEPROM(MACNP_start,MACL_start, inputMessage);
}
}
else if (request->hasParam(PARM_ML)) {
inputMessage = request->getParam(PARM_ML)->value();
if(isValidMacAddress(inputMessage.c_str())== 1){
writeStringToEEPROM(MACL_start,MACF_start, inputMessage);
}
}
else if (request->hasParam(PARM_MF)) {
inputMessage = request->getParam(PARM_MF)->value();
if(isValidMacAddress(inputMessage.c_str())== 1){
writeStringToEEPROM(MACF_start,MACF_end, inputMessage);
}
}
else {
inputMessage = “No message sent”;
}
request->send(200, “text/text”, inputMessage);
});
webserver.onNotFound(notFound);
webserver.begin();
}
if(flg == true){
BLEDevice::init(“”);
pBLEScan = BLEDevice::getScan(); //create new scan
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
pBLEScan->setInterval(100);
pBLEScan->setWindow(99); // less or equal setInterval value
}
}
void loop() {
if(flg == true){
Serial.println(“Start: “);
BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
Serial.println(“Scan done!”);
pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory
}
delay(50);
}
void process ()
{
Serial.println(F(“ALARM”));
digitalWrite(led, HIGH);
delay(1500);
digitalWrite(led, LOW);
}
// check tech entered mac address is correct or not
int isValidMacAddress(const char* ma) {
int i = 0;
int s = 0;
unsigned n = strlen(ma);
if(n >0){
for(int x =0; x < n; x++)
{
if (isxdigit(ma[x])) {
i++;
}
else if (ma[x] == ‘:’) {
++s;
}
}
}
return (i == 12 && s == 5);
}
void writeStringToEEPROM(int addrOffset, int endadres, const String &strToWrite)
{
byte len = endadres;
EEPROM.write(addrOffset, len);
delay(5);
for (int i = 0; i < len; i++)
{
EEPROM.write(addrOffset + i, strToWrite[i]);
delay(5);
}
EEPROM.commit();
}
char* readStringFromEEPROM(unsigned int saddress,unsigned int addresslen)
{
static char message[MAX_M_LENGTH]; int pos =0;
for(int i =0; i < addresslen; i++)
{
int z = EEPROM.read(saddress + i);
char x =z;
if(z != 0xFF)
{
message[pos] = x;
pos++;
}
else{
message[pos] = ‘\0’;
break;
}
}
return message;
}
Compile results
Sketch uses 1384302 bytes (41%) of program storage space. Maximum is 3342336 bytes.
Global variables use 58324 bytes (17%) of dynamic memory, leaving 269356 bytes for local variables. Maximum is 327680 bytes.
Hi.
Do you get any errors on the Serial Monitor, when you enter the sixth parameter?
Regards,
Sara
Hi Sara,
Good Day!
No errors in the serial monitor. Soft AP still works, and I can ping the ESP32, but the web server fails until I reboot.
Best regards
Johan
Hi Sara,
I fixed it.
No problem with the web server. I had all wrong in the “writeStringToEEPROM” function, and further in the “readStringFromEEPROM” function, I coded a NULL check before returning the value—both fixed issues.
Thanks once again.
Best regards
Johan