ESP32S NodeMCU
VSCode with PlatformIO
Hey all,
Apologies if I get terms wrong, this is my first time with an ESP32 and webservers. I'm developing code for an amateur ESP32 project that involves connection to an http page. I have set up an if-else loop that reads the ending of the webserver url to set the waterState variable. The ESP32 will connect to my WiFi network with no issue. However, my computer will not connect to the url. The result should print out the state chosen (ex: morning) and the terminal will indicate that the function has completed execution.
I tried moving around the WiFiClient and WiFiServer instances but that hasn't worked. I was able to get this program working once before when I kept the ScheduleProt code inside the WiFi connect. I tried that replicating that again but it now isn't working.
WiFiConnect.h
#ifndef WIFICONNECT_H
#define WIFICONNECT_H
#include <WiFiClient.h>
#include "Wifi.h"
class WiFiConnect
{
private:
#define WIFI_NETWORK "NetworkName"
#define WIFI_PASSWORD "Password"
#define WIFI_TIMEOUT 20000
public:
void wifiConnect();
void wifiDisconnect();
};
#endif
WiFiConnect.cpp - Handles connection to WiFi
#include <WiFi.h>
#include <WiFiConnect.h>
void WiFiConnect::wifiConnect() {
WiFiServer server(80);
Serial.print("Connecting to WiFi");
WiFi.mode(WIFI_AP);
WiFi.begin(WIFI_NETWORK, WIFI_PASSWORD);
unsigned long startAttemptTime = millis();
//Connection Protocol
while(WiFi.status() != WL_CONNECTED && (millis() - startAttemptTime) < WIFI_TIMEOUT) {
Serial.println("...");
delay(100);
}
if(WiFi.status() != WL_CONNECTED) {
Serial.println("Failed, attempting again...");
delay(5000);
}
else{
Serial.print("Connected: ");
Serial.println(WiFi.localIP());
server.begin();
}
}
void WiFiConnect::wifiDisconnect() {
Serial.println("Disconnecting from WiFi...");
WiFi.disconnect();
}
ScheduleProt.h
#ifndef SCHEDULEPROT_H
#define SCHEDULEPROT_H
class ScheduleProt {
public:
int waterState = -1;
void scheduleWatering();
};
#endif
ScheduleProt.cpp - Reads the URL from the http server
#include <WiFi.h>
#include <Arduino.h>
#include "WiFiConnect.h"
#include "ScheduleProt.h"
void ScheduleProt::scheduleWatering() {
WiFiServer server(80);
WiFiClient client = server.available();
WiFiConnect newConnection;
newConnection.wifiConnect();
while(waterState = -1){
if (client) {
String req = client.readStringUntil('\r');
Serial.println("Waiting for user input...");
//Watering Times
if(req.indexOf("/morning/") != -1){
client.print("Morning");
waterState = 0;
}
else if(req.indexOf("/noon/") != -1){
waterState = 1;
client.print("Noon");
}
else if(req.indexOf("/evening/") != -1){
waterState = 2;
client.print("Evening");
}
else if(req.indexOf("/midnight/") != -1){
waterState = 3;
client.print("Midnight");
}
}
}
Serial.println("User input recieved, Huzzah!" + waterState);
newConnection.wifiDisconnect();
}
Here is the terminal
�Connecting to WiFi...
...
...
...
...
...
...
...
...
Connected: 192.168.1.100
If it helps, here is the main.cpp code
#include <Arduino.h>
#include <time.h>
#include "Wifi.h"
#include "ScheduleProt.h"
#include "WaterProt.h"
#include "CurrentTime.h"
#define DEEPSLEEPTIME 86400000
#define WATER_DURATION 10000
#define MOTORPIN 0
WaterProt waterProtocol;
CurrentTime currentTime;
ScheduleProt newSchedule;
void setup() {
Serial.begin(9600);
newSchedule.scheduleWatering();
}
void loop() {
if (waterProtocol.getWateringHour(newSchedule.waterState) == currentTime.getCurrentHour()){
waterProtocol.waterPlant(MOTORPIN, WATER_DURATION);
}
else {
esp_sleep_enable_timer_wakeup(1800000);
esp_deep_sleep_start();
}
esp_sleep_enable_timer_wakeup(DEEPSLEEPTIME);
esp_deep_sleep_start();
}
The webpage error [1]: https://i.stack.imgur.com/HLIaH.png
Any help would be appreciated! Thank you!
It looks like you're actually creating two separate WiFiServer
s, and only calling begin()
on one of them.
WiFiServer
is created inside WiFiConnect::wifiConnect()
. This is a local variable and so it goes away when that function completes.WiFiServer
is created inside ScheduleProt::scheduleWatering()
. This one is probably the one you want to keep, but you'll need to add a call to server.begin()
before the call to server.available()
.My suggestion is:
WiFiServer
from WiFiConnect::wifiConnect()
.ScheduleProt::scheduleWatering()
that relate to WiFiConnect
to the top of the function, so that they happen before the WiFiServer
is initialized.server.begin()
just before the call to server.available()
. I also notice that ScheduleProt::scheduleWatering()
is called from your setup()
function, which means that it will only run once (ie accept one HTTP connection), and the loop()
function will only run after that connection has completed. It looks like this might be intended, but I wasn't sure so thought I should point it out just in case you were unaware.
Update: I just had another look at the docs and it looks like WiFiServer.available()
doesn't actually wait for a client to connect, it just returns the connection if there is one already. If that's the case, you really need to call it repeatedly until it returns a connection (or use a blocking function instead - I haven't looked into what's available in terms of that). Probably the easiest way to do this with your current code is to move the WiFiClient client = server.available();
inside the while
loop.
It might also be a good idea to add a delay(1);
inside that loop, so that it isn't running the processor at 100% load. I can't say this for sure without refreshing my memory on how the ESP32 does power management, but it's likely that adding the delay will save a significant amount of power. Either way, it won't hurt.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.