ESP32 WiFi Access Point (ESP-IDF)

Introduction

In previous article, you learnt about configuring ESP32 as a station. ESP32 can also be configured as an access point (AP) which allows other station devices connect to it. In this article, you will learn about steps to configure ESP32 as an AP using ESP-IDF framework.

We will take a look at a project in ESP-IDF examples folder to understand how to write an WiFi application in which ESP32 is an access point. The folder is located at

~/esp-idf/examples/wifi/getting_started/softap

In this example, ESP32 is configured as an AP with pre-defined SSID and password. These parameters are configurable using ESP32 component which you can easily change before compiling the project. The ESP32 will print out log messages when a station connects to it successfully, or when a station disconnects from it.

Hardware Used

In this article, we will be using the hardware listed in the table below

QTYComponent NameBuy on amazon
1ESP32 DevKit Camazon.com

Affiliate Disclosure: When you click on links in this section and make a purchase, this may result in this site earning a commission at no extra cost to you.

Similar to station mode, there are several steps that you need to do to configure ESP32 as an AP:

  • Initialisation
  • Configuration
  • Start WiFi
  • Handle WiFi events

Initialisation

As discussed in previous article, the initialisation includes setting up nvs, esp-netif, create default loop, create wifi task and bind wifi driver with esp-netif. Those steps are discussed in details previously and are not mentioned here again. You are advised to revisit previous post when necessary to understand the following code

ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_create_default_wifi_ap();
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
                                                    ESP_EVENT_ANY_ID,
                                                    &wifi_event_handler,
                                                    NULL,
                                                    NULL));

wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));

Note that differ from station mode, you need to call esp_netif_create_default_wifi_ap() API to create a default network interface binding WiFi driver and TCP/IP stack.

Configuration

To configure WiFi parameters, you call esp_wifi_set_mode() and esp_wifi_set_config(). Since ESP32 is working as an AP, you need to pass WIFI_MODE_AP when setting its mode.

wifi_config_t wifi_config = {
    .ap = {
        .ssid = EXAMPLE_ESP_WIFI_SSID,
        .ssid_len = strlen(EXAMPLE_ESP_WIFI_SSID),
        .channel = EXAMPLE_ESP_WIFI_CHANNEL,
        .password = EXAMPLE_ESP_WIFI_PASS,
        .max_connection = EXAMPLE_MAX_STA_CONN,
        .authmode = WIFI_AUTH_WPA_WPA2_PSK
    },
};
if (strlen(EXAMPLE_ESP_WIFI_PASS) == 0) {
    wifi_config.ap.authmode = WIFI_AUTH_OPEN;
}

ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));

Note that here WiFi parameters are stored in project configuration using Kconfig. As discussed previously, Kconfig file contains definitions enclosed between menu and endmenu keywords. Between these keywords, you can define any number of parameters that you like or set a default value for each parameter. Using Kconfig allows you to remove hard-coded values from your code, e.g. you can store SSID and password credential information of your WiFi network.

menu "My WiFi Configuration"
	
	config ESP_WIFI_SSID
        string "WiFi SSID"
        default "MyESP32"
        help
            SSID (network name) for the example to connect to.
	
	config ESP_WIFI_PASSWORD
        string "WiFi Password"
        default "12345678"
        help
            WiFi password (WPA or WPA2) for the example to use.
	
	config ESP_WIFI_CHANNEL
        int "WiFi Channel"
        range 1 13
        default 1
        help
            WiFi channel (network channel) for the example to use.

    config ESP_MAX_STA_CONN
        int "Maximal STA connections"
        default 4
        help
            Max number of the STA connects to AP.

endmenu

Start WiFi

After initialising and configuring WiFi, you need to call esp_wifi_start() to start WiFi.

ESP_ERROR_CHECK(esp_wifi_start());

ESP32 has now been configured and started working as an AP waiting for clients to connect to.

Handle WiFi events

There are a number of events that the WiFi driver posts to the event task. The table below listed those events

EventDescription
WIFI_EVENT_AP_STARTIndicates WiFi has started
WIFI_EVENT_AP_STOPIndicates WiFi has stopped
WIFI_EVENT_AP_STACONNECTEDOccurs when a station is connected
WIFI_EVENT_AP_STADISCONNECTEDOccurs when a station is disconnected

You can write your code to do something when you receive these events. In this example, it simply prints out information of the station that is connected or disconnected from ESP32. In previous step, remember that wifi_event_handler callback has been registered to listen to any WiFi event. In the callback, we can extract which event is generated by checking event_id.

static void wifi_event_handler(void* arg, esp_event_base_t event_base,
                                    int32_t event_id, void* event_data)
{
    if (event_id == WIFI_EVENT_AP_STACONNECTED) {
        wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data;
        ESP_LOGI(TAG, "station "MACSTR" join, AID=%d",
                 MAC2STR(event->mac), event->aid);
    } else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) {
        wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data;
        ESP_LOGI(TAG, "station "MACSTR" leave, AID=%d",
                 MAC2STR(event->mac), event->aid);
    }
}

Get IP address of ESP32 AP

If you want to get the IP address of the ESP32 when it is configured as an AP, you can use the function esp_netif_get_ip_info(). This is useful, for example, when you want to access a web server hosted on the ESP32.

esp_netif_t * p_netif = esp_netif_create_default_wifi_ap();
esp_netif_ip_info_t if_info;
ESP_ERROR_CHECK(esp_netif_get_ip_info(p_netif, &if_info));
ESP_LOGI(TAG, "ESP32 IP:" IPSTR, IP2STR(&if_info.ip));

It will output the IP address of ESP32, like so:

I (830) MyApp: ESP32 IP:192.168.4.1

Change IP address of ESP32 AP

In some cases, you might want to change the default IP address of ESP32 AP, e.g. set it to be 192.168.1.1. You can do that by using API esp_netif_get_ip_info(). This snippet of code shows how to do it:

esp_netif_ip_info_t ipInfo;
IP4_ADDR(&ipInfo.ip, 192,168,1,1);
IP4_ADDR(&ipInfo.gw, 192,168,1,1);
IP4_ADDR(&ipInfo.netmask, 255,255,255,0);
esp_netif_dhcps_stop(p_netif);
esp_netif_set_ip_info(p_netif, &ipInfo);
esp_netif_dhcps_start(p_netif);

Wrapping Up

In this post, you have seen that steps to write an application to configure ESP32 as an AP is pretty much the same when configuring it as a station. You just need to make slight modification to your code. We will explore more complex WiFi projects in the coming posts.

1 thought on “ESP32 WiFi Access Point (ESP-IDF)”

Leave a Comment