How to get the MAC address of a W5500 shield?

This can't be a new question but I have not been able to find an answer. I am using an Arduino Mega with a Seeed Ethernet shield. The shield uses a W5500 chip. I looked through the libraries and found a reference to a getMacAddress function in the 5100.h source file.

gW5100.getMACAddress(mac_address)

I plugged it into my sketch (attached) and it compiled and ran, but all I get as a result are zeroes. (Screen shot, attached).

I looked at the datasheet for the W5500 chip and registers 0x0009 - 0x000E are used to store the MAC address. Does anyone know how I can read those registers?

Thanks,
Mike

Screenshot.jpg

ArduinoEthernet-01.ino (4.29 KB)

You don't read it until you assign it. In your code, this is it.

byte mac[] = { 0x2C, 0xF7, 0xF1, 0x08, 0x00, 0x9A };

// then in setup
  if (Ethernet.begin(mac) == 0)

Thanks.

My understanding was that these types of devices were shipped with MAC addresses already installed, that my defining it replaced it.

If this project works out I may end up making 150 or so per year and having to hard code the MAC address will be a real pain. I could store a value on the SD card, but that still means reading the number off the sticker and typing it in.

Mike

I'm working on this as well. It is strange that the answer is so hard to find.

Are you using this library: GitHub - Wiznet/WIZ_Ethernet_Library: WIZnet Ethernet Library ?

Did you uncomment the line: #define WIZ550io_WITH_MACADDRESS ?

Looking at your code, I would get rid of most of the code except the part that should get and print the mac id. It will make it easier to troubleshoot and for others to help.

In the WebClient example, you see this:

