UDP-Pakete zwischen Python-Programm und Arduino: Probleme

Hallo liebe Community,

ich habe einen Arduino Leonardo ETH und versuche momentan einen UDP-Austausch zwischen meinem PC und dem Arduino via Ethernet hinzubekommen. PC-seitig habe ich in Python programmiert.

Nun besteht folgendes Problem: Senden von UDP-Paketen zum Arduino (genauer zum entsprechenden Port) funktioniert immer. Allerdings scheint der Arduino die Pakete nicht immer entgegenzunehmen. Da Pakete vom Arduino nur zurückgesendet werden sollen, wenn vorher ein Paket auf dem Arduino eingegangen ist, kommt dann natürlich auf dem PC auch nichts an.
Manchmal funktioniert es allerdings. Wenn es nicht funktioniert, dann hilft es manchmal, wenn ich den Arduino kurz vom Strom entkopple und wieder anschließe. Wenn es denn mal läuft und ich dann das exakt gleiche Programm auf den Arduino hochlade, funktioniert es hinterher nicht mehr.

Folgendes habe ich schon versucht: Als erstes habe ich gecheckt, ob die Firewall bestimmte Ports blockiert. Habe die Firewall abschaltet, aber das Problem besteht weiter. Dann habe ich PC-seitig im Python-Programm die Kommunikation an einen spezifischen Ausgangsport gebunden, da die Ausgangsports ansonsten ja zufällig vergeben werden und ich vermutete, dass es (warum auch immer) Probleme mit bestimmten Ports gibt. Hat aber auch nichts geholfen.
Dann habe ich mit Wireshark die Kommunikation zwischen PC und Arduino beobachtet. Man sieht dann, dass vom PC aus Pakete an die Arduino-IP mit dem eingestellten Port (5005, siehe Code unten) gesendet werden. Das Problem liegt also nicht am Python-Programm.

Jetzt bin ich ziemlich ratlos: Die Pakete kommen am Port an, auf dem der Arduino abhört, aber aus irgendeinem Grund erkennt der Arduino nicht, dass Pakete bereitliegen.

Ich hoffe mir kann jemand helfen, ich bin nämlich mit meinem Latein am Ende.

Nun die Codes (zuerst der Arduino-Code):

#include <SPI.h>
#include <Ethernet2.h>
#include <EthernetUdp2.h>   

byte mac[] = {
  0x90, 0xA2, 0xDA, 0x10, 0x5D, 0xA8
};
IPAddress ip(169, 254, 219, 101);

unsigned int localPort = 5005;

char packetBuffer[UDP_TX_PACKET_MAX_SIZE];

EthernetUDP Udp;

void setup() {
  Ethernet.begin(mac, ip);
  Udp.begin(localPort);
  Serial.begin(9600);
}

void loop() {
  int packetSize = Udp.parsePacket();
  Serial.println(packetSize);
  if (packetSize)
  {
    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write("Hallo");
    for(int i=0;i<UDP_TX_PACKET_MAX_SIZE;i++) packetBuffer[i] = 0;
    Udp.endPacket();
  }
  delay(1000);
}

Das Python-Programm:

import socket
from time import gmtime, strftime
import time
UDP_IP = "169.254.219.101"
UDP_PORT = 5005
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
sock.settimeout(2)
while True:
    MESSAGE = "Hallo Arduino"
    sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))

    try:
        data, addr = sock.recvfrom(1024)
        print "received message:", data
    except Exception,e:
        print e

    time.sleep(2)

Ich hab keine Ahnung von Python aber warum haben beide Teilnehmer die gleiche IP Adresse so wie Port??

Die im Python-Programm eingestellte IP-Adresse und Port geben nur an, welche IP der Empfänger hat und welchen Port dieser abhört. Die IP vom PC steht ja fest.

Und woher weiß der Arduino wo er hinschicken soll?

Der Arduino erkennt, wenn ein Paket vom PC bereit liegt. Dieses Paket enthält auch die Informationen über die IP und den Port des PCs. Ich sehe auch gerade, dass Teile des Arduino-Codes nicht kopiert wurden. Ich korrigiere das mal eben.

Zur Erläuterung: UDP ist ein verbindungsloses Netzwerkprotokoll. Es muss also keine ständige Verbindung zwischen Server und Client bestehen. Im Prinzip kann jeder beliebige Client ein Paket an den Server (den Arduino) senden. Der Arduino sendet dann an die IP mit entsprechendem Port zurück, die im empfangenen Paket mit enthalten sind.

Bei “copy and paste” fehlen nicht einfach mal Zeilen mittendrin…

Ja jetzt sieht das schon ganz anders aus.