I'm playing around with some ESP8266 (ESP-01) and Arduino IDE. Following some great guides on Random Nerd, I have set up one ESP as a server and two as clients. The idea is for the clients to POST the status of a switch to the server (which will then have a GET endpoint for reading out all the statuses).
I've managed to set up a POST endpoint which takes some input, and stores it in memory (in an array), which I then can GET in a different endpoint. So I thought I'd make a simple data class for these "entries", but then I get problems
Error compiling for board Generic ESP8266 Module.
Maybe I'm setting up the class/array wrong, or maybe I can't do things this way on an ESP8266? Maybe I'm running out of memory?
/*********
https://tttapa.github.io/ESP8266/Chap10%20-%20Simple%20Web%20Server.html
*********/
// Load Wi-Fi library
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <FS.h>
#include <ArduinoJson.h>
#ifndef STASSID
#define STASSID "XXXXXXX"
#define STAPSK "XXXXXXXXXXXXXX"
#endif
const char* ssid = STASSID;
const char* password = STAPSK;
// Assign output variables to GPIO pins
const int output5 = 2;
const int output4 = 0;
// Set web server port number to 80
AsyncWebServer server(80);
char * clientID = "n/a";
char * buttonID = "n/a";
char * buttonState = "n/a";
class Entry {
public:
char* clientID;
char* buttonID;
char* buttonState;
unsigned long times;
Entry() {}
Entry(char* cid, char* bid, char* state) {
clientID = cid;
buttonID = bid;
buttonState = state;
times = millis();
}
String toString() {
char tmp[100];
sprintf(tmp, "%u\t%s\t%s\t%s\n", times, clientID, buttonID, buttonState);
return tmp;
}
};
static const int MAX_STATES = 20;
Entry states[MAX_STATES];
int statePos = 0;
String processor(const String& var){
Serial.println(var);
}
// https://stackoverflow.com/questions/68700739/esp8266-crashes-when-sending-json-object-and-resets
// https://arduinojson.org/v6/example/http-server/
String TEMP() {
String Json;
StaticJsonDocument<512> doc;
JsonArray Temp1 = doc.createNestedArray("Log");
for (int i = 0; i < statePos && i < MAX_STATES; i++) {
JsonObject doc_0 = doc.createNestedObject();
doc_0["clientID"] = states[i].clientID;
doc_0["buttonID"] = states[i].buttonID;
doc_0["buttonState"] = states[i].buttonState;
doc_0["times"] = states[i].times;
Serial.println(states[i].toString());
Temp1.add(doc_0);
}
serializeJson(doc, Json);
Serial.println(Json);
return Json;
}
void setup() {
Serial.begin(115200);
pinMode(output4, OUTPUT);
pinMode(output5, OUTPUT);
// Connect to Wi-Fi network with SSID and password
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
// Print local IP address and start web server
Serial.println("");
Serial.println("WiFi connected.");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
Serial.println("GET /");
request->send(SPIFFS, "/index.html", String(), false, processor);
});
server.on("/buttonstate", HTTP_POST, [](AsyncWebServerRequest *request){
Serial.println("POST /buttonstate");
unsigned long currentTime = millis();
int params = request->params();
if (!(request->hasParam("ID", true) && request->hasParam("button", true) && request->hasParam("state", true))) {
request->send(400, "text/plain", "400: Invalid Request");
return;
}
AsyncWebParameter* param1 = request->getParam("ID", true);
AsyncWebParameter* param2 = request->getParam("state", true);
AsyncWebParameter* param3 = request->getParam("button", true);
char *clientID = param1->value();
char * buttonState = param2->value();
char * buttonID = param3->value();
Entry entry(clientID, buttonID, buttonState);
states[statePos++] = entry; //clientID + ";" + buttonID + ";" + buttonState;
if (statePos >= MAX_STATES) statePos = 0;
request->send(200, "text/plain", "200: OK");
});
// https://stackoverflow.com/questions/47095927/esp8266-json-parameters-in-http-post-request
server.on("/log", HTTP_GET, [](AsyncWebServerRequest *request){
Serial.println("GET /log");
AsyncWebServerResponse *response = request->beginResponse(200, "application/json", TEMP().c_str());
response->addHeader("Access-Control-Allow-Origin", "*");
request->send(response);
//request->send_P(200, "application/json", TEMP().c_str());
});
server.begin();
Serial.println("Ready! v2.22");
}
void loop(){
digitalWrite(output5, HIGH);
}