Arduino Ethernet

Auf der Suche nach einer VoIP-Probe, die ich als Spiegel und vielleicht auch Auswerteeinheit nutzen könnte, ist mir auch die Arduino-Plattform aufgefallen. Dort gibt es auch die Möglichkeit ein Ethernet-Shield aufzulöten oder direkt einen "Arduino Ethernet" zu kaufen. Die Programmierung ist recht einfach gestaltet und es gibt sogar schon ein Beispiel für einen UDP-Mirror, der Pakete auf Port 8888 annimmt und eine Antwort retour sendet.

Wenn Sie mit Arduino und Ethernet arbeiten, dann benötigen sie neben dem entsprechenden "Shield" auch eine entsprechende Library.

Es lohnt sich durchaus einmal in das Library-Verzeichnis (z.B. C:\Program Files (x86)\Arduino\libraries\Ethernet\examples) zu schauen. Oftmals sind dort sehr viele Beispiele abgelegt.

Hardware

Ich habe mit zwei Arduino Geräten experimentiert, die aber beide quasi die gleiche Funktion hatten. Das ist einmal der "originale" Arduino Ethernet, den man für ca. 50€ kaufen kann.

Zudem habe ich noch ein paar Arduino NANO und einen davon habe ich mit einem Ethernet-Shield basierend auf dem ENC28J60 bestückt.

Das gesamte Gerät ist quasi nicht viel größer als ein Daumen. Beide Geräte gibt es im entsprechenden Elektronik-Vertrieb oder als China-Nachbau. Bitte schauen Sie genau, dass Sie die richtige Library nutzen. Es gibt hier mehrere.

Raw-Performance

Aber zuerst hat mich interessiert, wie "schnell" diese Plattform überhaupt senden kann. Also habe ich basierend auf dem UDP-Sample einen "UDPStorm" programmiert.

arduinoethernet1.txt
Source zum Download

Schon im Taskmanager habe ich bei mir dann gesehen, dass der Durchsatz auch abhängig von der Größe der Pakete ist.

UDP Payloadgröße Durchsatz

10 Bytes

160KByte/Sec = 1,6MBit/Sek

100 Bytes

102KByte/Sec = 1 MBit

160 Bytes

95kByte/Sec = 0,95MBit

500 Bytes

90KByte/Sec = 0,9MBit

1000 Bytes

90KByte/Sec = 0,9MBit

1480 Bytes

90KByte/Sec = 0,9MBit

Auch wenn der Arduino einen 10/100 MBit-Port hat, so schafft er doch kaum mehr als 1 Megabit und das wird sicher noch abnehmen, wenn er sinnvolle Daten senden soll. Interessanterweise wurde der Durchsatz kleiner, wenn die Pakete größer wurden. Wenn ich mit der typischen VoIP-Größe arbeite von 160 Bytes, dann sendet der Arduino ca. alle 43ms ein Paket.

Das ist alles noch weit weg von 20ms-Paketabständen. Die Probe könnte also nicht mal ansatzweise einen einzigen VoIP-RTP-Datenstrom simulieren oder als "Performance Probe" arbeiten.

Damit kann ich das Experiment "Arduino als VoIP-Probe" hier beenden. Auch wenn man einen UDP-Mirror aufbauen wollte, wird das Ergebnis kaum sinnvoll sein. Da kann ein ICMP-Ping an einen Router vergleichbare Daten liefern.

Einsatz im LAN

Auch wenn der Einsatz als "Probe" also ausfällt, so kann ich mir durchaus noch andere Dinge vorstellen z.B. als IP-Türgong o.ä. Niemand wird aber die Box mit entsprechenden Adressen statisch versehen wollen. Interessant ist zumindest die Vergabe von IP-Adressen per DHCP und auch eine DNS-Abfrage wäre nett. Interessanterweise ist das aber schon in der Ethernet Library enthalten. Man muss einfach nur die IP-Adresse weglassen und prüfen, dass man eine IP-Adresse hat.

if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    while(true);  // Betrieb anhalten
}
delay(1000);    // give the Ethernet a second to initialize:

Und DNS ist auch schon enthalten. Allerdings muss immer noch die MAC-Adresse vorgegeben werden. Einige Arduino haben einen Chip, der eine eindeutige Adresse mitliefert. Wobei es hier eher kritisch ist, wenn mehrere Arduino im gleichen LAN unterwegs sind und daher doppelte MAC-Adressen stören. Die Wahrscheinlichkeit eine andere MAC Adresse zu verwenden ist relativ gering (2^48).

