Apr 21

Auto-generated, Random, Persistent MAC Address for Arduino Ethernet

This is a follow up to our post from a couple of days on the same subject.

Whilst I still often use the code from our previous post without any issues, it was pointed out that the way it generates random addresses isn't random (the standard Arduino random functions aren't really random). This isn't an issue for most people's usage as it's not overly common to have loads (20+) of Arduino devices on the same local network.

Regardless, here's an updated version which is more random. It uses the TrueRandom library from tinkerit. The TrueRandom library generates random numbers by using a complicated algorithm, described by the authors themselves;

It is hard to get a truly random number from Arduino. TrueRandom does it by setting up a noisy voltage on Analog pin 0, measuring it, and then discarding all but the least significant bit of the measured value. However, that isn't noisy enough, so a von Neumann whitening algorithm gathers enough entropy from multiple readings to ensure a fair distribution of 1s and 0s.

The TrueRandom library does include a function to generate a MAC address for you, however it generates random bytes for all six octets of the address. This can cause issues as the first three octets are important and some network devices - such as your DHCP server - will ignore invalid addresses.

The first three octets are the "Organizationally Unique Identifier" or OUI, these are assigned to companies. I've use the OUI from GHEO Sa, which is the correct one for Arduino Ethernet. Then the rest of the MAC address or the last three octets is randomly generated.

Here's the code;

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

byte mac[6] = { 0x90, 0xA2, 0xDA, 0x00, 0x00, 0x00 };
char macstr[18];

void setup() {
  Serial.begin(9600);
  // Store MAC address in EEPROM
  if (EEPROM.read(1) == '#') {
    for (int i = 3; i < 6; i++) {
      mac[i] = EEPROM.read(i);
    }
  } else {
    for (int i = 3; i < 6; i++) {
      mac[i] = TrueRandom.randomByte();
      EEPROM.write(i, mac[i]);
    }
    EEPROM.write(1, '#');
  }
  snprintf(macstr, 18, "x:x:x:x:x:x", 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() {
}

As it includes an external library it's a little more annoying if you want to distribute your sketch and it also adds a little size to your program. For most situations you can use either solution and be completely fine, I've added this post for completeness.

Thanks for Mike for the prompt, if anyone else has any comments please feel free to add them below.

4 responses to "Auto-generated, Random, Persistent MAC Address for Arduino Ethernet"

  1. Pending moderation
  2. it works like a charm. thanks!
  3. Pending moderation
  4. Pending moderation

Leave a comment