Sample sketch fails

I am using the XIAO ESP32S3 sample called WiFiAccessPoint seen here

/*
  WiFiAccessPoint.ino creates a WiFi access point and provides a web server on it.

  Steps:
  1. Connect to the access point "yourAp"
  2. Point your web browser to http://192.168.4.1/H to turn the LED on or http://192.168.4.1/L to turn it off
     OR
     Run raw TCP "GET /H" and "GET /L" on PuTTY terminal with 192.168.4.1 as IP address and 80 as port

  Created for arduino-esp32 on 04 July, 2018
  by Elochukwu Ifediora (fedy0)
*/

#include <WiFi.h>
#include <NetworkClient.h>
#include <WiFiAP.h>

#ifndef LED_BUILTIN
#define LED_BUILTIN 2  // Set the GPIO pin where you connected your test LED or comment this line out if your dev board has a built-in LED
#endif

// Set these to your desired credentials.
const char *ssid = "MyAP";
const char *password = "";

NetworkServer server(80);

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);

  Serial.begin(115200);
  Serial.println();
  Serial.println("Configuring access point...");

  // You can remove the password parameter if you want the AP to be open.
  // a valid password must have more than 7 characters
  if (!WiFi.softAP(ssid, password)) {
    log_e("Soft AP creation failed.");
    while (1);
  }
  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(myIP);
  server.begin();

  Serial.println("Server started");
}

void loop() {
  NetworkClient client = server.accept();  // listen for incoming clients

  if (client) {                     // if you get a client,
    Serial.println("New Client.");  // print a message out the serial port
    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
        Serial.write(c);            // print it out the serial monitor
        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:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();

            // the content of the HTTP response follows the header:
            client.print("Click <a href=\"/H\">here</a> to turn ON the LED.<br>");
            client.print("Click <a href=\"/L\">here</a> to turn OFF the LED.<br>");

            // The HTTP response ends with another blank line:
            client.println();
            // 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
        }

        // Check to see if the client request was "GET /H" or "GET /L":
        if (currentLine.endsWith("GET /H")) {
          digitalWrite(LED_BUILTIN, HIGH);  // GET /H turns the LED on
        }
        if (currentLine.endsWith("GET /L")) {
          digitalWrite(LED_BUILTIN, LOW);  // GET /L turns the LED off
        }
      }
    }
    // close the connection:
    client.stop();
    Serial.println("Client Disconnected.");
  }
}

It produces the following Serial output

16:23:26.689 -> 
16:23:26.689 -> Configuring access point...
16:25:02.380 -> 
16:25:02.380 -> Configuring access point...
16:25:02.380 -> AP IP address: 192.168.4.1
16:25:02.380 -> Server started

When I use my browser to access the AP by IP I get the following

Ideas?

What is "eero secure" ?

The free routers our ISP provides (from Amazon) does not allow web access to the admin ip of 192.168.4.1 hence the need to change the sample sketch to use a different IP on the esp32. I actually found a fix by ME! but when I try it now it still doesn't work.

Well, there's something I don't understand about this problem, it seems more like a network problem than an ESP problem.

Let's start with the first things that came to mind.

It looks like you configured your ESP with the IP address 192.168.4.1, but without knowing your local network settings, I can't tell you if that's correct.
On most routers and providers I've had in the past, the local subnet was 192.168.1.0/24. So, with 192.168.4.1, I believe you're trying to use it as the new local subnet for that ESP access point (i.e., your ISP's router isn't configured to use the 192.168.4.0/24 subnet), correct?

When you try to access the ESP address 192.168.4.1, I see that your router rejects the request, but since I don't have your router, I can only speculate.
The first reason that comes to mind is that since your router only "knows" the 192.168.1.0/24 subnet (and the rest of the Internet via its default gateway), it doesn't "know" the 192.168.4.0 subnet. So you'll probably just need to add another IP address 192.168.4.* to your PC's network (e.g., 192.168.4.100): this way, you won't query the router's gateway but can access it directly.

Another option is to define/install a physical router for the 192.168.4.0/24 network to act as a gateway to your ISP's local network. But obviously this is a very different and less manageable thing, so try my first suggestion and let me know if it helps.

And the answer is ..... ?