// start the Ethernet connection:
#if defined(WIZ550io_WITH_MACADDRESS)
if (Ethernet.begin() == 0) {
#else
if (Ethernet.begin(mac) == 0) {
#endif

If you uncommented the library properly, the first Ehernet.begin should give you the MAC address. I don't know my board in front of me, but from here, we just need to figure out how to access the variable that holds the mac id. It might be as simple as Serial.print(mac);

I'll give this a try this weekend, but please post back if you find the solution.

I found a thread on the Wiznet wiki that says it is not possible to get the mac address from within the software. You would have to get it from a router, for example.

http://wizwiki.net/forum/viewtopic.php?t=501

Hi guys,

I stumbled into this problem a days ago, and I think I came up with some solution (or so I think).

Before I came up with a solution, I read this thread: WIZ550io schematic and PIC memory for MAC Address - #4 by Edward - WIZ550io - WIZnet Developer Forum

So the conclusion is if you use software reset, the MAC Address value (and the other like IP, DNS, Gateway, etc) on the Common Register W5500 became zero. I peek into the Ethernet library and found out everytime we init the Wiznet module, we do software reset. You can find it on w5500.cpp:

void W5500Class::init(uint8_t ss_pin)
{
  SPI_CS = ss_pin;

  delay(1000);
  initSS();
  SPI.begin();
  w5500.swReset(); //<-- Software reset
  for (int i=0; i<MAX_SOCK_NUM; i++) {
    uint8_t cntl_byte = (0x0C + (i<<5));
    write( 0x1E, cntl_byte, 2); //0x1E - Sn_RXBUF_SIZE
    write( 0x1F, cntl_byte, 2); //0x1F - Sn_TXBUF_SIZE
  }
}

So what I do is comment the //W5500.swReset();, and voila, I can read the MAC Address. Here is the code to read MAC Address in case you need it. Don`t forget to uncomment #define WIZ550io_WITH_MACADDRESS on file Ethernet2.h first.

#include <SPI.h>
#include <Ethernet2.h>

IPAddress ip(192, 168, 202, 133);
EthernetServer server(80);

void setup() {
  Serial.begin(9600);
  Ethernet.begin(ip);
  server.begin();
  byte mac_address[6] ={0,};
  w5500.getMACAddress(mac_address);
  for(int i = 0; i < 6; i++) {
    Serial.write(mac_address[i]);
  }
}

void loop() {
}

But please be aware if your Wiznet module is already flashed by software reset, you need to rewrite the MAC Address using Ethernet.begin(mac) (and it goes without saying, please comment #define WIZ550io_WITH_MACADDRESS on file Ethernet2.h before do Ethernet.begin(mac)).

But this solution came up with anoher question: Why we need to do software reset after all? I have comment it and still haven`t find any problem till today. If you know, please kindly share it here.

Sorry for my bad english. Hope it helps guys.

1 Like

Reopened at the request of @m610

Dear mr Papatonk,
Your example does indeed give some data as a result, yet doing a reverse mac address search doesn't yield a vendor. The fact you got a result in the first place is probably because you gave "ip " as a parameter when calling the begin method of the Ethernet object where a mac address was expected.

Please investigate this a bit closer if you are still active on this forum, you could be propagating random data as mac addresses on your network.

To everyone else ending up in this forum after a search.
Do not take for granted that wiznet W5500 IC's have a fixed ip before being initialized which is what seems to be implied here. This needs at least some further investigation.

To anyone else who stumbling on this wondering about the mac addresses of wiznet chips , if you have w5500 boards please share your results if you try what mr Papatonk suggests.

Friendly regards.

Thank you for reopening this thread.

I hate to tell you this but @Papatonk has not been seen since 2017 so I doubt whether he/she will see your update

If people don't take what he does as scripture anymore I think what has been done here has served its purpose. It being the last post on a thread that's been viewed 27K times the message "investigate before using" seemed important.

I am also trying to be cordial and take account of everyone's sensibilities.

Hi Phoenixxl,

My example only works for W5500 that have internal MAC, which in my case w550io (WIZ550io | WIZnet Document System).

If you use barebone W5500, e.g. this one: (Amazon.com: HiLetgo 2pcs W5500 Ethernet LAN Network Module Support TCP/IP51/STM32 Microcontroller Program with 32k Bytes SPI 3.3V/5V Over W5100 : Electronics), it won't work at all. Please double check what module you are using.

Sincerely,
Papatonk

1 Like

Hi Papatonk,

First , thank you for taking the time to reply.

I was confused mainly because this thread began as a question about the " Mega with a Seeed Ethernet shield" which I presume isn't the w550io.

I am also surprised to see this comment in the Ethernet2 library:

Deprecated/Archived Library

This library is no longer going to be used, since the official Arduino library has been updated and works great

Since I don't see any support for the W550io in the arduino library.

I don't have a module with a w550io on it so sadly I can't investigate this any further. I'm glad this got cleared up somehow.

A few things though,

There is no definition of WIZ550io_WITH_MACADDRESS in ethernet2.h as far as i see. there is a check though, isn't the general idea you define it in a sketch instead of modifying the library?

Looking closer at ethernet2.cpp
there is a
"#if defined(WIZ550io_WITH_MACADDRESS)"
block which omits giving a mac address as a first parameter to the begin method but instead the method starts with ip as an argument.

Both the code inside the block and outside do call w5500.init(w5500_cspin); which has the swreset function in it as you mentioned above.

Would this maybe work as a fix?
1 ) adding "#define WIZ550io_WITH_MACADDRESS" in the ino.
2 ) changing w5500.cpp like this instead:

Let me underline , the reason why I asked for this thread to be reopened is because your code does yield a result when executed on an arduino with any w5500 type board attached to it. People thinking that result is a mac address and using it as such could potentially cause problems. Us discussing this a bit more hopefully shows people they should verify the result they get. There are online tools that verify if a MAC has the correct manufacturer bytes set. afaik the wiznet range is 00:08:DC:xx:xx:xx .

Friendly regards.

Hi Phoenixxl

"I was confused mainly because this thread began as a question about the " Mega with a Seeed Ethernet shield" which I presume isn't the w550io."

I understand the confusion. You know, at that time, the only W5500 I know is w550io. I'm not aware that any other module doesn't have internal MAC at that time, so I don't specify the module model that can be used for my example because I assume every W5500 does have internal MAC.

"There is no definition of WIZ550io_WITH_MACADDRESS in ethernet2.h as far as i see. there is a check though, isn't the general idea you define it in a sketch instead of modifying the library?"

You're correct, we need to avoid changing the library if possible. I think back on 2017, the definition is there, but maybe not anymore on recent version.

"Would this maybe work as a fix?
1 ) adding "#define WIZ550io_WITH_MACADDRESS" in the ino.
2 ) changing w5500.cpp like this instead:"

Or just call w5500.getMACAddress(mac_address) before Ethernet.begin(ip), so MAC can be retrieved before software reset. If I recall correctly, that's what I do instead messing around with the library. I forget if I should call SPI.begin() first or not, it's been a while, I don't work with W5500 anymore.

Double checking if the MAC is indeed from manufacture is a valid steps too. Hopefully it can enlighten anybody who tried to get internal MAC to works.

1 Like