UDP Packet kommt nur einmal an

Guten Morgen,

ich stehe vor folgendem Problem und hoffe hier im Forum einen Hinweis zu bekommen.
Die Historie ist wie folgt:
Windows PC mit Processing Sketch schickt mittels UDP / Ethernet eine Nachricht an einen Arduino Nano mit Ethernet-Shield. Der Nano erhält die Nachricht und sendet eine Nachricht mit Messwerten, usw. an den PC / Processing. Dieser Ablauf funktioniert einbandfrei.

Im nächsten Schritt wurde der PC mit Processing Sketch gegen einen Raspbeery mit Phyton Sketch getauscht. Der Rasbi sendet nun mittels UDP alle 10s seine Nachricht (mit WireShark geprüft) an den Arduino Nano.

Und nun das Problem: Der Nano empfängt die UDP Nachricht genau einmal (das eine mal auch korrekt) nach dem Neustart, danach nicht mehr.
Hat jemand eine Idee, was die Ursache sein kann, bzw. in welche Richtung ich suchen muss?
Bin gespannt auf Eure antworten.
Vielen Dank im Voraus
Christian

// Ethernet Shield (an Pins 10, 11, 12, 13)
// 1wire Bus (an Pin 5)
// Ultraschallsensor an PIN 3 und 4
// Tx und Rx Ultraschall müssen bei der Sketch Übertragung entfernt werden!!!

#include <SoftwareSerial.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <SPI.h>                 // needed for Arduino versions later than 0018
#include <UIPEthernet.h> // für NANO (für UNO und MEGA wäre #include <Ethernet.h> notwendig

// Dieser Arduino
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEF};
IPAddress ip(192, 168, 178, 55);
IPAddress gateway(192, 168, 178, 1);
IPAddress subnet(255, 255, 255, 0);
#define UDP_TX_PACKET_MAX_SIZE 64

unsigned int localPort = 8888;      // local port to listen on

//Zieladresse
IPAddress ipZiel(192, 168, 178, 42);
unsigned int localPortZiel = 6000;

// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];  //buffer to hold incoming packet,
char  ReplyBuffer[] = "Erhalten";           // a string to send back

EthernetUDP Udp;  // An EthernetUDP instance to let us send and receive packets over UDP

// OneWireBus
#define ONE_WIRE_BUS 5 // Digitalport Pin definieren
float Temp1;           // Temperaturwert 1
DeviceAddress Sensor1 = {0x28, 0xFF, 0x98, 0x87, 0x50, 0x17, 0x04, 0x06}; //Temperatursensor 1

OneWire ourWire(ONE_WIRE_BUS); /* Ini oneWire instance */
DallasTemperature sensors(&ourWire);/* Dallas Temperature Library für Nutzung der oneWire Library vorbereiten */

//Ultraschall pin assignments. TX on the arduino connects to RX on the sensor, RX to TX.
#define TX_PIN 3
#define RX_PIN 4

SoftwareSerial DYPSensor = SoftwareSerial(RX_PIN, TX_PIN);
const int MAX_TRY_SERIAL = 50; // how many cycles of 10ms to wait for before giving up on the sensor (up to 255)
int abstand;
int abstand_soll = 200;
int schalter = 0;
int current_reading;
 
//***************************************************************************************************************************
void setup() {
  Ethernet.begin(mac, ip); // start the Ethernet
  Udp.begin(localPort);    // start the UDP
  Serial.begin(9600);      // start Seriale Kommunikation
  sensors.begin();// Inizialisieren der Dallas Temperature library
  DYPSensor.begin(9600); //Ultraschallmessung
  
  //Start Informationen auf Serialem Monitor
  Serial.print("Local IP: ");
  Serial.print(Ethernet.localIP());
  Serial.print(", UDP Port: ");
  Serial.println(localPort);
  Serial.println("_____________________________________________________________");  

 delay(10);
} // end of setup

