ESP32 Arduino: Obtaining MAC address of stations connected to soft AP

In this tutorial we will check how to obtain the number of stations connected to a soft AP  hosted by the ESP32, running the Arduino core. We will also obtain their MAC addresses.  The tests were performed using a DFRobot’s ESP32 module integrated in a ESP32 development board.

 

Introduction

In this tutorial we will check how to obtain the number of stations connected to a soft AP  hosted by the ESP32, running the Arduino core. We will also obtain their MAC addresses.

If you need an introduction on how to set a soft AP on the ESP32 using the Arduino core, please check this previous post.

At the time of writing, I did not find any Arduino function that allowed to obtain the MAC addresses of the stations connected to the soft AP, so we are going to use some lower level functions and data structures from IDF, the software framework used under the hood by the Arduino core.

The station list printing functionality from this tutorial is based on this very good code example from lucadentella, which I encourage you to check.

The tests were performed using a DFRobot’s ESP32 module integrated in a ESP32 development board.

 

The code

We will start our code by including the WiFi.h library, in order to be able to setup the soft AP. Additionally, we will need to include the esp_wifi.h library, in order to be able to use the functions and data structures needed to get the information about the stations connected to the soft AP.

#include "WiFi.h"
#include "esp_wifi.h"

Next, we will declare the credentials of the WiFi network the ESP32 will host as global variables. We need to specify the network name and the password.

const char *ssid = "MyESP32AP";
const char *password = "testpassword";

Moving on to the setup function, we will start a serial connection so we can output the results of our code. Additionally, we will start the soft AP by calling the softAP method on the WiFi extern variable that is available after importing the WiFi.h library.

As input, this method receives both the network name and password, which were previously stored in the two global variables.

To finalize, we will also print the IP of the soft AP. You can check below the whole setup function. This way, we know that the procedure of setting the soft AP is finished as soon as the IP is printed.

void setup() {

  Serial.begin(115200);
  WiFi.softAP(ssid, password);

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

}

In the Arduino main loop, we will periodically call a function to print the MAC address of the stations connected to the soft AP. We will that function PrintStations and we will analyze the implementation later.

The Arduino main loop code can be seen below.

void loop() {
  PrintStations();

  delay(20000);
}

We will now implement the PrintStations function. As already mentioned, in order to get the MAC address of the connected stations, we will need to use some lower level functions and data structures, from IDF.

First, we will need a variable of type wifi_sta_list_t. This struct contains an integer field called num, which corresponds to the number of stations connected to the soft AP.

Additionally, it contains an array of wifi_sta_info_t variables, called sta. Each element of the array will contain the MAC address of a station connected to the soft AP.

Note that for now we are just declaring a variable of the wifi_sta_list_t, which doesn’t contain any information yet.

wifi_sta_list_t stationList;

To obtain the actual information of the stations, we need to call the esp_wifi_ap_get_sta_list function, passing as input the address of our previously declared wifi_sta_list_t variable.

This function returns a variable of type esp_err_t which can be used for error checking. Nonetheless, for this simple example, we will assume everything works as expected. Note however that in a final application you should always check for errors and act when an error is found.

esp_wifi_ap_get_sta_list(&stationList);

Now that we have the information on our stationList variable, we can access its num field and print the number of stations currently connected to the soft AP.

Serial.print("N of connected stations: ");
Serial.println(stationList.num);

Next, we can use this num field to loop through the information of each station. As mentioned, the information is stored in a field called sta, which corresponds to an array of wifi_sta_info_t variables. We will read one by one, at each iteration of the loop.

for(int i = 0; i<stationList.num; i++) {

    wifi_sta_info_t station = stationList.sta[i];

    // Print MAC address code
}

The wifi_sta_info_t struct has a field called mac, which is an array of type uint8_t with a length of 6. Since MAC addresses are composed by 6 bytes, each element of the array corresponds to a byte of the MAC address of the station.

So, we can iterate through this array and print the whole MAC address. Note that typically MAC addresses are represented in hexadecimal format, with each byte separated by “:” or “-“.

We will print the MAC addresses with the help of the sprintf function, using the %02x format specifier to convert each byte to its hexadecimal representation.

for(int j = 0; j< 6; j++){
    char str[3];

    sprintf(str, "%02x", (int)station.mac[j]);
    Serial.print(str);

    if(j<5){
      Serial.print(":");
    }
}

And with this we finish our function. The final source code can be seen below. It has some extra prints on the PrintStations function for better readability.

#include "WiFi.h"
#include "esp_wifi.h"

const char *ssid = "MyESP32AP";
const char *password = "testpassword";

void PrintStations()
{

  wifi_sta_list_t stationList;

  esp_wifi_ap_get_sta_list(&stationList);  

  Serial.print("N of connected stations: ");
  Serial.println(stationList.num);

  for(int i = 0; i < stationList.num; i++) {

    wifi_sta_info_t station = stationList.sta[i];

    for(int j = 0; j< 6; j++){
      char str[3];

      sprintf(str, "%02x", (int)station.mac[j]);
      Serial.print(str);

      if(j<5){
        Serial.print(":");
      }
    }
    Serial.println();
  }

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

void setup() {

  Serial.begin(115200);
  WiFi.softAP(ssid, password);

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

}

void loop() {
  PrintStations();

  delay(20000);
}

 

Testing the code

To test the code, first compile it and upload it to the ESP32 using the Arduino IDE. Once the procedure finishes, open the IDE serial monitor.

After setting the soft AP, it should print the its IP and the number of stations. Since no station is connected yet, it should output zero.

If you connect a station to the soft AP, then the next time the PrintStations function is called, it should output the MAC of that device and the number of stations should be updated to one.

As illustrated in figure 1, you can even connect more than one station and obtain the MACs of all the devices connected to the ESP32 soft AP.

ESP32 Arduino Soft AP MAC address of stations.png

Figure 1 – MAC addresses of the stations connected to the ESP32 soft AP.

You can then compare the printed MAC address with the MAC address of your device to confirm they match. In my case, one of my devices is a Windows machine. So, if I send the following command in the command line, I will get its MAC address:

ipconfig /all

You can check the result of this command in figure 2. I’m just showing the last byte of the MAC address of the device for privacy reasons, but you can confirm that it matches the one printed on the Arduino serial monitor.

Windows Machine Get MAC address.png

Figure 2 – MAC address of one of the machines connected to the ESP32.

 

Related Posts

Advertisements
This entry was posted in ESP32 and tagged , , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s