ESP32 ESP-IDF Get and Set Custom MAC Address

In this tutorial, we will learn how to get and set a custom MAC address of ESP32 using ESP-IDF framework. Setting the custom MAC address of ESP32 becomes very useful in many applications such as enhancing privacy, improving network compatibility, and avoiding address conflicts. We will begin by learning how to retrieve the default MAC address and then proceed to change it to a custom value.

MAC Address Introduction

A MAC address is a unique identifier assigned to each device for use as a network address in communications within a network segment. This use is common in most IEEE 802 networking technologies, including Ethernet, Wi-Fi, and Bluetooth. A MAC address is typically assigned by the manufacturer of a device and is stored in the card’s read-only memory (ROM). A MAC address is usually represented as a string of 12 hexadecimal characters separated by colons, for example:

00:11:22:33:44:55.

Although MAC addresses are assigned by manufacturers to devices, we can change them to a custom value. However, it is important to note that after each reboot of the ESP32, the MAC address will revert back to its original value and you will need to include a code to set the custom address every time the ESP32 is reset.

Create ESP32 ESP-IDF Project to Set and Get MAC Address

In this section, let’s create an ESP-IDF project to get and set MAC address.

Open your VS Code and head over to View > Command Palette. Type ESP-IDF: New Project in the search bar and press enter.

Specify the project name and directory. We have named our project ‘esp32_mac_address.’ For the ESP-IDF board, we have chosen the custom board option. For ESP-IDF target, choose ESP32 module. Click ‘Choose Template’ button to proceed forward.

create esp32 esp-idf project

In the Extension, select the ESP-IDF option:

ESP-IDF in VS Code New Project 2

We will click the ‘sample_project’ under the get-started tab. Now click ‘Create a project using template sample_project.’

ESP-IDF in VS Code New Project 3

You will get a notification that the project has been created. To open the project in a new window, click ‘Yes.’

This opens the project that we created inside the EXPLORER tab. There are several folders inside our project folder.

ESP32 ESP-IDF Code to Get and Set Custom MAC Address

This ESP32 ESP-IDF code gets the default MAC address and then proceeds to change it to a custom value. Finally prints them on the serial console of VS code.

Copy this code to the main.c file in the esp-idf project that we created above.

#include <stdio.h>
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"

#define MAC_ADDR_SIZE 6

uint8_t mac_address[6] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55};

static void get_mac_address()
{
    uint8_t mac[MAC_ADDR_SIZE];
    esp_wifi_get_mac(ESP_IF_WIFI_STA, mac);
    ESP_LOGI("MAC address", "MAC address: %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}

static void set_mac_address(uint8_t *mac)
{
    esp_err_t err = esp_wifi_set_mac(ESP_IF_WIFI_STA, mac);
    if (err == ESP_OK) {
        ESP_LOGI("MAC address", "MAC address successfully set to %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
    } else {
        ESP_LOGE("MAC address", "Failed to set MAC address");
    }
}

void app_main(void)
{
    esp_err_t ret = nvs_flash_init();
	if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
	{
		ESP_ERROR_CHECK(nvs_flash_erase());
		ret = nvs_flash_init();
	}
	ESP_ERROR_CHECK(ret);

    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    esp_netif_create_default_wifi_sta();

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
    ESP_ERROR_CHECK(esp_wifi_start());

    get_mac_address();
    set_mac_address(mac_address);
}

How Does this Code Work

Start by including the necessary header files.

#include <stdio.h>
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"

Then, define a constant MAC_ADDR_SIZE as 6, which is the size of a MAC address in bytes.

#define MAC_ADDR_SIZE 6

A global variable “mac_address” of size 6 is declared and initialized with the value {0x00, 0x11, 0x22, 0x33, 0x44, 0x55}. This is a custom MAC address which we will assign to ESP32.

The bit 0 of the first byte of ESP32 MAC address can not be 1. For example, the MAC address can set to be “1a:XX:XX:XX:XX:XX”, but can not be “15:XX:XX:XX:XX:XX”.

uint8_t mac_address[6] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55};

Getting ESP32 MAC Address

The “get_mac_address()” function gets the default factory MAC address of the ESP32. It uses the “esp_wifi_get_mac()” function to get the MAC address and then prints it on the console using the ESP_LOGI macro.


static void get_mac_address()
{
    uint8_t mac[MAC_ADDR_SIZE];
    esp_wifi_get_mac(ESP_IF_WIFI_STA, mac);
    ESP_LOGI("MAC address", "MAC address: %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}

Setting ESP32 MAC Address

The “set_mac_address()” function set a custom MAC address for the ESP32. It takes a pointer to the MAC address as an argument. The “esp_wifi_set_mac()” function is used to set the MAC address. If the function returns ESP_OK, the custom MAC address is successfully set, and a message is logged using the ESP_LOGI macro. If the function returns an error, an error message is logged using the ESP_LOGE macro.

Note: The MAC addresses for the ESP32 soft-AP and station should not be the same.

static void set_mac_address(uint8_t *mac)
{
    esp_err_t err = esp_wifi_set_mac(ESP_IF_WIFI_STA, mac);
    if (err == ESP_OK) {
        ESP_LOGI("MAC address", "MAC address successfully set to %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
    } else {
        ESP_LOGE("MAC address", "Failed to set MAC address");
    }
}

Before using esp_wifi_set_mac() function, WiFi must be initialized by esp_wifi_init().

This is a main function of an ESP32 application. The function initializes the non-volatile storage (NVS) flash memory system, initializes the networking interface and sets it up in station mode, and sets up the Wi-Fi configuration. The MAC address of the device is then retrieved and set to a predefined value.

void app_main(void)
{
    esp_err_t ret = nvs_flash_init();
	if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
	{
		ESP_ERROR_CHECK(nvs_flash_erase());
		ret = nvs_flash_init();
	}
	ESP_ERROR_CHECK(ret);

    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    esp_netif_create_default_wifi_sta();

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
    ESP_ERROR_CHECK(esp_wifi_start());

    get_mac_address();
    set_mac_address(mac_address);
}

ESP32 ESP-IDF OpenWeatherMap API Sensorless Weather Station Demo

In this section, we will see a demo to get and set the custom MAC address of ESP32. First of all, download the complete project from the following link and build the project.

To flash your chip, type the following command in the serial terminal. Remember to replace the COM port with the one through which your board is connected.

idf.py -p COMX flash monitor
ESP32 Web Server Control Output GPIO Project Flash Chip

After the code flashes successfully, if everything works fine, you will see the default and changed MAC address values printed on the console as shown below:

ESP32 ESP-IDF Set and Get MAC Address

You may also like to read:

2 thoughts on “ESP32 ESP-IDF Get and Set Custom MAC Address”

Leave a Comment