Apr 19

Auto generated, persistent MAC address for Arduino Ethernet

Most of the Arduino projects we create here are network connected using Ethernet. Probably the most annoying thing about Arduino Ethernet shields is that they don't each have a unique MAC address. This means that if you're deploying a number (any number more than one, actually) on a local network then you're going to run into trouble.

Update: Here's a post showing an alternative, more random option.

A lot of people and most examples on the Internet hard-code the MAC address into the sketch. This is fine but soon becomes a hindrance if you're deploying a few boards or store your code in a version control system.

Generating a random MAC address is useful and quite simple but ideally we don't what the MAC address of each node to change each time it boots, this can cause issues with DHCP and also having a persistent MAC address is useful for sending with messages over the network to uniquely identify which node it came from.

Here's a simple example sketch which generates a random MAC address and stores it in EEPROM (non-volatile memory, the Arduino has a small amount). The random MAC address is generated on first boot, on each subsequent boot after that it is read back out of EEPROM to ensure it stays the same.

#include <SPI.h>
#include <Ethernet.h>
#include <EEPROM.h>

byte mac[6] = { 0xBE, 0xEF, 0x00, 0x00, 0x00, 0x00 };
char macstr[18];

void setup() {
  Serial.begin(9600);
  // Random MAC address stored in EEPROM
  if (EEPROM.read(1) == '#') {
    for (int i = 2; i < 6; i++) {
      mac[i] = EEPROM.read(i);
    }
  } else {
    randomSeed(analogRead(0));
    for (int i = 2; i < 6; i++) {
      mac[i] = random(0, 255);
      EEPROM.write(i, mac[i]);
    }
    EEPROM.write(1, '#');
  }
  snprintf(macstr, 18, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

  // Start up networking
  Serial.print("DHCP (");
  Serial.print(macstr);
  Serial.print(")...");
  Ethernet.begin(mac);
  Serial.print("success: ");
  Serial.println(Ethernet.localIP());
}

void loop() {
}

Feel free to use this example code for whatever you wish. The only thing to watch out for is if you are using EEPROM elsewhere in your sketch that you don't clobber the values. You can remove the macstr variable and associated print lines to save on program space and RAM (memory) if you need it.

3 responses to "Auto generated, persistent MAC address for Arduino Ethernet"

  1. Good idea, but pretty pretty average implementation.

    "Gives you a random MAC" is a bit kind... as it uses the 10 bit AnalogRead() for the seed it actually at most gives you one of 1024 MAC addresses. By the time you have 35 on a network odds are you will have a MAC address clash.

    Actually on second glance, why not just use the values of three calls to AnalogueRead() as the lower 3 bytes of the MAC address (maybe waiting a second between calls so it can get a little more random).

    Why bother much the random number generator at all, as you are working on the assumption that AnalogueRead() is returning a random number....

    Mike

  2. Thanks for the comment Mike.

    If you're got any improvements feel free to post them for everyone.

    Cheers,

    Hadley
  3. I've added another post showing an alternative, more random method here;

    https://nicegear.co.nz/blog/autogenerated-random-persistent-mac-address-for-ardu...

    Hadley

Leave a comment