One of the most frequent questions I receive from my website’s contact form or from my Facebook page is whether it’s possible to publish an HTTP server when the esp32 chip is working in SoftAP mode, that is when it publishes its own wifi network.
In previous tutorials (18 – Access Point and 20 – Webserver) I’ve already blogged about the two subjects separately, today I’ll explain how to combine them.
Let’s start defining the parameters of the TCP/IP network will be published by the esp32 chip. You have to choose an addressing plan, that is which IP addresses will belong to the network. You can use some of the IP addresses IANA assigned to private networks (RFC1918):
The numbers /8
are, in short
form, the network mask
. For example/8 means that the network 10.0.0.0/8 contains all the addresses from 10.0.0.1 to 10.255.255.254, a total of 16.777.216 different addresses. Thanks to the subnetting
you can slice
a network in smaller subnetworks.
In this example I’m going to use the network 192.168.1.0 with netmask 255.255.255.0 (/24), that is a network with 254 usable addresses (192.168.1.1 – 192.168.1.254). You have to statically assign to the esp32 chip an address that belongs to that network; to make things easy I chose the first one (192.168.1.1):
memset(&info, 0, sizeof(info));
IP4_ADDR(&info.ip, 192, 168, 1, 1);
IP4_ADDR(&info.gw, 192, 168, 1, 1);
IP4_ADDR(&info.netmask, 255, 255, 255, 0);
The other devices which will connect to the network will dynamically configure their IP address, thanks to the DHCP service. To use the DHCP server in your program, first you have to stop it before configuring the network settings and then start it:
After having configured the TCP/IP network and the related services, you can set up the wifi interface of the esp32 chip and activate the SoftAP mode:
wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT();
You have to prepare a wifi_config_t struct that contains all the parameters for the wifi network (SSID, authentication…) and pass it to the method:
You can hardcode the parameters in the program, or make them configurable via menuconfig (as in this example) or Possiamo decidere di inserire i parametri hardcoded nel programma, di renderli configurabili tramite menuconfig (come nell’esempio) or even read them from a config file or from NVS variables.
Finally start the wifi interface with:
Now you can use the Netconn API of the lwip library to bind your program to the TCP/80 port (it’s the standard port used by the HTTP protocol) and to listen for incoming connections:
struct netconn *conn;
conn = netconn_new(NETCONN_TCP);
netconn_bind(conn, NULL, 80);
The accept() method blocks the program until a new connection is accepted:
struct netconn *newconn;
After having established the connection, your program must speak the same language (protocol) of the client; in this case the HTTP protocol used by web browsers.
To keep the example simple, it will publish a static website, whose content is stored in an SPIFFS partition (see the ESP32lights project for more information). Therefore, the program will answer requests in the form GET <resource> looking for the resource in the SPIFFS partition and, if found, sending its content using the netconn_write() method:
To be able to connect to the HTTP server published by the esp32 chip, a client must know the IP address (192.168.1.1) assigned to the chip.
We can leverage the mDNS service (as explained here) to allow the client to connect using an alias (for example esp32web):
mdns_server_t* mDNS = NULL;
ESP_ERROR_CHECK(mdns_set_instance(mDNS, "esp32 webserver"));
If the device you’re using supports the mDNS service, it will be possible to connect to the website using the address esp32web.local:
The complete program is available in my Github repository. After having loaded it on your devboard, a new wifi network will be available:
if you connect to that network, your device will be assigned an IP addess on the 192.168.1.0/24 network:
and you’ll be able to point the browser to http://esp32web.local (or http://192.168.1.1) and display the website: