Create a WiFi access point with an ESP32
(Updated at 01/05/2023)
The Access Point mode allows you to use the ESP32 to create a WiFi network to connect. This is similar to WiFi connection sharing available on phones. As with phones, the operation of a WiFi router is simulated: this is known as a Soft AP (for “software” WiFi access point). You should, therefore, not expect the same performance as with a conventional WiFi router, especially on a microcontroller!
Also, note that, unlike the phone’s connection sharing, the ESP32 is not connected to the Internet. So you can use the Access Point mode to create a private WiFi local area network wholly isolated from the Internet.
Here are some uses of the Access Point mode:
Connecting to the ESP32 in Access Point mode temporarily to enter the credentials of its WiFi router and allow the ESP32 to connect to our classic WiFi network. Most connected objects use this principle to connect to the home WiFi.
Have a separate network from your home network and not connected to the Internet.
To easily communicate between several ESP32 by WiFi.
To have a local server on an isolated WiFi network.
Set the ESP32 to Access Point mode (AP)
Simply use WiFi.mode(WIFI_AP)
and WiFi.softAP()
to enable Access Point mode. Here is a straightforward example of how to create a WiFi network with an ESP32 :
#include <WiFi.h>
const char* ssid = "uPesy_AP";
const char* password = "super_strong_password";
void setup()
{
Serial.begin(115200);
Serial.println("\n[*] Creating AP");
WiFi.mode(WIFI_AP);
WiFi.softAP(ssid, password);
Serial.print("[+] AP Created with IP Gateway ");
Serial.println(WiFi.softAPIP());
}
void loop(){}
Tip
Don’t forget to import the WiFi.h
module with #include <WiFi.h>
.
Important
If the chosen password is less than 8 characters, the compiler will return an error. The password must be at least 8 to 63 characters long.
Terminal output
[*] Creating AP
[+] AP Created with IP Gateway 192.168.4.1
You can then connect to the Wi-Fi network by entering the password. In this example, it’s a computer on Windows 10 that will connect to ESP32.
You can also create an open Wi-Fi network by setting NULL
for the password :
#include <WiFi.h>
const char* ssid = "uPesy_AP";
const char* password = NULL;
void setup()
{
Serial.begin(115200);
Serial.println("\n[*] Creating AP");
WiFi.mode(WIFI_AP);
WiFi.softAP(ssid, password);
Serial.print("[+] AP Created with IP Gateway ");
Serial.println(WiFi.softAPIP());
}
void loop(){}
The access point appears as an open network :
Tip
The IP displayed in the terminal corresponds to the router’s local IP on the new WiFi network.
The access point can also be further customized by specifying the WiFi channel used (more information on the WiFi channels is available on Wikipedia ), the visibility or not of the network, as well as the maximum number of devices that can be connected at the same time.
#include <WiFi.h>
const char* ssid = "uPesy_AP"; // SSID Name
const char* password = "super_strong_password"; // SSID Password - Set to NULL to have an open AP
const int channel = 10; // WiFi Channel number between 1 and 13
const bool hide_SSID = false; // To disable SSID broadcast -> SSID will not appear in a basic WiFi scan
const int max_connection = 2; // Maximum simultaneous connected clients on the AP
void setup()
{
Serial.begin(115200);
Serial.println("\n[*] Creating AP");
WiFi.mode(WIFI_AP);
WiFi.softAP(ssid, password, channel, hide_SSID, max_connection);
Serial.print("[+] AP Created with IP Gateway ");
Serial.println(WiFi.softAPIP());
}
void loop(){}
Once connected to the WiFi network from a device, one can then ping the router, in this case, the ESP32 in the Windows command prompt with:
ping 192.168.4.1
We have our local WiFi router on an ESP32 on which we can add several devices (computer, phone, ESP32, Raspberry Pi …)
Advanced configuration
The IP address 192.168.4.1
of the access point can be modified, as well as the gateway’s IP address and the subnet mask. You must use the WiFi.softAPConfig()
function before creating the access point via WiFi.softAP()
. The function WiFi.softAPConfig(local_ip, gateway, subnet)
accepts the following parameters
IPAddress local_ip
is the local IP address of our access point in the newly created networkIPAddress gateway
is the IP address of the gateway. In our case, it will be the same as the local IP.subnet
the subnet mask of the network created by the ESP32, usually255.255.255.0
For example, to have a Wi-Fi access point with a local IP 192.168.0.1
with a subnet mask of 255.255.255.0
, the code would be :
#include <WiFi.h>
const char* ssid = "uPesy_AP";
const char* password = "super_strong_password";
IPAddress local_ip(192,168,0,1);
IPAddress gateway(192,168,0,1);
IPAddress subnet(255,255,255,0);
void setup()
{
Serial.begin(115200);
Serial.println("\n[*] Creating AP");
WiFi.mode(WIFI_AP);
WiFi.softAPConfig(local_ip, gateway, subnet);
WiFi.softAP(ssid, password);
Serial.print("[+] AP Created with IP Gateway ");
Serial.println(WiFi.softAPIP());
}
void loop(){}
Terminal output
[*] Creating AP
[+] AP Created with IP Gateway 192.168.0.1
Application examples
An example displays a list of devices connected to the ESP32 with their MAC and local IP addresses. It is a simplified version of the one you can have on a typical WiFi router.
#include <WiFi.h>
#include "esp_wifi.h"
const char* ssid = "uPesy_AP"; // SSID Name
const char* password = "super_strong_password"; // SSID Password - Set to NULL to have an open AP
const int channel = 10; // WiFi Channel number between 1 and 13
const bool hide_SSID = false; // To disable SSID broadcast -> SSID will not appear in a basic WiFi scan
const int max_connection = 2; // Maximum simultaneous connected clients on the AP
void display_connected_devices()
{
wifi_sta_list_t wifi_sta_list;
tcpip_adapter_sta_list_t adapter_sta_list;
esp_wifi_ap_get_sta_list(&wifi_sta_list);
tcpip_adapter_get_sta_list(&wifi_sta_list, &adapter_sta_list);
if (adapter_sta_list.num > 0)
Serial.println("-----------");
for (uint8_t i = 0; i < adapter_sta_list.num; i++)
{
tcpip_adapter_sta_info_t station = adapter_sta_list.sta[i];
Serial.print((String)"[+] Device " + i + " | MAC : ");
Serial.printf("%02X:%02X:%02X:%02X:%02X:%02X", station.mac[0], station.mac[1], station.mac[2], station.mac[3], station.mac[4], station.mac[5]);
Serial.println((String) " | IP " + ip4addr_ntoa(&(station.ip)));
}
}
void setup()
{
Serial.begin(115200);
Serial.println("\n[*] Creating AP");
WiFi.mode(WIFI_AP);
WiFi.softAP(ssid, password, channel, hide_SSID, max_connection);
Serial.print("[+] AP Created with IP Gateway ");
Serial.println(WiFi.softAPIP());
}
void loop()
{
display_connected_devices();
delay(5000);
}
Terminal output
[+] Device 0 | MAC : 44:E2:42:08:D7:11 | IP 192.168.4.2
[+] Device 1 | MAC : 00:0A:F7:42:42:42 | IP 192.168.4.3
-----------
[+] Device 0 | MAC : 44:E2:42:08:D7:11 | IP 192.168.4.2
[+] Device 1 | MAC : 00:0A:F7:42:42:42 | IP 192.168.4.3
Alternatively, some devices could be prevented from connecting by filtering MAC addresses. For example, only allow the ESP32 to connect to it. Indeed, the esp_wifi_deauth_sta(int device_id)
function can be used by specifying the device number you want to remove.
Tip
The solution of the first person who will send me an example of a code that allows filtering the MAC addresses on the WIFI router created by the ESP32 will be published here!
Use the STATION and AP mode at the same time
It is possible to have the ESP32 working with the STATION and AP modes at the same time. That is to say that the ESP32 is connected to a classic WiFi router (STATION mode) with also a WiFi access point activated (AP mode). This mode is called WIFI_AP_STA
.
Note
There is a separate network interface for each mode. Since the interfaces are independent, they each have a different IP address.
One of the possible applications is to connect to the Internet the local WiFi network created by the ESP32 in Soft AP mode.
The Arduino code mixes both the management of the STATION mode and the AP mode. The code is relatively simple when you already use the two modes separately:
We use the WiFi mode
WIFI_AP_STA
We create our local WiFi access point (Soft AP)
Then we connect to the classic WiFi router
Here is an example that allows you to have the two modes at the same time:
#include <WiFi.h>
const char* wifi_network_ssid = "Lounge";
const char* wifi_network_password = "cupcakes";
const char *soft_ap_ssid = "uPesy_AP";
const char *soft_ap_password = NULL;
void setup()
{
Serial.begin(115200);
WiFi.mode(WIFI_AP_STA);
Serial.println("\n[*] Creating ESP32 AP");
WiFi.softAP(soft_ap_ssid, soft_ap_password);
Serial.print("[+] AP Created with IP Gateway ");
Serial.println(WiFi.softAPIP());
WiFi.begin(wifi_network_ssid, wifi_network_password);
Serial.println("\n[*] Connecting to WiFi Network");
while(WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(100);
}
Serial.print("\n[+] Connected to the WiFi network with local IP : ");
Serial.println(WiFi.localIP());
}
void loop() {}
Terminal output
[*] Creating ESP32 AP
[+] AP Created with IP Gateway 192.168.4.1
[*] Connecting to WiFi Network
.............................................................
[+] Connected to the WiFi network with local IP: 192.168.85.37
Important
Don’t mix up the credentials:
wifi_network
refers to the credentials of the classic WiFi router (AT&T, Verizon, Xfinity)soft_ap
is the credential of the access point that we will create with the ESP32. You will have to enter this password on the devices that want to connect to the ESP32.