An Arduino with an Ethernet shield can wake a remote computer by sending a WOL (Wake on LAN) message. SendWOLMagicPacket is a simple function to send the WOL magic packet. It draws on the Arduino Waker project.
The SendWOLMagicPacket function takes a single argument—a pointer to the MAC address of the remote machine as a 6 byte array:
1 |
byte g_TargetMacAddress[] = {0x00,0x1A,0x4D,0x59,0x98,0xbc}; |
Here’s the source for an Arduino program to send wake-on-lan (WOL) packets to wake a remote machine:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
#include <SPI.h> #include <Ethernet.h> #include <Utility\Socket.h> void SendWOLMagicPacket(byte * pMacAddress) { // The magic packet data sent to wake the remote machine. Target machine's // MAC address will be composited in here. const int nMagicPacketLength = 102; byte abyMagicPacket[nMagicPacketLength] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; byte abyTargetIPAddress[] = { 255, 255, 255, 255 }; // don't seem to need a real ip address. const int nWOLPort = 7; const int nLocalPort = 8888; // to "listen" on (only needed to initialize udp) // Compose magic packet to wake remote machine. for (int ix=6; ix<102; ix++) abyMagicPacket[ix]=pMacAddress[ix%6]; if (UDP_RawSendto(abyMagicPacket, nMagicPacketLength, nLocalPort, abyTargetIPAddress, nWOLPort) != nMagicPacketLength) Serial.println("Error sending WOL packet"); } int UDP_RawSendto(byte* pDataPacket, int nPacketLength, int nLocalPort, byte* pRemoteIP, int nRemotePort) { int nResult; int nSocketId; // Socket ID for Wiz5100 // Find a free socket id. nSocketId = MAX_SOCK_NUM; for (int i = 0; i < MAX_SOCK_NUM; i++) { uint8_t s = W5100.readSnSR(i); if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT) { nSocketId = i; break; } } if (nSocketId == MAX_SOCK_NUM) return 0; // couldn't find one. if (socket(nSocketId, SnMR::UDP, nLocalPort, 0)) { nResult = sendto(nSocketId,(unsigned char*)pDataPacket,nPacketLength,(unsigned char*)pRemoteIP,nRemotePort); close(nSocketId); } else nResult = 0; return nResult; } |
Testing
The SendWOLMagicPacket function can be tested using the small harness below. After initializing the Ethernet port, it watches the Arduino’s serial port. Whenever the ‘w’ character is received, the test rig will send a wake command. The MAC address of the remote machine is defined in the global variable: g_TargetMacAddress
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
// Make up a mac Address and an IP address. Both should be globally unique or // at least unique on the local network. static byte g_abyMyMacAddress[] = {0x00,0x1A,0x4B,0x38,0x0C,0x5C}; static IPAddress g_MyIPAddress(192,168,15,44); // The machine to wake up. WOL should already be configured for the target machine. // The free windows program "Wake On LAN Ex 2" by Joseph Cox can be useful for testing the remote // machine is properly configured. Download it here: http://software.bootblock.co.uk/?id=wakeonlanex2 static byte g_TargetMacAddress[] = {0x00,0x1A,0x4D,0x59,0x98,0xbc}; void setup () { Ethernet.begin(g_abyMyMacAddress, g_MyIPAddress); Serial.begin(9600); Serial.println("Wake on Lan (WOL) Demo"); Serial.println("Send 'w' to initiate WOL"); } void loop() { // When 'w' is received, send a magic packet to wake the remote machine. if(Serial.available() > 0) if(Serial.read() == 'w') { SendWOLMagicPacket(g_TargetMacAddress); Serial.println("Magic packet sent"); } } |
Finding the MAC address
To wake a remote computer, you needs the physical address, or MAC address of the machine’s network. You can find a computer’s MAC address using the ipconfig function. Open up a command window on the machine you’d like to wake remotely and type ipconfig /all at the prompt. Look for the line labelled Physical Address. That’s the MAC address you need to give to the Arduino to wake the computer, as a 6 byte array:
1 |
byte abyTargetMacAddress[] = {0xE0,0xCB,0x4E,0x32,0x62,0xDD}; |