EDIT: after a quick search about that problem, I found something (Gemini answer from Reddit). It looks like you can/should try adding the IP address 192.168.4.1 to to your eero "Allowed" list.

Here is the description I found (but can't test it, so check it out...):

  • In the eero app, go to Discover > eero Plus > Block & Allow Sites.
  • Tap Add Allowed Site.
  • Enter 192.168.4.1 (or the specific local domain if you're using one).
  • Apply it to the "Network" or the specific profile of the device you are using to browse.

Sorry you are missing the point. I didn't assign any IP, that is the IP the ISP applied to the router and It is the standard AP address so my ESP32 causes an error.

It's just a label the ISP places on the web page. They probably do that to scare off 10-year-olds who are playing around with the net. All it really means is that an ESP32 wants to use the IP 192.168.4.1, which clashes with the ISP's modem/router using that IP. This is the reason I started the topic: how can I change the ESP32 code to use a different gateway IP? I think I found it in a post I made on DBWS, which I need to test after I finish my coffee. The 'fix' is to either add a delay to allow the AP to be created but the proper fix is to wait on a WiFi event that I don;t recall. I can't access the DBWS site again because Bill banned me after I posted about Trump.

That 192.168.4.1 is the address of the ISP modem/router, it is hard coded in the router that I have no access to

Surely you can set the IP address to one of your choosing rather than the default

ChatGPT came up with this sketch when I asked the question

#include <WiFi.h>

const char* ssid = "ESP32_AP";
const char* password = "12345678";

IPAddress local_ip(192,168,10,1);   // Desired IP
IPAddress gateway(192,168,10,1);    // Usually same as AP IP
IPAddress subnet(255,255,255,0);    // Subnet mask

void setup() {
  Serial.begin(115200);

  // Configure AP IP
  WiFi.softAPConfig(local_ip, gateway, subnet);

  // Start AP
  WiFi.softAP(ssid, password);

  Serial.print("AP IP address: ");
  Serial.println(WiFi.softAPIP());
}

void loop() {}

but this is not an area that I am familiar with

First test worked, now I will try to establish a server on it and connect with my browser.

Some success, here is serial log


BUT the following code (it's a mess I know) never does the client thing. I have NO training in this stuff so am 100% cluless how to try to make work. This is a sample sketch so the original worked.

What is preventing either the followoing line

NetworkClient client = server.accept();  // listen for incoming clients

or this line

if (client) {                     // if you get a client,

to not work????

/*
  WiFiAccessPoint.ino creates a WiFi access point and provides a web server on it.

  Steps:
  1. Connect to the access point "yourAp"
  2. Point your web browser to http://192.168.4.1/H to turn the LED on or http://192.168.4.1/L to turn it off
     OR
     Run raw TCP "GET /H" and "GET /L" on PuTTY terminal with 192.168.4.1 as IP address and 80 as port

  Created for arduino-esp32 on 04 July, 2018
  by Elochukwu Ifediora (fedy0)
*/

#include <WiFi.h>
#include <NetworkClient.h>
#include <WiFiAP.h>

#ifndef LED_BUILTIN
#define LED_BUILTIN 2  // Set the GPIO pin where you connected your test LED or comment this line out if your dev board has a built-in LED
#endif

// Set these to your desired credentials.
const char *ssid = "MyAP";
const char *password = "";

// added per chatGPT
IPAddress local_ip(192,168,10,1);   // Desired IP
IPAddress gateway(192,168,10,1);    // Usually same as AP IP
IPAddress subnet(255,255,255,0);    // Subnet mask

NetworkServer server(80);

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);

  Serial.begin(115200);
  Serial.println();
  Serial.println("Configuring access point...");

// original code
  // You can remove the password parameter if you want the AP to be open.
  // a valid password must have more than 7 characters
  //if (!WiFi.softAP(ssid, password)) {
  //  log_e("Soft AP creation failed.");
  //  while (1);
  //}

// mix of original code and proposed solution 1
  //WiFi.mode(WIFI_AP); 
  //WiFi.softAP(ssid, password);   //launch the access point
  //delay(100) ;  // a more correct approach is to wait for SYSTEM_EVENT_AP_START to fire
  //Serial.println("Setting the AP");
  //IPAddress Ip(192, 168, 4, 100);    //setto IP Access Point same as gateway
  //IPAddress NMask(255, 255, 255, 0);
  //WiFi.softAPConfig(Ip, Ip, NMask);
  // Show IP address.

// ChatGPT solution - seems to work
  WiFi.softAPConfig(local_ip, gateway, subnet);
  // Start AP
  WiFi.softAP(ssid, password);

  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(myIP);
  server.begin();

  Serial.println("Server started");
}

void loop() {
  NetworkClient client = server.accept();  // listen for incoming clients

  // does not work as I never see the New Client msg

  if (client) {                     // if you get a client,
    Serial.println("New Client.");  // print a message out the serial port
    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
        Serial.write(c);            // print it out the serial monitor
        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:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();

            // the content of the HTTP response follows the header:
            client.print("Click <a href=\"/H\">here</a> to turn ON the LED.<br>");
            client.print("Click <a href=\"/L\">here</a> to turn OFF the LED.<br>");

            // The HTTP response ends with another blank line:
            client.println();
            // 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
        }

        // Check to see if the client request was "GET /H" or "GET /L":
        if (currentLine.endsWith("GET /H")) {
          digitalWrite(LED_BUILTIN, HIGH);  // GET /H turns the LED on
        }
        if (currentLine.endsWith("GET /L")) {
          digitalWrite(LED_BUILTIN, LOW);  // GET /L turns the LED off
        }
      }
    }
    // close the connection:
    client.stop();
    Serial.println("Client Disconnected.");
  }
}

