Heute lag mein Ethernet Shield für das Arduino UNO und MEGA 2560 in der Post. Natürlich musste ich das gleich testen :)

In der Arduino IDE findet man praktischerweise unter Datei Beispiele Ethernet UDPSendReceiveString gleich ein Beispiel, zum Senden und Empfangen von UDP Nachrichten. Mir erschien es am sinvollsten damit zu beginnen, da UDP von der Implementirung her sehr einfach sein sollte.

Die ersten Daten senden

Mit dem UDPSendReceiveString kann man über UPD einen String (also einen Text) an das Arduino schicken, und bekommt diesen auf den seriellen Monitor geschrieben.

Als erstes muss man die IP-Adresse im Beispiel anpassen. Den Port habe ich bei mir auf 8888 gelassen.

//Die Beispiel Mac-Adresse koennt ihr ohne Probleme verwenden.
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};

//Hier eine IP-Adresse aus eurem Netzwerk
//In meinem Fall 192.168.1.5
IPAddress ip(192, 168, 1, 5);

//Port auf dem der UDP Server laeuft
unsigned int localPort = 8888;

Ich habe das ganze bei mir unter Windows 10 getestet, allerdings mit dem eingebauten Ubuntu: Alte Daten im UDP Buffer Wie man erkennen kann, hat der UDP Buffer eine Länge von 24 Byte, so das man also nur 24 Zeichen auf einmal an das Arduino schicken kann.

Dies sollte für die meisten Fälle komplett ausreichend sein, die Buffergröße kann aber auch frei gewählt werden. Im Beispiel wird der Buffer über die Konstante UDP_TX_PACKET_MAX_SIZE definiert, und ist deshalb nur 24 Byte groß.

//buffer to hold incoming packet
//UDP_TX_PACKET_MAX_SIZE == 24
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];

Des Weiteren, und was viel wichtiger ist, wird der Buffer in dem Beispiel Code nicht geleert!

Das bedeutet, ihr könnt bei euren Nachrichten Fragmente von alten Nachrichten bekommen (auch zusehen im Screenshot oben). Dies ist natürlich sehr störend, deshalb solltet ihr den Beispiel Code modifizieren, so das der Buffer zuerst komplett geleert wird.

   //Alten Buffer leeren
   for(int i=0; i < UDP_TX_PACKET_MAX_SIZE; i++){
     packetBuffer[i] = 0;
   }
   // read the packet into packetBufffer
   Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
   Serial.println("Contents:");
   Serial.println(packetBuffer);

Keine alten Daten mehr im UDP Buffer

LEDs über das Netzwerk schalten

Jetzt, wo ich erste Erfahrungen mit dem Ethernet Shield gesammelt habe, kann ich mich also an etwas eigenem versuchen. Für den Anfang werde ich erst einmal LEDs über das Netzwerk ein- und ausschalten.

Verkabelung Das UNO ist natürlich unter dem Ethernet Shield, allerdings fand ich diese Darstellung besser...

Dafür benötigen wir zunächst folgenden Code auf dem Arduino:

//MIT License
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>

#define LED_BLAU    2 //Pin 2
#define LED_ORANGE  3 //Pin 3

#define LED_BLAU_AN   101 //UDP String zum einschalten der blauen LED
#define LED_BLAU_AUS  102 //UDP String zum ausschalten der blauen LED

#define LED_ORANGE_AN  201 //UDP String zum einschalten der orangen LED
#define LED_ORANGE_AUS 202 //UDP String zum einschalten der orangen LED

unsigned int action;

byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};

IPAddress ip(192, 168, 1, 5);
unsigned int localPort = 8888;


char packetBuffer[UDP_TX_PACKET_MAX_SIZE];

EthernetUDP Udp;

void setup() {
  Serial.begin(9600);

  pinMode(LED_BLAU, OUTPUT);
  pinMode(LED_ORANGE, OUTPUT);

  Ethernet.begin(mac, ip);
  Udp.begin(localPort);
}

void loop() {
  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if (packetSize) {
    //Alten Buffer leeren
    for(int i=0; i < UDP_TX_PACKET_MAX_SIZE; i++){
      packetBuffer[i] = 0;
    }
    // Empfangene Daten lesen
    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
    //Empfangenen Text in Zahl umwandeln
    if(atoi(packetBuffer) > 0){
      action = atoi(packetBuffer);
    }else{
      Serial.println("Kein gueltiger Befehl");
      return;
    }

    switch(action){
      case LED_BLAU_AN:
        Serial.println("Schalte blaue LED ein");
        digitalWrite(LED_BLAU, HIGH);
        break;

      case LED_BLAU_AUS:
        Serial.println("Schalte blaue LED aus");
        digitalWrite(LED_BLAU, LOW);
        break;

      case LED_ORANGE_AN:
        Serial.println("Schalte orange LED ein");
        digitalWrite(LED_ORANGE, HIGH);
        break;

      case LED_ORANGE_AUS:
        Serial.println("Schalte orange LED aus");
        digitalWrite(LED_ORANGE, LOW);
        break;
    }
  }
  delay(10);
}

Wenn wir jetzt 101 über UDP an das Arduino senden, wird die blaue LED eingeschaltet. Mit 201 können wir noch die orange LED einschalten.

Ausschalten können wir die LEDs über 102 und 202

echo 101 | netcat -u 192.168.1.5 8888
echo 201 | netcat -u 192.168.1.5 8888

echo 102 | netcat -u 192.168.1.5 8888
echo 202 | netcat -u 192.168.1.5 8888

LEDs über UDP schalten