WOL come accendere un computer con Arduino

Con alcune righe di codice possiamo utilizzare la funzione wake on lan disponibile in tutti i computer per poterli accendere inviando un particolare pacchetto di dati attraverso la rete lan (magic packet).
Questa caratteristica abbinata a una scheda Arduino Ethernet (o con ethernet shield) può risultare utile in moltissimi casi come ad esempio, l’accensione programmata o l’accensione simultanea di gruppi di computer.

Permettere alla board di avviare il computer mi da la possibilità di espandere il campo di applicazione, soprattutto nel caso in cui si ha la possibilità di utilizzare delle piccole schede madri come le nano-itx per realizzare applicazioni anche complesse.

Solitamente la funzione wol è disabilitata, per attivarla bisogna accedere al bios del computer e navigare nei menu fino ad abilitare il Wake on lan. Dovete consultare il manuale della vostra scheda madre perché ogni modello a la sua voce specifica.

Ora è necessario conoscere il MAC address della scheda di rete montata sulla mainboard. Dopo aver avviato il sistema operativo (Windows nel mio caso) aprite una finestra prompt dei comandi (Start->Esegui->cmd.exe) e digitate il seguente commando

ipconfig /all

verranno elencate una serie di parametri tra cui la voce “Indirizzo fisico” composta da sei byte esadecimali. Annotate questi valori.

La composizione del magic packet che avvia il pc, rispetta una particolare sintassi, infatti è composto da 102 byte dove i primi 6 vengono settati al valore 0xFF e i successivi vengono settati con l’indirizzo fisico (mac address) ripetendolo per 16 volte

wake on lan magic packet

il protocollo utilizzato per l’instradamento è quello UDP, sulla porta 7 oppure 9.

Il codice seguente è ricco di commenti che descrivono bene il funzionamento del sistema.

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>

//Configurazione Arduino Ethernet
byte arduino_MAC[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte arduino_IP[] = { 192, 168, 0, 250 };

//Porta UDP locale
int portaLocale = 7;

//Indirizzo broadcast della rete locale
byte broadCastIp[] = { 192, 168, 0, 255 };
//Mac address della scheda lan del pc da avviare
byte remote_MAC_ADD[] = { 0x00, 0x0D, 0x9D, 0xD8, 0x80, 0xC8 };
//Porta UDP WOL
int wolPort = 9;

//Creao un oggetto EthernetUDP
EthernetUDP Udp;

void setup()
{
  //init modulo ethernet WIZ5100
  Ethernet.begin( arduino_MAC, arduino_IP);

  //init oggetto EthernetUDO
  Udp.begin(portaLocale);

  //definisco un pin in input per accendere il pc
  //quando richiesto
  pinMode(3, INPUT);

}

void loop()
{
  //controllo il pin3
  //se è presente un livello logico alto invio
  //il magic Packet
  if(digitalRead(3) == HIGH)
  {
    inviaMagicPacket();
  }
}

//funzione per la creazione e l'invio
//del magic packet
void inviaMagicPacket()
{
  //definisco un array da 102 byte
  byte magicPacket[102];
  //variabili per i cicli
  int Ciclo = 0, CicloMacAdd = 0, IndiceArray = 0;

  for( Ciclo = 0; Ciclo < 6; Ciclo++)
  {
    //i primi 6 byte dell'array sono settati al valore 0xFF
    magicPacket[IndiceArray] = 0xFF;
    //incremento l'indice dell'array
    IndiceArray++;
  }

  //eseguo 16 cicli per memorizzare il mac address del pc
  //da avviare
  for( Ciclo = 0; Ciclo < 16; Ciclo++ )
  {
    //eseguo un ciclo per memorizzare i 6 byte del
    //mac address
    for( CicloMacAdd = 0; CicloMacAdd < 6; CicloMacAdd++)
    {
      magicPacket[IndiceArray] = remote_MAC_ADD[CicloMacAdd];
      //incremento l'indice dell'array
      IndiceArray++;
    }
  }

  //spedisco il magic packet in brodcast sulla porta prescelta
  Udp.beginPacket(broadCastIp, wolPort);
  Udp.write(magicPacket, sizeof magicPacket);
  Udp.endPacket();

}

Mentre il circuito elettrico è il seguente

Wake on lan

Quando forniamo alimentazione al pin3, Arduino invierà, tramite il modulo ethernet, il magic packet producendo l’accensione del pc.