Ok, got it. That's why I wrote:

On most routers and providers I've had in the past, the local subnet was 192.168.1.0/24. So, with 192.168.4.1, I believe you're trying to use it as the new local subnet for that ESP access point

Said that, I'm still confused because if you can't access the admin interface of your ISP router, doesn't have anything to do with the ESP. Some basic networking concepts are missing here, even if @UKHeliBob already gave you some code to test.

You NEED to assign an IP to your AP. To do so, you should define a separate subnet first, different from the one of your ISP. Like the one @UKHeliBob already told you, 192.168.10.0/24 is good.
Then assign an IP to the AP (192.168.10.1), and now you just need to add another IP address from the same "custom" subnet to your PC, like 192.168.10.100 (unless you add a DHCP server functionality to your AP, a fixed IP is required).

Now you can connect your PC to the AP via its Wifi, and access the services you need (its web server in this case), without any further action required to/by your ISP and/or router.

@UKHeliBob The key point I was missing was that I had to first connect to the SSID I created on the ESP32 (thanks @J-M-L). That is something I have seen certain devices do, but I didn't know I had to in this case. I then had to have certain WiFi functions in the correct order (thanks, @sonofcy); it's too easy to mess that up.
The code should be the final solution/documentation for this issue.
One gotcha is I originally was using an XIAO ESP32-S3, but discovered it needs an antenna plugged in, even when 12"/30cm from the laptop.

Here is the final code. If anyone wants/needs just the AP part of the code, let me know, and I will break it out.

#include <WiFi.h>
#include <NetworkClient.h>
#include <WiFiAP.h>

#ifndef LED_BUILTIN
#define LED_BUILTIN 2
#endif

const char *ssid = "MyAP";
const char *password = "12345678";

IPAddress localIp(192, 168, 4, 1);
IPAddress gateway(192, 168, 4, 1);
IPAddress subnet(255, 255, 255, 0);

NetworkServer server(80);

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);

  Serial.begin(115200);
  delay(1000);
  Serial.println();
  Serial.println("Starting AP...");

  WiFi.disconnect(true, true);
  delay(1000);

  WiFi.mode(WIFI_AP);

  if (!WiFi.softAPConfig(localIp, gateway, subnet)) {
    Serial.println("softAPConfig failed");
    while (true) {
      delay(1000);
    }
  }

  if (!WiFi.softAP(ssid, password)) {
    Serial.println("softAP failed");
    while (true) {
      delay(1000);
    }
  }

  Serial.print("AP IP address: ");
  Serial.println(WiFi.softAPIP());

  server.begin();
  Serial.println("Server started");
}