Übrigens: Wenn ich bei meinem Board das LAN-Kabel abziehe, bleibt für die Software die Verbindung erhalten. Ein Neuverbinden startet keine DHCP-Neuanfrage. Ein Reset hilft dann weiter.

Meldung per Syslog

Wenn die Probe wie hier natürlich keine sonstigen Ausgaben hat, sollte man einen Weg einbauen eine Rückmeldung zu erhalten. Per Default kann ein Arduino-Programm natürlich über den seriellen Port Ausgaben absenden aber dazu muss man sich direkt mit dem Arduino verbinden. Wenn aber das LAN funktioniert, dann ist SYSLOG ein adäquater Ersatz.

IPAddress syslogServer(192, 168, 10, 101); // IP Address of Syslog Server
EthernetUDP udp;                           // An EthernetUDP instance to let us send and receive packets over UDP

void setup() {
  Ethernet.begin(mac,ip); udp.begin(localudpPort);
  sendSyslogMessage(6, "Syslog logging started"); 
}

void sendSyslogMessage(int severity, String message)
{
  /*
   0 Emergency: system is unusable 
   1 Alert: action must be taken immediately 
   2 Critical: critical conditions 
   3 Error: error conditions 
   4 Warning: warning conditions 
   5 Notice: normal but significant condition 
   6 Informational: informational messages 
   */

  int pri = (32 + severity);
  String priString = String(pri, DEC);
  String buffer = "<" + priString + ">" + "AlarmSystem " + message;
  int bufferLength = buffer.length();
  char char1[bufferLength+1];
  for(int i=0; i  {
    char1[i]=buffer.charAt(i);
  }
  char1[bufferLength] = '\0'; udp.beginPacket(syslogServer, syslogPort); udp.write(char1); udp.endPacket();  
}

SNMP mit Arduino

Auch ein "Monitoring" per SNMP kann interessant sein, z.B. wenn man die Eingänge (Analog/Digital) mit einem externen Status verbindet und per SNMP anfragen kann. Hier habe ich aber nicht vor weiter zu entwickeln, da SNMP zwar wichtig aber für den Hausgebrauch nicht so einfach einzusetzen ist. Da ist es ein vielfaches einfacher, per HTTP die Daten abzurufen. Änderungen eines Wertes könnten per SNMP-Traps versendet werden. Aber auch hier muss dann ein SNMP Trap Receiver betrieben werden. Alles möglich aber für den Arduino sehe ich da nur wenig Einsatzbereiche. Daher belasse ich es hier bei ein paar Links.

Meldung per Mail, HTTP o.ä.

Neben SNMP und SYSLOG bleiben natürlich immer noch die "gängigen" Wege auf so einer kleinen Plattform Daten über das LAN zu verwenden. Aber über entsprechende Libraries kann ein Arduino natürlich auch einfache SMTP-Verbindungen aufbauen und so eine Mail versenden. Allerdings hört der Arduino natürlich nicht auf Gruppenrichtlinien o.ä., so dass im Code zumindest der Mailserver, der Sender und der Empfänger hinterlegt werden muss. Eventuell auch die erforderliche Authentifizierung mit Anmeldedaten. Eine SSL-Implementierung zum Schutz dieser Anmeldedaten habe ich noch nicht gefunden. Insofern würde ich per SMTP nur anonym versenden.

Wer einen WebServer betreibt, kann dort natürlich auch eine Skriptseite (PHP, ASPX o.ä.) hinterlegen, mit der man z.B. er HTTP-Get oder HTTP-Post die gewünschten Daten an den Webserver zur weiteren Verarbeitung übergeben kann. Ein einfacher HTTP-Zugriff ist mit den entsprechenden Libraries einfach möglich. Allerdings müssen Sie natürlich den aktiven Serverteil entwickeln und dauerhaft betreiben. Aber man sieht diesen Weg sehr oft. So gibt es einige Heizungen und Smarthome-Steuerungen, die per HTTP mit dem Mutterschiff des Betreibers sprechen. HTTP ist nun mal in vielen Umgebungen auch Anonym erlaubt, während SMTP meist als Schutz gegen Relay-Missbrauch zurecht blockiert wird.

Weitere Links