The solution I came up with is to save the MAC address in eeprom. There are two parts - the first part is a simple sketch (below) that accepts the MAC address from the serial terminal and writes it to eeprom. This only has to run once per board to initialise the MAC address on that board, though you can run it again if you want to change the address.
Code: Select all
#include <EEPROM.h>
const int eepromMacFlag = 0; // 1 byte
const int eepromMacAddress = 1; // 3 bytes
/*
Set_MAC_Address
Prompts for a MAC address from the serial port and stores it in EEPROM for use by later sketches.
*/
// Set up ethernet
// assign a MAC address for the ethernet controller.
// MAC address is stored in EEPROM on initial run
byte mac[] = {0x90, 0xA2, 0xDA, 0x00, 0x00, 0x00};
byte loadMAC = true;
int SerialReadHexDigit() {
while (Serial.available() == 0) {
// do nothing
}
byte c = (byte) Serial.read();
Serial.print((char)c);
if (c >= '0' && c <= '9') {
return c - '0';
}
else if (c >= 'a' && c <= 'f') {
return c - 'a' + 10;
}
else if (c >= 'A' && c <= 'F') {
return c - 'A' + 10;
}
else {
return -1; // getting here is bad: it means the character was invalid
}
}
int SerialReadHexByte() {
byte a = SerialReadHexDigit();
byte b = SerialReadHexDigit();
if (a<0 || b<0) {
return -1; // an invalid hex character was encountered
}
else {
return (a*16) + b;
}
}
char * printMac(byte * mac) {
char macstr[18];
snprintf(macstr, 18, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
Serial.println(macstr);
}
void setup() {
// start serial port:
Serial.begin(9600);
Serial.println("");
// Retrieve MAC address from EEPROM if present
if (EEPROM.read(eepromMacFlag) == '#') {
Serial.print("MAC address already in EEPROM: ");
for (int i = 0; i < 3; i++) {
mac[i+3] = EEPROM.read(eepromMacAddress + i);
}
printMac(mac);
Serial.print("Overwrite (Y/n)? ");
while (Serial.available() == 0) {
// do nothing
}
char c = Serial.read();
if (c == 'n' || c == 'N') { loadMAC = false; }
Serial.println("");
}
if (loadMAC) {
Serial.println("Initialising MAC address");
byte macchar[2];
for (int i = 0; i < 3; i++) {
Serial.println("");
Serial.print("Enter MAC address byte ");
Serial.print(i+3);
Serial.print(": ");
mac[i+3] = SerialReadHexByte();
EEPROM.write(eepromMacAddress + i, mac[i+3]);
}
EEPROM.write(eepromMacFlag, '#');
Serial.println("");
Serial.print("Saved MAC Address:");
printMac(mac);
} else {
Serial.println("Aborted");
}
}
void loop(){
}
Code: Select all
#include <SPI.h>
#include <util.h>
#include <EEPROM.h>
// EEPROM locations
const int eepromMacFlag = 0; // 1 byte
const int eepromMacAddress = 1; // 3 bytes
#include <Ethernet.h>
// Default MAC address for the ethernet controller.
// Unique MAC address can be stored in EEPROM using Set_MAC_Address sketch
byte mac[] = {0x90, 0xA2, 0xDA, 0x00, 0xFF, 0xFF};
const int outputStringLen = 200;
char outputString[outputStringLen]; // buffer used for constructing output strings
void setup() {
// start serial port:
Serial.begin(9600);
// start the Ethernet connection and the server:
// Retrieve MAC address from EEPROM if present
if (EEPROM.read(eepromMacFlag) == '#') {
Serial.println("Retrieving MAC address from EEPROM");
for (int i = 0; i < 3; i++) {
mac[i+3] = EEPROM.read(eepromMacAddress + i);
}
}
else {
Serial.println("No MAC address stored in EEPROM");
Serial.println("Using default MAC address");
}
snprintf(outputString, outputStringLen, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
Serial.print("MAC Address: ");
Serial.println(outputString);
Serial.println("DHCP...");
while (Ethernet.begin(mac) == 0) {
Serial.println("No DHCP");
delay(1000);
Serial.println("DHCP...");
}
Serial.println("IP address: ");
Serial.println(Ethernet.localIP());
}