void loop() {
  static unsigned long lastReportMs = 0;

  if (millis() - lastReportMs >= 2000) {
    lastReportMs = millis();
    Serial.print("Stations connected: ");
    Serial.println(WiFi.softAPgetStationNum());
  }

  NetworkClient client = server.accept();

  if (!client) {
    delay(10);
    return;
  }

  Serial.println("New Client");

  String currentLine = "";
  unsigned long timeoutStartMs = millis();

  while (client.connected() && millis() - timeoutStartMs < 3000) {
    while (client.available()) {
      char incomingCharacter = client.read();
      Serial.write(incomingCharacter);

      if (incomingCharacter == '\n') {
        if (currentLine.length() == 0) {
          client.println("HTTP/1.1 200 OK");
          client.println("Content-type:text/html");
          client.println("Connection: close");
          client.println();

          client.println("OK<br>");
          client.println("<a href=\"/H\">LED ON</a><br>");
          client.println("<a href=\"/L\">LED OFF</a><br>");
          client.println();

          break;
        } else {
          currentLine = "";
        }
      } else if (incomingCharacter != '\r') {
        currentLine += incomingCharacter;

        if (currentLine.endsWith("GET /H")) {
          digitalWrite(LED_BUILTIN, HIGH);
          Serial.println();
          Serial.println("LED ON");
        }

        if (currentLine.endsWith("GET /L")) {
          digitalWrite(LED_BUILTIN, LOW);
          Serial.println();
          Serial.println("LED OFF");
        }
      }

      timeoutStartMs = millis();
    }
  }

  client.stop();
  Serial.println();
  Serial.println("Client Disconnected");
}

I will mark this as the solution after a couple of days' wait to see if there is any follow-up.

See my last post for the correct code and solution. The reason the request was rejected is I had not connected to the SSID so the ISP Modem/Router rejected the 192.168.4.1 as that is it's IP. There is also a small time before the AP can receive a request.
The ISP router is not involved. The correct path is phone or laptop connected to the SSID. By not doig that I was trying to connect to the reserved address 1892.168.4.1. Once I executed the SSID step, waited for the AP to be created it worked with 192.168.4.1 because that address was on the ESP32.
Perhaps the part that fooled you and others is you assumed I had connected to the MyAP SSID but I did not know that was required and had not. Once I did that I was able to get it working fairly quickly.

Impossible, 192.168.4.1 is the EERO address, see previous post to you explaining SSID

OR, see my final post with the code that works. If you can provide code for your method, then we would have two solutions. I look forward to that as it sounds better than mine.

Even if it works, it's generally not a good idea to assign to your AP the same IP address of another device around. You can do so if you are 100% sure you connect to that WiFi network only (and for example not having also an Ethernet connection to your ISP local network), but if you want it for any reason it's ok for me.

My advice is still to define your own new specific subnet and use that.

This means doing something like the one from @UKHeliBob example:

...
IPAddress localIp(192, 168, 10, 1);
IPAddress gateway(192, 168, 10, 1);
IPAddress subnet(255, 255, 255, 0);
...

Then turn the AP on, and connect to its WiFi network. Then from your PC open that WiFi connection properties and set a manual local IP address for your PC from the AP network, any address is ok (except for 1 and 255) let's say 192.168.10.100 (no Gateway or DNS is required, because the network is local and isolated) .
Now just launch your browser and open http://192.168.10.1/ and the code should show the first page.

A quick side note: if no client is connected you don't need to use a delay(), because (in the future) it prevents you from doing other things while checking client connections...
Just change from:

...
  if (!client) {
    delay(10);
    return;
  }

  Serial.println("New Client");
...

to:

...
  if (client) {
    Serial.println("New Client");
    ...and so on...

It's a different SSID, but I get your point. I posted that last sketch as proof that the address 192.168.4.1 can work; I did not intend to say it is the best solution. I am working on two additional sketches that are 'better' solutions.

Not sure what that accomplishes. I was able to connect my PC to the server and turn the LED on/off.

Sure you was, because you and the AP used the same IP address of your local network. As i said before, you can do it and it works, but it's just not something formally correct and prevents you from connecting to both the networks at the same time. Adding a secondary IP address to your PC will allow you to use any available connection simultaneously. But since this isn't a strict requirement, it's (and was) just a suggestion.