ESP32 Soft AP: Station disconnected event

In this tutorial we will check how to setup a soft AP on the ESP32 and handle the “station disconnected” event. We will be using the Arduino core. The tests from this tutorial were performed using an ESP32 board from DFRobot.

Introduction

In this tutorial we will check how to setup a soft AP on the ESP32 and handle the “station disconnected” event. We will be using the Arduino core.

In this previous tutorial, we have already covered how to handle the “station connected” event. Now we will be able to also handle the “station disconnected” event, which will allow us to better control the devices that are connected to the ESP32 network.

In the implementation of the handling function of the disconnected event we will print the MAC address of the disconnecting device.

For completeness, we will also handle the “station connected” event, so we can check exactly when the station connected and then disconneced from our network.

The tests from this tutorial were performed using an ESP32 board from DFRobot.

The code

We will start by including the WiFi.h library, so we have access to all the WiFi related functionalities we need for this tutorial.

#include <WiFi.h>

Then we will move on to the Arduino setup, where we will start by opening a serial connection, to output the results of our tests.

After this we will take care of setting up the ESP32 to work as a soft AP. We do this by calling the softAP method on the WiFi extern variable, passing as input the name we want to assign to our network.

Serial.begin(115200);
WiFi.softAP("MyESP32AP");

Then we will register the WiFi event handling functions. Recall from the introductory section that we will handle both the “station connected” and “station disconnected” events.

The corresponding event identifiers are SYSTEM_EVENT_AP_STACONNECTED and SYSTEM_EVENT_AP_STADISCONNECTED. We will later define two handling functions for each of the events we want to catch.

The “station connected” event handling function will be called “WiFiStationConnected” and the “station disconnected” event handling function will be called “WiFiStationDisconnected“.

As we did in the previous tutorials, we register WiFi event handling functions by calling the onEvent method on the WiFi extern variable, passing as first input the handling function and as second input the event identifier.

Naturally, since we want to register handling functions for two distinct events, we need to call the onEvent method twice, as shown below.

WiFi.onEvent(WiFiStationConnected, SYSTEM_EVENT_AP_STACONNECTED);
WiFi.onEvent(WiFiStationDisconnected, SYSTEM_EVENT_AP_STADISCONNECTED);

The full Arduino setup function can be seen below.

void setup() {
 
  Serial.begin(115200);
  
  WiFi.softAP("MyESP32AP");

  WiFi.onEvent(WiFiStationConnected, SYSTEM_EVENT_AP_STACONNECTED);
  WiFi.onEvent(WiFiStationDisconnected, SYSTEM_EVENT_AP_STADISCONNECTED);

}

To finalize, we will take care of defining both handling functions, which will have pretty much the same implementation, except that we will be accessing different structs to obtain the event information.

So, we will start by defining the WiFiStationConnected function. Its implementation will correspond to printing a message indicating that a station has connected and then printing the MAC address of that station. The procedure needed to obtain the MAC address in detail was already covered here.

In short, our handling functions receive as input a union of type system_event_info_t (aliased as WiFiEventInfo_t), which contains some additional information about the event.

In the case of the SYSTEM_EVENT_AP_STACONNECTED event, we can simply access to the sta_connected union member. This member corresponds to a struct of type system_event_ap_staconnected_t, which contains a data member called mac.

The mac data member is an array of 6 bytes that contains the MAC address of the station. This means we can simply iterate through this array and print all its elements.

The complete handling function is shown below. As can be seen, we are iterating through all the bytes of the MAC address and printing them in hexadecimal format. Bytes are being printed separated by colons, which is the usual format for representing a MAC address.

void WiFiStationConnected(WiFiEvent_t event, WiFiEventInfo_t info){
  
  Serial.println("Station connected");
  
  for(int i = 0; i< 6; i++){
    
    Serial.printf("%02X", info.sta_connected.mac[i]);  
    if(i<5)Serial.print(":");
  }

  Serial.println("\n------------");
}

The WiFiStationDisconnected function implementation will be exactly the same, except that we instead access a member of the system_event_info_t union that is called sta_disconnected.

This union member corresponds to a struct of type system_event_ap_stadisconnected_t, which also contains an array called mac with the 6 bytes of the address of the disconnected station.

The full implementation of this handling function can be seen below.

void WiFiStationDisconnected(WiFiEvent_t event, WiFiEventInfo_t info){
  
  Serial.println("Station disconnected");
  
  for(int i = 0; i< 6; i++){
    
    Serial.printf("%02X", info.sta_disconnected.mac[i]);  
    if(i<5)Serial.print(":");
  }

  Serial.println("\n------------");
}

The final code can be seen below.

#include <WiFi.h>

void WiFiStationConnected(WiFiEvent_t event, WiFiEventInfo_t info){
  
  Serial.println("Station connected");
  
  for(int i = 0; i< 6; i++){
    
    Serial.printf("%02X", info.sta_connected.mac[i]);  
    if(i<5)Serial.print(":");
  }

  Serial.println("\n------------");
}

void WiFiStationDisconnected(WiFiEvent_t event, WiFiEventInfo_t info){
  
  Serial.println("Station disconnected");
  
  for(int i = 0; i< 6; i++){
    
    Serial.printf("%02X", info.sta_disconnected.mac[i]);  
    if(i<5)Serial.print(":");
  }

  Serial.println("\n------------");
}
 
void setup() {
 
  Serial.begin(115200);
  
  WiFi.softAP("MyESP32AP");

  WiFi.onEvent(WiFiStationConnected, SYSTEM_EVENT_AP_STACONNECTED);
  WiFi.onEvent(WiFiStationDisconnected, SYSTEM_EVENT_AP_STADISCONNECTED);

}
 
void loop() {}

Testing the code

To test the code, simply compile it and upload it to your device. After the procedure finishes, wait a while until the network is setup.

After the network is setup, you should be able to see it from any WiFi enabled device, such as a Smartphone or a laptop.

Then, connect to the network using a device of your choice. After successfully connecting, disconnect from the network. You should get a result similar to figure 1.

As can be seen, after we connected to the network, the corresponding handling function was executed and the MAC address of the connecting device was printed.

Similarly, after the device disconnects from the network, the event handling function is executed and the MAC address of the disconnecting device got printed. The MAC printed on both events should match, since it refers to the same device.

Note: At the time of writing, there’s an issue on the Arduino core that makes the additional debug messages seen in figure 1 getting printed when a station connects. You can track the progress of the issue here.

Output of the program, showing the station connection and disconnection events information.
Figure 1 – Output of the program, showing the station connection and disconnection events information.

Related tutorials

ESP32 WiFi: Soft AP station connection event

ESP32 WiFi Soft AP: Getting MAC of connecting station

Leave a Reply