0

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.sstatic.net/HLIaH.png

Any help would be appreciated! Thank you!

1
  • Btw a #define is interpreted by a preprocessor before the compiler does anything. Having them in a private section of a class does not scope them as private to the class. They are visible to every line of code in the file after they occur, barring any particular preprocessor conditionals such as #if. Commented Jun 12, 2022 at 3:15

1 Answer 1

2

It looks like you're actually creating two separate WiFiServers, and only calling begin() on one of them.

  • One WiFiServer is created inside WiFiConnect::wifiConnect(). This is a local variable and so it goes away when that function completes.
  • The other 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:

  • Remove all references to WiFiServer from WiFiConnect::wifiConnect().
  • Move the two lines inside ScheduleProt::scheduleWatering() that relate to WiFiConnect to the top of the function, so that they happen before the WiFiServer is initialized.
  • Add a call to 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 (i.e. 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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for the response. I made the changes that you suggested and they all make logical sense. However, the same issue still occurs, and the browser does not connect to the http server. I tested the ping of the ESP32 and verified that it was still connected. For now, I have been moving around the while loops and adding delays to try to solve the issue, to no avail.
I've just updated my answer with another suggestion.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.