Forum: Mikrocontroller und Digitale Elektronik Arduino als WOL server


von lens23 (Gast)


Lesenswert?

Hallo,

ich möchte mit meinem Arduino und dem Ethernet Shield einen PC über WOL 
starten können.
Ich habe im Internet volgenden Code gefunden.
Warum funktioniert er nicht? PC wird nicht gestartet.
1
 
2
3
// Arduino Wake-On-LAN
4
// Needs Arduino > 1.0-beta3 with the new UDP API ( http://code.google.com/p/arduino/wiki/Arduino1 )
5
6
// Date: 04 September 2011
7
// Author: Michele Spagnuolo
8
// Email: michele@spagnuolo.me
9
// Site: http://michele.spagnuolo.me
10
11
#include <SPI.h>
12
#include <Ethernet.h>
13
#include <EthernetUdp.h>
14
15
// ETHERNET CONFIGURATION
16
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xB1, 0xAC }; // Arduino's MAC address
17
byte ip[] = { 192, 168, 178, 21 }; // Arduino IP address
18
byte gw[] = { 192, 168, 178, 1}; // Gateway IP address
19
byte bc[] = { 192, 168, 178, 255 }; // Broadcast IP address
20
21
// WOL CONFIGURATION
22
byte pc_mac[] = {0x00, 0x24, 0x21, 0x7B, 0xA0, 0x07}; // PC's MAC address
23
24
EthernetUDP Udp;
25
26
char WOL_done = 0;
27
28
void setup() {
29
    Ethernet.begin(mac,ip,gw);
30
    delay(100);
31
    Udp.begin(7);
32
    delay(100);
33
}
34
35
void WOL(byte mac[]) {
36
    byte preamble[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
37
    char i;
38
39
    Udp.beginPacket(bc, 7);
40
    Udp.write(preamble, sizeof preamble);
41
    
42
    for (i=0; i<16; i++)
43
      Udp.write(mac, sizeof mac);
44
    
45
    Udp.endPacket();
46
}
47
48
void loop() {
49
  if (WOL_done)
50
    WOL(pc_mac);
51
  WOL_done = 1;
52
}

von Cyblord -. (cyblord)


Lesenswert?

Kannst du den PC denn überhaupt via WOL starten? Also mal von einem 2.PC 
über ein WOL-Tool versucht? Ist WOL korrekt aktiviert bei deinem PC?

von Bitflüsterer (Gast)


Lesenswert?

Den Code habe ich mir jetzt nicht angeschaut.

Zum einen muss Deine Ethernetkarte Wake-On-LAN unterstützen. Nicht alle 
tun das.
Zum anderen kann es sein, dass das Feature erst an/in der Hardware oder 
per Software (evtl. BIOS) aktiviert werden muss.

von lens23 (Gast)


Lesenswert?

Danke für eure schnellen Antworten.

Ich kann den PC von einem anderen PC aus ohne Probleme starten.

von Cyblord -. (cyblord)


Lesenswert?

Hast du mal die korrekte Byteorder der ganzen Adressen überprüft?

von Patrick (Gast)


Lesenswert?

Du rufst setup() einmal anfangs und dann loop() in einer Schleife auf?

Das da:
1
char WOL_done = 0;
2
...
3
void loop() {
4
  if (WOL_done)
5
    WOL(pc_mac);
6
  WOL_done = 1;
7
}

funktioniert somit natürlich nicht. Wahrscheinlich soll es
1
if (! WOL_done)
2
...

heißen.

von lens23 (Gast)


Lesenswert?

hab es geändert, funktioniert trotzdem nicht :-(

von Εrnst B. (ernst)


Lesenswert?

Dann: Am Ziel-PC wireshark laufen lassen, nachschauen, was für ein 
Packet dein Arduino da verbricht, und ob es überhaupt ankommt.

von micha (Gast)


Lesenswert?

lens23 schrieb:
> Ich habe im Internet volgenden Code gefunden.
> Warum funktioniert er nicht? PC wird nicht gestartet.

Stimmt der IP Adressraum?

von Dirk B. (dirkb2)


Lesenswert?

Das sizeof mac in der Funktion WOL liefert nicht den gewünschten Wert.
Da kommt sizeof (byte*) raus

Entweder du machst einen extra Paramter oder schreibst fest 6 rein.

von lens23 (Gast)


Lesenswert?

Dirk B. schrieb:
> Das sizeof mac in der Funktion WOL liefert nicht den gewünschten
> Wert.
> Da kommt sizeof (byte*) raus
>
> Entweder du machst einen extra Paramter oder schreibst fest 6 rein.

ok, jetzt nochmals bitte für dummies. Wo muss ich die 6 reinschreiben?

von Jürgen S. (jurs)


Lesenswert?

lens23 schrieb:
> ok, jetzt nochmals bitte für dummies. Wo muss ich die 6 reinschreiben?


Udp.write(mac, 6);

Weil Du das Array als Zeiger an die Funktion übergibst, ist "sizeof mac" 
nämlich nur 2 (= Größe des Zeigers).

von lens23 (Gast)


Lesenswert?

danke, funktioniert einwandfrei.
Jetzt würde ich noch gerne einen 2. PC Starten können :D
Wie mach ich dass am elegantesten?

von Karl (Gast)


Lesenswert?

lens23 schrieb:
> byte pc_mac[] = {0x00, 0x24, 0x21, 0x7B, 0xA0, 0x07}; // PC's MAC
> address

Die Adresse des 2. PC ebenfalls in ein Array schreien und dann aufrufen?

byte pc_mac_2[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05}; // 2. PC's MAC

WOL(pc_mac_2);

von lens23 (Gast)


Lesenswert?

alles klar, vielen Dank.
Funktioniert einwandfrei :-)

von ArminLinder (Gast)


Lesenswert?

Tschuldigt, wenn ich hier so an diesen alten Therad anstückle, aber ich 
bin gerade dabei, mich in die Ardiuno Programmierung zu stürzen. Ich 
verstehe nicht, wieso die vorgeschlagene Lösung funktioniert.
1
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xB1, 0xAC };

