ESP8266 style chipId for ESP32

This is not actually a question, but rather a solution I had previously tried searching this forum for and wanted to post for the benefit of other newbies like me.

I have been using ESP8266 boards (LOLIN D1 mini Pro’s specifically) for a project and recently started using ESP32 boards (LOLIN D32 Pro’s) as well in the same project. When I set up the project originally, I needed a way for the boards to self-identify and found a solution using ESP8266’s ESP.getChipId() along with a switch…case. (You can read the background here.)

The chip ID works great for this because it is relatively unique, but still provides an easy to work with integer. However, when moving to the ESP32, I ran into a problem because it doesn’t have getChipId. Fortunately, the chip ID for ESP8266 is just a decimal output of the last three bytes of the MAC address. So, you can extract those by truncating using a bitshift after calling the ESP32’s MAC address with ESP.getEfuseMac(). You use a 40-bit shift because in the ESP32, the MAC address is defined as a 64-bit integer, but you just want to keep the last 24 bits (aka 3 bytes). Also, I believe ESP.getEfuseMac() is preferred over WiFi.macAddress(), because it’s available even before starting the wifi.

Here’s the code I came up with:

uint64_t macAddress = ESP.getEfuseMac();
uint64_t macAddressTrunc = macAddress << 40;
chipID = macAddressTrunc >> 40;

The code assumes you have ‘uint32_t chipID;’ defined in your universal variables at the beginning of the sketch.

If you want to load the same sketch code on both ESP8266s and ESP32s, you can use #ifdef

#ifdef ESP8266
 chipID = ESP.getChipId();

#ifdef ESP32
 uint64_t macAddress = ESP.getEfuseMac();
 uint64_t macAddressTrunc = macAddress << 40;
 chipID = macAddressTrunc >> 40;

Thanks for sharing the solution you found cweinhofer!

If somebody as me will be using this solution, it can lead to unexpected problems. To identify devices I’m using only last 4 bytes from efuseMac. But because the efuseMac address it’s written in reverse order than reading it as Wifi MAC I ended up with 2 identical device trying to connect to Mqtt broker, which is big no no.

Just reverse the order and you’ll be fine:

uint32_t id = 0;
for(int i=0; i<17; i=i+8) {
  id |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
Serial.printf("%08X\n", id);

Thanks, Cicicok. You are indeed correct. I had just run into the same problem recently using my (incorrect) method and was trying to figure out what was going on. When I wrote my code, I didn't realize that EfuseMac uses little endian architecture (LSB comes first).

One question - you said you're using the last 4 bytes from efuseMac, but isn't it just the last 3 bytes?