i am writing a code that connects an ESP32 to an Arduino Nano 33 IoT. The ESP32 is acting as some sort of bridge between the client and an Arduino Nano 33 IoT as a server. Both devices are connected to a local network. The ESP32 is acting as both client and server. That means it spits out its static IP address and you can connect to it and then through an HTML web page on that IP address, you can control 4 LEDs connected to the Arduino Nano 33 IoT. The requests will be sent with the HTTP method to the Arduino Nano 33 and the Arduino will turn the LEDs on and off. The ESP32 will then wait for the response code and when it comes, it shows it in the serial monitor. Now I have two problems:
When I make a request, especially at the beginning when the code gets uploaded, it will be executed without any problem, but after that when I want to turn an LED off, often I get a -5 response code and sometimes even -2 (which represents an error in the code) and the LEDs won't turn off.
Even when an LED turns on successfully, I don't get 200 as the response code.
I would appreciate it if someone can help me understand, what these negative response codes are and how can i fix them. You can find the codes I have written in VSCode for both ESP32 and Arduino below.
Thanks,
Ali
P.S.: I'm relatively new to the topic and might need some basic explanations as well :)
ESP32:
#include <Arduino.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <SPI.h>
#include <SPIFFS.h>
#include <ESPAsyncWebServer.h>
IPAddress ip(192, 168, 0, 32);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 0, 0);
IPAddress nano(192, 168, 0, 33);
AsyncWebServer server(80);
WiFiClient client;
HTTPClient http;
String redState = "";
String greenState = "";
String blueState = "";
String whiteState = "";
String fadeState = "";
uint8_t ledStatus[5];
String processor(const String &var)
{
if(var == "rState"){
if(ledStatus[1] == 1){
redState = "ON";
}
else
{
redState = "OFF";
}
return redState;
}
if(var == "gState"){
if(ledStatus[2] == 1){
greenState = "ON";
}
else
{
greenState = "OFF";
}
return greenState;
}
if(var == "bState"){
if(ledStatus[3] == 1){
blueState = "ON";
}
else
{
blueState = "OFF";
}
return blueState;
}
if(var == "wState"){
if(ledStatus[4] == 1){
whiteState = "ON";
}
else
{
whiteState = "OFF";
}
return whiteState;
}
if(var == "fadeState"){
if(ledStatus[5] == 1){
fadeState = "ON";
}
else
{
fadeState = "OFF";
}
return fadeState;
}
return String();
}
void httpGETRequest(const char* serverName) {
// Your Domain name with URL path or IP address with path
http.begin(client, serverName);
}
String httpGETResponse(int a, bool status) {
// Send HTTP POST request
int httpResponseCode = http.GET();
String payload = "--";
if (httpResponseCode>0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
payload = http.getString();
if (httpResponseCode == 200)
{
ledStatus[a] = status;
}
}
else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
}
// Free resources
http.end();
return payload;
}
const char* ssid = "opdeckenlicht";
const char* password = "opdeckenlicht";
const char* nano33 = "http://192.168.0.32/";
const char* reconnect = "http://192.168.0.32/reconnect";
const char* redLEDon = "http://192.168.0.32/r/On";
const char* redLEDoff = "http://192.168.0.32/r/Off";
const char* greenLEDon = "http://192.168.0.32/g/On";
const char* greenLEDoff = "http://192.168.0.32/g/Off";
const char* blueLEDon = "http://192.168.0.32/b/On";
const char* blueLEDoff = "http://192.168.0.32/b/Off";
const char* whiteLEDon = "http://192.168.0.32/w/On";
const char* whiteLEDoff = "http://192.168.0.32/w/Off";
const char* fadeLEDon = "http://192.168.0.32/fade/on";
const char* fadeLEDoff = "http://192.168.0.32/fade/off";
void setup() {
Serial.begin(9600);
WiFi.config(ip, gateway, subnet);
Serial.println("");
Serial.print("Connecting to ");
Serial.print(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.print("IP address: ");
Serial.println(WiFi.localIP());
// Initialize SPIFFS
if(!SPIFFS.begin(true)){
Serial.println("An Error has occurred while mounting SPIFFS");
return;
}
}
void loop() {
server.begin();
client.connect(nano, 80);
http.begin(nano33);
// Route to load style.css file
server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(SPIFFS, "/style.css", "text/css");
});
server.on("/r/style.css", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(SPIFFS, "/style.css", "text/css");
});
server.on("/g/style.css", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(SPIFFS, "/style.css", "text/css");
});
server.on("/b/style.css", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(SPIFFS, "/style.css", "text/css");
});
server.on("/w/style.css", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(SPIFFS, "/style.css", "text/css");
});
server.on("/fade/style.css", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(SPIFFS, "/style.css", "text/css");
});
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
Serial.println("Client connected.");
Serial.println("");
request->send(SPIFFS, "/index.html", String(), false, processor);
});
server.on("/reconnect", HTTP_GET, [](AsyncWebServerRequest *request){
httpGETRequest(reconnect);
delay(1000);
client.connect(nano, 80);
http.begin(nano33);
request->send(SPIFFS, "/index.html", String(), false, processor);
});
// Red LED
server.on("/r/on", HTTP_GET, [](AsyncWebServerRequest *request){
httpGETRequest(redLEDon);
delay(5);
httpGETResponse(1, 1);
// ledStatus[1] = 1;
request->send(SPIFFS, "/index.html", String(), false, processor);
});
server.on("/r/off", HTTP_GET, [](AsyncWebServerRequest *request){
httpGETRequest(redLEDoff);
delay(5);
httpGETResponse(1, 0);
// ledStatus[1] = 0;
request->send(SPIFFS, "/index.html", String(), false, processor);
});
// Green LED
server.on("/g/on", HTTP_GET, [](AsyncWebServerRequest *request){
httpGETRequest(greenLEDon);
delay(5);
httpGETResponse(2, 1);
// ledStatus[2] = 1;
request->send(SPIFFS, "/index.html", String(), false, processor);
});
server.on("/g/off", HTTP_GET, [](AsyncWebServerRequest *request){
httpGETRequest(greenLEDoff);
delay(5);
httpGETResponse(2, 0);
// ledStatus[2] = 0;
request->send(SPIFFS, "/index.html", String(), false, processor);
});
// Blue LED
server.on("/b/on", HTTP_GET, [](AsyncWebServerRequest *request){
httpGETRequest(blueLEDon);
delay(5);
httpGETResponse(3, 1);
// ledStatus[3] = 1;
request->send(SPIFFS, "/index.html", String(), false, processor);
});
server.on("/b/off", HTTP_GET, [](AsyncWebServerRequest *request){
httpGETRequest(blueLEDoff);
delay(5);
httpGETResponse(3, 0);
// ledStatus[3] = 0;
request->send(SPIFFS, "/index.html", String(), false, processor);
});
// White LED
server.on("/w/on", HTTP_GET, [](AsyncWebServerRequest *request){
httpGETRequest(whiteLEDon);
delay(5);
httpGETResponse(4, 1);
// ledStatus[4] = 1;
request->send(SPIFFS, "/index.html", String(), false, processor);
});
server.on("/w/off", HTTP_GET, [](AsyncWebServerRequest *request){
httpGETRequest(whiteLEDoff);
delay(5);
httpGETResponse(4, 0);
// ledStatus[4] = 0;
request->send(SPIFFS, "/index.html", String(), false, processor);
});
// Fade Mode
server.on("/fade/on", HTTP_GET, [](AsyncWebServerRequest *request){
httpGETRequest(fadeLEDon);
delay(3000);
httpGETResponse(5, 1);
// ledStatus[5] = 1;
request->send(SPIFFS, "/index.html", String(), false, processor);
});
server.on("/fade/off", HTTP_GET, [](AsyncWebServerRequest *request){
httpGETRequest(fadeLEDoff);
delay(3000);
httpGETResponse(5, 0);
// ledStatus[5] = 0;
request->send(SPIFFS, "/index.html", String(), false, processor);
});
}
Arduino Nano 33:
#include <Arduino.h>
#include <WiFi.h>
#include <SPI.h>
#include "WebServer.h"
IPAddress ip(192, 168, 0, 33);
IPAddress esp(192, 168, 0, 32);
WiFiServer server(80);
WiFiClient client;
Lightcontroller leds;
Luefter x;
Tempsensor core, driver;
VController vcont;
WebServer::WebServer()
{
ssid = "opdeckenlicht";
password = "opdeckenlicht";
status = WL_IDLE_STATUS;
}
void WebServer::setup()
{
WiFi.config(ip);
// check for the WiFi module:
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
// don't continue
while (true);
}
String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
Serial.println("Please upgrade the firmware");
}
// attempt to connect to WiFi network:
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to Network named: ");
Serial.println(ssid); // print the network name (SSID);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, password);
// wait 5 seconds for connection:
delay(5000);
}
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your board's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print where to go in a browser:
Serial.print("To see this page in action, open a browser to http://");
Serial.println(ip);
server.begin(); // start the web server on port 80
}
void WebServer::begin()
{
leds.setup();
x.setup();
WebServer::setup();
}
void WebServer::run()
{
// put your main code here, to run repeatedly:
client = server.available(); // listen for incoming clients
if (client) { // if you get a client,
String currentLine = ""; // make a String to hold incoming data from the client
while (client.connected()) { // loop while the client's connected
if (client.available()) { // if there's bytes to read from the client,
char c = client.read(); // read a byte, then
// Check to see what the client request was:
if (currentLine.endsWith("GET /reconnect")) {
status = WiFi.begin(ssid, password);
server.begin();
Serial.println("Reconnected to: ");
Serial.print(ssid);
}
if (currentLine.endsWith("GET /r/On")) {
leds.control(2,255);
Serial.println("Red LED on.");
}
if (currentLine.endsWith("GET /r/Off")) {
leds.control(2,0);
Serial.println("Red LED off.");
}
if (currentLine.endsWith("GET /g/On")) {
leds.control(3,255);
Serial.println("Green LED on.");
}
if (currentLine.endsWith("GET /g/Off")) {
leds.control(3,0);
Serial.println("Green LED off.");
}
if (currentLine.endsWith("GET /b/On")) {
leds.control(5,255);
Serial.println("Blue LED on.");
}
if (currentLine.endsWith("GET /b/Off")) {
leds.control(5,0);
Serial.println("Blue LED off.");
}
if (currentLine.endsWith("GET /w/On")) {
leds.control(6,255);
Serial.println("White LED on.");
}
if (currentLine.endsWith("GET /w/Off")) {
leds.control(6,0);
Serial.println("White LED off.");
}
if (currentLine.endsWith("GET /fade/on")) {
leds.fade(1);
Serial.println("Fade mode on.");
}
if (currentLine.endsWith("GET /fade/off")) {
leds.fade(0);
Serial.println("Fade LED off.");
}
if (c == '\n') { // if the byte is a newline character
// if the current line is blank, you got two newline characters in a row.
// that's the end of the client HTTP request, so send a response:
if (currentLine.length() == 0) {
// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
// and a content-type so the client knows what's coming, then a blank line:
Serial.println("Executing task...");
// break out of the while loop:
break;
}
else { // if you got a newline, then clear currentLine:
currentLine = "";
}
}
else if (c != '\r') { // if you got anything else but a carriage return character,
currentLine += c; // add it to the end of the currentLine
}
}
}
// close the connection:
// client.stop();
// Serial.println("client disconnected");
}
}
Negative returns from the ESP32 HTTPClient library indicate an error while attempting to communicate with the server, rather than an HTTP response code.
The library is open source, so you can find its source code online and see what the return values indicate. -2 means HTTPC_ERROR_SEND_HEADER_FAILED, -5 means HTTPC_ERROR_CONNECTION_LOST. The gist of it is that the network connection to the web server is unstable and unexpectedly goes away.
In this case, you're using the ESPAsyncWebServer. Its README is long but contains critical information, particularly in the "Important Things To Remember" section:
You can not use yield or delay or any function that uses them inside
the callbacks
You directly call delay() in callback handlers, which is disallowed.
This section should spell it out more clearly, but this means it is not safe to re-enter the network stack - it is not safe to call TCP-related functions (including HTTPClient) from a callback. Unfortunately you call HTTPClient functions extensively from web server callbacks, which is why they're failing.
In general for web server callbacks (not just the async library ones), requests should be handled in a short, determinate amount of time. If you need to run a function that can take a long time, you should start that outside the callback. If you need to report its results to the browser accessing the web server you should do that asynchronously.
It might be sufficient to eliminate the delay() calls, but it's still unsafe to call HTTPClient from the async web server callbacks, and it's still a problem to call potentially long running functions while responding to a web server request.
The best approach is to rewrite your code to perform the HTTPClient calls from outside the web server callbacks and to not call delay() in them. One way to do this is to provide state variables which the callbacks set and which the loop() code inspects to decide whether to do the HTTPClient work.
For instance, something like this would move the code out of the callback:
boolean turn_red_len_on = false;
// Red LED
server.on("/r/on", HTTP_GET, [](AsyncWebServerRequest *request) {
turn_red_led_on = true;
request->send(SPIFFS, "/index.html", String(), false, processor);
});
void loop() {
if(turn_red_len_on) {
httpGETRequest(redLEDon);
delay(5);
httpGETResponse(1, 1);
turn_red_led_on = false;
}
}
You'd need to restructure your code similarly to the example I provided, and do this for each callback that needs to use an HTTPClient.
As an alternative, you could switch to the WebServer library that's part of the Arduino framework for the ESP32. This loses many of the advanced features of the async web server but will be more resilient with code that misbehaves by running long running functions in the callbacks.
Perhaps it would be simpler just to put the LEDs on the ESP32?
I'm running an Async web server on an esp32 and need to run an OTA update where Im grabbing the bin file from a link on a local server. My OTA update code works on another code and my async web server works without the OTA code but when I try to use both the codes together it wont upload. Just wondered if there is an alternative library I can use or an edit I can make to make it all work in one. because the libraries seem to clash.
#include <Arduino.h>
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <AsyncTCP.h>
#include "SPIFFS.h"
#include "HttpsOTAUpdate.h"
These are my libraries and this is the error message I get. In the IDE. I would post the full console error message but its super long.
IDE Error
#include <Arduino.h>
#include <WiFi.h>
#include <ESPAsyncWe5bServer.h>
#include <AsyncTCP.h>
#include "SPIFFS.h"
#include "HttpsOTAUpdate.h"
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
TaskHandle_t Task1;
// Search for parameter in HTTP POST request
const char* PARAM_INPUT_1 = "ssid";
const char* PARAM_INPUT_2 = "pass";
const char* PARAM_INPUT_3 = "ip";
const char* PARAM_INPUT_4 = "gateway";
String payload = "";
//Variables to save values from HTML form
String ssid;
String pass;
String ip;
String gateway;
// File paths to save input values permanently
const char* ssidPath = "/ssid.txt";
const char* passPath = "/pass.txt";
const char* ipPath = "/ip.txt";
const char* gatewayPath = "/gateway.txt";
bool apmode = false;
IPAddress localIP;
//IPAddress localIP(192, 168, 1, 200); // hardcoded
// Set your Gateway IP address
IPAddress localGateway;
//IPAddress localGateway(192, 168, 1, 1); //hardcoded
IPAddress subnet(255, 255, 0, 0);
// Timer variables
unsigned long previousMillis = 0;
const long interval = 10000; // interval to wait for Wi-Fi connection (milliseconds)
static const char *url = "http://192.168.1.142/arduinotest/https_OTA_updatesv2.ino.doitESP32devkitV1.bin"; //state url of your firmware image
static const char *server_certificate = "-----BEGIN CERTIFICATE-----\n" \
"MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/\n" \
"MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\n" \
"DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow\n" \
"SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT\n" \
"GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC\n" \
"AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF\n" \
"q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8\n" \
"SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0\n" \
"Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA\n" \
"a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj\n" \
"/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T\n" \
"AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG\n" \
"CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv\n" \
"bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k\n" \
"c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw\n" \
"VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC\n" \
"ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz\n" \
"MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu\n" \
"Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF\n" \
"AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo\n" \
"uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/\n" \
"wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu\n" \
"X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG\n" \
"PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6\n" \
"KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==\n" \
"-----END CERTIFICATE-----";
static HttpsOTAStatus_t otastatus;
// Initialize SPIFFS
void initSPIFFS() {
if (!SPIFFS.begin(true)) {
Serial.println("An error has occurred while mounting SPIFFS");
}
Serial.println("SPIFFS mounted successfully");
}
// Read File from SPIFFS
String readFile(fs::FS &fs, const char * path){
Serial.printf("Reading file: %s\r\n", path);
File file = fs.open(path);
if(!file || file.isDirectory()){
Serial.println("- failed to open file for reading");
return String();
}
String fileContent;
while(file.available()){
fileContent = file.readStringUntil('\n');
break;
}
return fileContent;
}
void HttpEvent(HttpEvent_t *event)
{
switch(event->event_id) {
case HTTP_EVENT_ERROR:
Serial.println("Http Event Error");
break;
case HTTP_EVENT_ON_CONNECTED:
Serial.println("Http Event On Connected");
break;
case HTTP_EVENT_HEADER_SENT:
Serial.println("Http Event Header Sent");
break;
case HTTP_EVENT_ON_HEADER:
Serial.printf("Http Event On Header, key=%s, value=%s\n", event->header_key, event->header_value);
break;
case HTTP_EVENT_ON_DATA:
break;
case HTTP_EVENT_ON_FINISH:
Serial.println("Http Event On Finish");
break;
case HTTP_EVENT_DISCONNECTED:
Serial.println("Http Event Disconnected");
break;
}
}
void OTAUpdate(){
HttpsOTA.onHttpEvent(HttpEvent);
Serial.println("Starting OTA");
HttpsOTA.begin(url, server_certificate);
Serial.println("Please Wait it takes some time ...");
while(true){
otastatus = HttpsOTA.status();
if(otastatus == HTTPS_OTA_SUCCESS) {
Serial.println("Firmware written successfully. To reboot device, call API ESP.restart() or PUSH restart button on device");
} else if(otastatus == HTTPS_OTA_FAIL) {
Serial.println("Firmware Upgrade Fail");
}
delay(1000);
}
}
// Write file to SPIFFS
void writeFile(fs::FS &fs, const char * path, const char * message){
Serial.printf("Writing file: %s\r\n", path);
File file = fs.open(path, FILE_WRITE);
if(!file){
Serial.println("- failed to open file for writing");
return;
}
if(file.print(message)){
Serial.println("- file written");
} else {
Serial.println("- frite failed");
}
}
// Initialize WiFi
bool initWiFi() {
if(ssid=="" || ip==""){
Serial.println("Undefined SSID or IP address.");
return false;
}
WiFi.mode(WIFI_STA);
localIP.fromString(ip.c_str());
localGateway.fromString(gateway.c_str());
if (!WiFi.config(localIP, localGateway, subnet)){
Serial.println("STA Failed to configure");
return false;
}
WiFi.begin(ssid.c_str(), pass.c_str());
Serial.println("Connecting to WiFi...");
unsigned long currentMillis = millis();
previousMillis = currentMillis;
while(WiFi.status() != WL_CONNECTED) {
currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
Serial.println("Failed to connect.");
return false;
}
}
Serial.println(WiFi.localIP());
apmode = false;
return true;
}
void networkScan(void * pvParameters){
while (true){
String payloadtmp = "";
Serial.println("Scanning");
int n = WiFi.scanNetworks();
if (n == 0) {
Serial.println("no networks found");
} else {
Serial.print(n);
Serial.println(" networks found");
payloadtmp += "[";
for (int i = 0; i < n; ++i) {
payloadtmp += " \"";
payloadtmp += (WiFi.SSID(i));
payloadtmp += "\",";
}
payloadtmp += "]";
payload = payloadtmp;
}
Serial.println(payload);
delay(1000);
}
}
// Replaces placeholder with LED state value
String processor(const String& var) {
if (var == "SSIDLST"){
Serial.println(payload);
return payload;
}
return String();
}
void setup() {
// Serial port for debugging purposes
Serial.begin(115200);
initSPIFFS();
// Set GPIO 2 as an OUTPUT
// Load values saved in SPIFFS
ssid = readFile(SPIFFS, ssidPath);
pass = readFile(SPIFFS, passPath);
ip = readFile(SPIFFS, ipPath);
gateway = readFile (SPIFFS, gatewayPath);
Serial.println(ssid);
Serial.println(pass);
Serial.println(ip);
Serial.println(gateway);
if(initWiFi()) {
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) { //default page (settings tab)
request->send(SPIFFS, "/index.html", "text/html", false, processor);
});
server.on("/otaupdates", HTTP_GET, [](AsyncWebServerRequest *request) { //ota updates
request->send(SPIFFS, "/otaupdates.html", "text/html", false, processor);
});
server.on("/updateOTA", HTTP_GET, [](AsyncWebServerRequest *request) { //ota updates
OTAUpdate();
request->send(SPIFFS, "/otaupdates.html", "text/html", false, processor);
});
server.serveStatic("/", SPIFFS, "/");
server.begin();
}
else {
apmode = true;
// Connect to Wi-Fi network with SSID and password
Serial.println("Setting AP (Access Point)");
// NULL sets an open Access Point
WiFi.softAP("ESP-WIFI-MANAGER", NULL);
IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(IP);
// Web Server Root URL
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ //The defult web page on client connect
request->send(SPIFFS, "/wifimanager.html", "text/html", false, processor);
});
server.serveStatic("/", SPIFFS, "/");
server.on("/scan", HTTP_POST, [](AsyncWebServerRequest *request){
request->send(SPIFFS, "/wifimanager.html", "text/html", false, processor);
});
server.on("/submit", HTTP_POST, [](AsyncWebServerRequest *request) { // Handles input taking and ssid and password saving once submit is saved.
int params = request->params();
for(int i=0;i<params;i++){
AsyncWebParameter* p = request->getParam(i);
if(p->isPost()){
// HTTP POST ssid value
if (p->name() == PARAM_INPUT_1) {
ssid = p->value().c_str();
Serial.print("SSID set to: ");
Serial.println(ssid);
// Write file to save value
writeFile(SPIFFS, ssidPath, ssid.c_str());
}
// HTTP POST pass value
if (p->name() == PARAM_INPUT_2) {
pass = p->value().c_str();
Serial.print("Password set to: ");
Serial.println(pass);
// Write file to save value
writeFile(SPIFFS, passPath, pass.c_str());
}
// HTTP POST ip value
if (p->name() == PARAM_INPUT_3) {
ip = p->value().c_str();
Serial.print("IP Address set to: ");
Serial.println(ip);
// Write file to save value
writeFile(SPIFFS, ipPath, ip.c_str());
}
// HTTP POST gateway value
if (p->name() == PARAM_INPUT_4) {
gateway = p->value().c_str();
Serial.print("Gateway set to: ");
Serial.println(gateway);
// Write file to save value
writeFile(SPIFFS, gatewayPath, gateway.c_str());
}
//Serial.printf("POST[%s]: %s\n", p->name().c_str(), p->value().c_str());
}
}
request->send(200, "text/plain", "Done. ESP will restart, connect to your router and go to IP address: " + ip);
delay(3000);
ESP.restart();
});
server.begin();
xTaskCreatePinnedToCore(
networkScan, /* Task function. */
"Task1", /* name of task. */
10000, /* Stack size of task */
NULL, /* parameter of the task */
1, /* priority of the task */
&Task1, /* Task handle to keep track of created task */
0); /* pin task to core 0 */
delay(500);
}
}
void loop() {
if (!apmode){
vTaskDelete(Task1);
}
}
Derived from the following code.
I uploaded that code to my ESP8266 and it's all good and okay when I communicate with it with my laptop while my laptop is connected to my network with a LAN cable.
The problem is: when I try to communicate with the ESP with my laptop or phone over Wi-Fi I get ERR_CONNECTION_REFUSED though they rarely work and communicate. I tried another phone another router, and did a factory reset to my router, and all the same.
I know that there is an option in the router that is called AP Isolation and it's been checked and it's disabled.
My question is: What could possibly be the reason for this error ERR_CONNECTION_REFUSED when I communicate with ESP8266 with that code?
If someone could help me I would be pleased as I am stuck in this situation.
The ESP code (same as the link):
#include <ESP8266WiFi.h>
const char* ssid = "*****";
const char* password = "*******";
WiFiServer server(80);
void setup() {
Serial.begin(115200);
Serial.println();
Serial.printf("Connecting to %s ", ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(" connected");
server.begin();
Serial.printf("Web server started, open %s in a web browser\n", WiFi.localIP().toString().c_str());
}
// prepare a web page to be send to a client (web browser)
// the connection will be closed after completion of the response
// the page will be refreshed automatically every 5 sec
String prepareHtmlPage() {
String htmlPage = String("HTTP/1.1 200 OK\r\n") +
"Content-Type: text/html\r\n" +
"Connection: close\r\n" +
"Refresh: 5\r\n" + "\r\n" +
"<!DOCTYPE HTML>" + "<html>" +
"Analog input: " + String(analogRead(A0)) +
"</html>" + "\r\n";
return htmlPage;
}
void loop() {
WiFiClient client = server.available();
// wait for a client (web browser) to connect
if (client) {
Serial.println("\n[Client connected]");
while (client.connected()) {
// read line by line what the client (web browser) is requesting
if (client.available()) {
String line = client.readStringUntil('\r');
Serial.print(line);
// wait for end of client's request, that is marked with an empty line
if (line.length() == 1 && line[0] == '\n') {
client.println(prepareHtmlPage());
break;
}
}
}
delay(1); // give the web browser time to receive the data
// close the connection:
client.stop();
Serial.println("[Client disconnected]");
}
}
I hope its not too late and it helps someone in need.
You need to do 2 things
Before WiFi.begin(), you need to add
WiFi.mode(WIFI_STA);
Second, you need to
#include <ESP8266mDNS.h>
in setup()
if (MDNS.begin("esp8266")) {
Serial.println("MDNS responder started");
}
and in loop()
MDNS.update();
Lastly, do not forget to add the following in every server response. Else, you will hit CORS error.
server.sendHeader("Access-Control-Allow-Origin", "*");
Please dont forget to add supporting libraries. Let me know if it works. Demo code would look like the below
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
const char* ssid = "<your SSID>";
const char* password = "<your WIFI Password>>";
int serverPort = 80;
int boardBaud = 115200;
ESP8266WebServer server(serverPort);
void handleRoot() {
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/html", "<h1>Hello World</h1>");
}
void handleNotFound() {
if (server.method() == HTTP_OPTIONS)
{
server.sendHeader("Access-Control-Allow-Origin", "*");
server.sendHeader("Access-Control-Max-Age", "10000");
server.sendHeader("Access-Control-Allow-Methods", "PUT,POST,GET,OPTIONS");
server.sendHeader("Access-Control-Allow-Headers", "*");
server.send(204);
}
else
{
server.send(404, "text/plain", "Error");
}
}
void setup(void) {
Serial.begin(boardBaud);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (MDNS.begin("esp8266")) {
Serial.println("MDNS responder started");
}
server.on("/", handleRoot);
server.onNotFound(handleNotFound);
server.begin();
Serial.println("HTTP server started");
}
void loop(void) {
server.handleClient();
MDNS.update();
}
I am communicating two ESP32 boards which are connected to a Wifi Network. One ESP32 board is the Server and the other is the client. I want to measure the ESP32 CPU utlization on the client ESP32. I have no idea how to do it and have not yet found any useful resources on the internet. Can someone help me with this?
This is the code on server
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
const char* ssid = "XXXXX";
const char* password = "XXXX";
AsyncWebServer server(80);
void setup() {
Serial.begin(115200);
WiFi.begin(ssid,password);
while (WiFi.status()!= WL_CONNECTED){
delay(200);
Serial.println("Connecting to Wifi...");
}
Serial.println("Connected to Wifi");
Serial.println(WiFi.localIP());
server.on("/test", HTTP_GET, [](AsyncWebServerRequest *request){
Serial.println("Request received from esp32client");
request->send(200, "text/plain", "Hello from ESP32Server to ESP32Client");
});
server.on("/test1", HTTP_GET, [](AsyncWebServerRequest *request){
Serial.println("Request received from PC-Client");
request->send(300, "text/plain", "Hello from ESP32Server to PC");
});
server.begin();
}
void loop() {
// put your main code here, to run repeatedly:
}
This is the code on Client
#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "XXXXX";
const char* password ="XXXXX";
void setup() {
Serial.begin(115200);
WiFi.begin(ssid,password);
while (WiFi.status()!= WL_CONNECTED){
delay(500);
Serial.println("Connecting to Wifi...");
}
Serial.println("Connected to Wifi Network...");
Serial.println(WiFi.localIP());
}
void loop() {
HTTPClient http;
http.begin("http://192.168.43.35/test");
int httpCode = http.GET();
if (httpCode > 0) {
String payload = http.getString();
Serial.println(httpCode);
Serial.println(payload);
}
else {
Serial.println("Error on HTTP request");
}
http.end();
delay(30000);
}
Use this function to get CPU load
vTaskGetRunTimeStats(char *buffer);
It tells CPU utilization by currently running task on esp32.
API documentation here.
Using the Arduino IDE with the Nodemcu-esp12e module, I created a program which makes an HTTP GET request.
However, I do not know how it would be the right way to deal with the return of this consultation.
I am validating the return with the 'indexOf' function to find out if the return is false/off or true/on.
This is the correct way to validate the return?
Any suggestions for how to improve this code?
#include <ESP8266WiFi.h>
const char* ssid = "mywifiid";
const char* password = "mypassword";
IPAddress host(192,168,0,11);
void setup() {
Serial.begin(115200);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
//
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
//
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void loop() {
//
Serial.print("connecting to ");
Serial.println(host);
//
WiFiClient client;
const int httpPort = 80;
if (!client.connect(host, httpPort)) {
Serial.println("connection failed");
return;
}
else{
Serial.println("connection success");
}
//
String get = "http://localhost/Test/GetStatusSensor?idsensor=2";
Serial.println(get);
//
client.print("GET " + get + "\r\nHTTP/1.1\r\nHost: localhost\Test\r\nConnection: keep-alive\r\n\r\n");
//
while(client.available()){
String line = client.readStringUntil('\r');
//
int iret= line.indexOf('on');
//
Serial.print(line);
Serial.println(String(iret));
//
if (iret> 0) {
//
Serial.println("On");
}
else {
Serial.println("Off");
}
}
//
Serial.println();
Serial.println("closing connection");
delay(20000); // 20 sec
}
My suggestion is to use JSON to switch to more structured way of comm. You can define custom data names and types and easily cover them. Take a look it at :
https://github.com/bblanchon/ArduinoJson
Here some JSON example from the HTTPClient example :
DynamicJsonBuffer jsonBuffer(BUFFER_SIZE);
JsonObject& root = jsonBuffer.parseObject(client);
if (!root.success()) {
Serial.println("JSON parsing failed!");
return false;
}
// Here were copy the strings we're interested in
strcpy(userData->name, root["name"]);
strcpy(userData->company, root["company"]["name"]);