definiert doch keinen Pointer, sondern ein statisches Array of Byte der 
Größe 6. Deswegen müsste sizeof mac eigentlich 6 zurückgeben, so wie das 
wohl auch die Absicht des Autors des ursprünglichen Codes war.

Um einen Pointer zu definieren, müsste ich doch in etwa sowas schreiben:
1
int (*mac)[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xB1, 0xAC };

Ebenso bei der Übergabe an die WOL Funktion: ich sehe den Pointer nicht.

Kann jemand etwas genauer darlegen, wie der Pointer in den Code kommt, 
soass sizeof auf 2 kommt statt auf 6? Dass es so ist nehme ich mal an, 
denn sonst wäre das Problem keins gewesen. Ich kann aber beim besten 
Willen der Erklärung nicht folgen.

Vielen Dank,

Armin.

von Dirk B. (dirkb2)


Lesenswert?

ArminLinder schrieb:
> Ebenso bei der Übergabe an die WOL Funktion: ich sehe den Pointer nicht.

Bei Funktionsparametern zerfällt das Array automatisch zu einem Pointer 
auf den Anfang des Arrays. C Grundlagen.

: Bearbeitet durch User
von Einer K. (Gast)


Lesenswert?

ArminLinder schrieb:
> Deswegen müsste sizeof mac eigentlich 6 zurückgeben,

Vollkommen Richtig.
Tut es auch.
(wenn man es nicht vorher durch die Parameter Mühle verfälscht)

Dirk B. schrieb:
> Bei Funktionsparametern zerfällt das Array automatisch zu einem Pointer.
>  C Grundlagen.
Arduino spielt das Lied in C++
Man kann das also auch unterbinden. (Referenz übergeben oder/und als 
Array Typisieren)

ArminLinder schrieb:
> Ich kann aber beim besten
> Willen der Erklärung nicht folgen.
C++ führt die Größe im Datentype mit
1
using MyArrayType = byte[6];
2
3
MyArrayType macA { 0x90, 0xA2, 0xDA, 0x0D, 0xB1, 0xAC };
4
5
6
//--
7
8
byte macB[] { 0x90, 0xA2, 0xDA, 0x0D, 0xB1, 0xAC };
1
sizeof(MyArrayType) // sagt 6
2
sizeof(macA) // sagt 6
3
sizeof(macB) // sagt 6


Eine klügere Definition der Funktion sollte wohl in etwa so aussehen:
1
void WOL(const MyArrayType &mac) 
2
{
3
   Serial.println(sizeof mac);
4
}

von Dirk B. (dirkb2)


Lesenswert?

Arduino Fanboy D. schrieb:
> Arduino spielt das Lied in C++

Das sind Raw-Arrays wie in C.

Was du da schreibst ist nicht das Problem.


Schau dir die Zeile

Udp.write(mac, sizeof mac);

im Eröffnungspost an und sag, wieviel Byte da gesendet werden.

von Einer K. (Gast)


Lesenswert?

Dirk B. schrieb:
> und sag
Nix sage ich dazu!
Ist alles gesagt!

von Cyblord -. (cyblord)


Lesenswert?

Arduino Fanboy D. schrieb:
> Dirk B. schrieb:
>> und sag
> Nix sage ich dazu!
> Ist alles gesagt!

Aber noch nicht von jedem. Merke dir: Die Oper ist erst zu Ende wenn die 
dicke Dame gesungen hat.

von John (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:

> Nix sage ich dazu!
> Ist alles gesagt!

Arduino Fanboy eben. Große Klappe und nix dahinter.

von Einer K. (Gast)


Lesenswert?

John schrieb:
> Arduino Fanboy eben. Große Klappe und nix dahinter.

Schwachmat!


Wenn du nicht kapierst, wie man das

Dirk B. schrieb:
> zerfällt das Array automatisch zu einem Pointer
In C++ unterbindet, dann gute Nacht.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.