//***************************************************************************************************************************
void loop() { //1
    //UDP empfangen, falls etwas gekommen ist
  int packetSize = Udp.parsePacket();    // if there's data available, read a packet
  if (packetSize) { //2
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remote = Udp.remoteIP();
    for (int i = 0; i < 4; i++) { //3
      Serial.print(remote[i], DEC);
      if (i < 3) { //4
        Serial.print(".");
      } //4
    } //3
    Serial.print(", port ");
    Serial.println(Udp.remotePort());
    
    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);       // read the packet into packetBufffer
    Serial.print("Contents:  ");
    String Nachricht1(packetBuffer);
    String Nachricht2 = Nachricht1.substring(0,packetSize);
    Serial.println(Nachricht2);
    // Ende der eingehenden UDP Nachricht
    // Jetzt kann die Nachricht verarbeitet werden........

  delay(50);
  temperaturen();
  udp_antwort();
}//2
current_reading = GetDistance();
 if (current_reading > 10){ //2
  Serial.print(current_reading);
  abstand = current_reading;
  Serial.println("cm");
  if (abstand < abstand_soll) {
    schalter = 1;
    udp_antwort();
    delay(5000);
  } else {
    schalter = 0;
  }
  Serial.print("Schalter = ");
  Serial.println(schalter);
 }//2

} //1
//--------------------------------------------------------------------------------------
int GetDistance() {
 byte msb, lsb, checksum, checkcalc, tries = 0;
 int distance;

// we want a 255 which is the start of the reading (not msb but saving a byte of variable storage)..
 while (msb != 255) {
 // wait for serial..
 while ( not DYPSensor.available() && tries < MAX_TRY_SERIAL ) {
 delay(10);
 tries++;
 }
 if (tries == MAX_TRY_SERIAL) {
 Serial.println(" TIMED OUT WAITING FOR SERIAL.");
 return -1;
 }
 msb = DYPSensor.read();
 }

// now we collect MSB, LSB, Checksum..
 while ( not DYPSensor.available() ) {
 delay(10);
 }
 msb = DYPSensor.read();

while ( not DYPSensor.available() ) {
 delay(10);
 }
 lsb = DYPSensor.read();

while ( not DYPSensor.available() ) {
 delay(10);
 }
 checksum = DYPSensor.read();

// is the checksum ok?
 checkcalc = 255 + msb + lsb;

if (checksum == checkcalc) {
 distance = msb * 256 + lsb;
 // Round from mm to cm
 distance += 5;
 distance = distance / 10;

return distance;
 } else {
 //Serial.println("bad checksum - ignoring reading.");
 return -1;
 }

} // end of GetDistance()

//--------------------------------------------------------------------------------------
void udp_antwort() {
    // senden der Antwort an Ziel IP/Port
    Udp.beginPacket(ipZiel, localPortZiel);
    Udp.println(String("112;") + int(Temp1*100) + String(";END"));//°C Temperatur Briefkasten
    Udp.println(String("401;") + abstand + String(";END"));// aktueller Abstand
    Udp.println(String("402;") + schalter + String(";END"));// aktuelle Schaltsignal
    Udp.println("END");
    Udp.endPacket();
}
//--------------------------------------------------------------------------------------
void temperaturen() {
   sensors.requestTemperatures();
   Temp1 = sensors.getTempC(Sensor1); 
   
   Serial.println("");
   Serial.println("_____________________________________________________________");
   Serial.println("Temperaturen:");
   Serial.println(String("Temp 1: ") + Temp1 + String("°C Temperatur Stromzähler"));
   Serial.println("_____________________________________________________________");
   Serial.println("");
}

UDP_Briefkasten.ino (5.96 KB)

Beide UDP-Packets (vom PC und vom Raspi) mal mit Wireshark untersucht? Gibts Unterschiede? Evtl. ist das vom Raspi zu groß und es gibt im Nano bzw. Nano-Shield einen Puffer-Überlauf?

Plan B: Nach jedem erfolgreichen Empfang am Nano einen Hard-Reset mittels Pin auslösen. Soft-Reset (ASM Jump auf Adresse 0) Initialisiert oft den Ethernet-Shield nicht richtig ...

Reboot als Fehlerklärung dient nur der Verschleierung schlechter Programmierung.

Was soll das delay(5000) in einem Programm, dass auf Anfragen wartet.

Ansonsten probiere mal den Puffer zu erhöhen:

#define UDP_TX_PACKET_MAX_SIZE 64

Gruß Tommy

Hallo,

vielen Dank für die schnellen Antworten. Habe jetzt beide UDP Packete (vom PC und Raspi) mit WireShark erfasst. Die Packetgrößen sind mit 44bytes gleich groß. Den Puffer habe ich auf 64 erhöht.

Leider keine Änderung. Es kommt nur das erste Packet nach Neustart an.

Ich habe leider keine Ahnung wie die ganzen WireShark Infos zu deuten sind, gibt es da spezielle Stellen die ich vergleichen sollte?

Vielen Dank im Voraus

Ein Unterschied gibt es doch.

Der Raspi wechselt ständig den Port, von dem aus er das Packet abschickt. Kann das einen Einfluss haben? Ich hatte angenommen das der Port, von dem es abgeschickt wird, für das Packet egal ist. Richtig oder Falsch?

Richtig, der Absendeport ist egal.
Wenn Du Deinen Sketch direkt ins Forum stellst, werden sich den mehr Leute anschauen, als als Anhang.
Benutze dazu Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *).
Das kannst Du auch noch nachträglich ändern.

Gruß Tommy

Hallo,

ich hab mir jetzt nicht deinen Sketch angesehen, aber eigentlich musst du jetzt durch geschick gesetzte Ausgaben an die Serielle des Nano mit dem Monitor rausbekommen wo es hängt.

Wenn es vorher mit dem PC anstelle des Pi funktioniert hat liegt es eventuell ja auch an dem Pi. Irgendetwas mus ja anders sein. Ich würde die Datenpakete mit dem Heifisch vergleichen. Fehlt ein Endzeichen oder ist anders und der Nano kommt nicht aus dem auslesen raus.

Der Ziel-Port ist natürlich nicht egal, der Quellport schon.

Beim Empfänger ist ein UDP-Socket im Zustand "Listen" und das tut das nur auf einem ganz bestimmten (Ziel-) Port. Ports sind dazu da, die verscheidenen Dienste auf einer Maschine zu unterscheiden.