«

»

Nov 20

Print this Post

Arduino Wakes My PC

I always dreamed of controlling some of my house features through the Internet. See IPTV in my computer, turn ON/OFF lights, remote P2P downloads… To acomplish this, I needed a server – my old desktop computer should do the work. But of course, it’s not my intention to leave it awake the whole day/week/month… :)

I needed a way to bring it on whenever I wanted. So I tought I could use an Arduino with an Ethernet shield to send the Wake On Lan packets.

The UdpRaw allowed me to send raw packets, so all I needed was to implement the “magic packet” – it consists of 6 times 0xFF followed by 16 times the target MAC address.

So, first, I store that MAC address in a byte array. Take “00:00:00:36:45:C1″ as my example target MAC:

byte wolMac[] = { 0x00,0x00,0x00,0x36,0x45,0xC1 };

Now, all I need is to copy that 16 times, after 6 * 0xFF (102 bytes total). This is how I did it:

byte all[102];
int i,c1,j=0;

for(i = 0; i < 6; i++,j++){
  all[j] = 0xFF;
}
for(i = 0; i < 16; i++){
  for( c1 = 0; c1 < 6; c1++,j++)
    all[j] = wolMac[c1];
}

After running this code, the “all” array will have the complete magic packet, ready to send:

UdpRaw.sendPacket(all,102,targetIp,targetPort);

So to test it, I thought of a simple program that sends the packet when a pushbutton is pressed. To do this, I used an interrupt at pin 2. Basically, the Arduino keeps listening to that pin and whenever it raises from LOW to HIGH, it will execute a certain function.

After this, I plan to make the Arduino to listen to a port from the Internet and whenever it receives a certain packet sequence, it wakes the computer. This way I’ll be able to power up the computer from anywhere in the world! :D

Here is the whole Arduino code:

/*
* Arduino WakeMyPc
 * Ricardo Dias
 * http://ricardo-dias.com/
 *
 * This sketch sends the "magic packet" to wake up
 * a PC on Local Area Network when a push-button
 * is pressed.
 */

#include <Ethernet.h>
#include <UdpRaw.h>

// ARDUINO CONFIG
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // Arduino MAC
byte ip[] = { 192, 168, 1, 112 }; // Arduino IP
byte gw[] = { 192, 168, 1, 254 }; // Gateway IP address
int localPort = 8888; //local port to listen on

// THE TARGET
byte targetIp[] = { 192, 168, 1, 255 };
int targetPort = 5456;
byte wolMac[] = { 0x00,0x00,0x00,0x36,0x45,0xC1 }; // The target PC Mac Address

void setup() {
  Ethernet.begin(mac,ip,gw);
  UdpRaw.begin(localPort);

  // Will run the sendPkt() function when a button wired to
  // pin 2 is pressed
  attachInterrupt(0, sendPkt, RISING);
}

void loop() {
  delay(1);
}

void sendPkt(){
  // The 'magic packet' consists of 6 times 0xFF followed by 16 times
  // the hardware address (MAC).

  byte all[102];
  int i,c1,j=0;

  for(i = 0; i < 6; i++,j++){
    all[j] = 0xFF;
  }
  for(i = 0; i < 16; i++){
    for( c1 = 0; c1 < 6; c1++,j++)
      all[j] = wolMac[c1];
  }

  UdpRaw.sendPacket(all,102,targetIp,targetPort);
}

PS: You may be thinking “Why the hell doesn’t he send the packets directly to the computer?”.
Here is the explanation: my ISP loves to reset my router every night at 2AM. This way, when the router wakes up and the server is down, he doesn’t know to which ethernet port the server is connected. To overcome this issue, the packets need to be sent to the broadcast IP. However, this can only be done inside the LAN.

About the author

Ricardo Dias

Ricardo Dias was born in Entroncamento, Portugal and is studying Electronic and Telecommunications Engineering at University of Aveiro. He is a researcher in robotics and is currently the Team Leader of CAMBADA@MSL team. As a hobby, he is also a freelancer Stage Lighting Designer.

Permanent link to this article: http://ricardo-dias.com/2010/11/20/arduino-wakes-my-pc/

7 comments

Skip to comment form

  1. Nick Athan

    Dear friend, I recently bought an Arduino ethernet board, and I really need to wake my pc over LAN.
    Your code is what I really need, but I cannot compile it successfully. All times its stops and says “Error Compiling”

    Please can you compile it in Arduino 1+ and send me the code and the libraries I need to use?
    I am trying to make it work for over 10 hours and had no luck.

    Looking forward to your reply.

    Please help me,
    Nick Athanasoulas

    1. Ricardo Dias

      Hi Nick

      First, thanks for commenting and stating your problem.

      You may have pointed an issue that others may be noticing, mainly because at the date of this post, the official library did not include raw UDP methods.
      After being away from Arduino, I decided to take your challenge and it seems that things at the Ethernet library changed a bit since my post.

      I opened the documentation and immediatelly noticed the new EthernetUDP class.
      So now, let’s get rid of the unofficial library and change the code to accomodate this new one.

      First, you must include the SPI library, as it is now a dependency of the Ethernet:
      #include <SPI.h>

      Also, include the EthernetUDP class:
      #include <EthernetUdp.h>

      Now create an EthernetUDP object of that class:
      EthernetUDP Udp;

      Initialize it in the setup():
      Udp.begin(localPort);

      And use it as said in the docs:
      Udp.beginPacket(targetIp,targetPort);
      for(i = 0; i < 102; i++)
      Udp.write(all[i]);
      Udp.endPacket();

      PS: The code should compile, but unfortunatelly I currently have no way to test this, so I would really appreciate that you leave a message if it works out of the box. :) I would be happy…

      Best regards,
      Ricardo DIas

      1. Michael Frey

        I just tested the changes you have made, and it compiles successfully!

        Thanks a lot for this example.

        Regards
        Michael

  2. Bottle

    Dear Ricardo Dias

    I tried a several times to get the wol script working on my arduino ethernet board.
    But i can’t boot my pc with it !
    I have no compiling errors but i’m not sure if I write good code.

    Looking forward to your reply.

    1. Ricardo Dias

      Hey Bottle!

      I would suggest you try Wake On LAN by using other PC and software prior to Arduino.
      There are configurations that need to be set in the BIOS of the PC and sometimes on the router.

      Best regards,
      Ricardo Dias

  3. Jeana

    I like the valuable information you supply in your articles.
    I will bookmark your blog and take a look at once more right here frequently.
    I’m rather certain I will learn plenty of new stuff right right here!
    Best of luck for the following!

    1. Ricardo Dias

      Hello Jeana,

      Thank you :)

      Best regards,
      Ricardo Dias

Comments have been disabled.