2

Scenario

I'm writing a code for Nucleo-144 F429ZI. It receives UDP packets (actually OSC bundles) and send back an answer when the command is completed.

Issues

It work fine most of the time. But there are two issues that sometime happen:

  1. a message sent from the board is not received by the PC
  2. the board receives the messages with a very long delay (up to 4 s) and in this situation also a ping shows this delay

What I tried

I changed:

  • board
  • switch
  • cables
  • PC, O.S. and software

The behavior is the same. In the firmware I checked all the return values and no one reports an error. Hence, I assume the messages actually leave the board. But apparently they don't reach the PC. Please note that I'm talking about 1 on 1000+ packets.

It seems (even it is hard to guess) that especially the second issue is more frequent if the PC sends packets to multiple IP. Example:

  1. PC sends packets to 192.168.100.1 only: the second issue happens very rarely (i.e. given 2 packets per seconds, it may took days)
  2. PC sends packets to other 10 boards in the same network: the second issue happens within minutes

When this happens, the only way to recover the correct behavior is to reset the board. Even disconnect and reconnect the Ethernet cable does nothing.

** Code **

I wrote a fake firmware to reproduce the problem (it does nothing but answer after some time). As said, running this code with a single board connected it works fine for a long time. But anyway, you might spot some mistake in the UDP handling:

#include <LwIP.h>
#include <ArduinoQueue.h>
#include <STM32Ethernet.h>
#include <EthernetUdp.h>
#include <OSCMessage.h>
#include <OSCBundle.h>
#include <OSCData.h>

#define UDP_TX_PACKET_MAX_SIZE 1024

EthernetUDP Udp; IPAddress remoteIP; unsigned long oldTick; OSCBundle bundleServo; char answer[128]; int ch; float pos;

int getIndex(OSCMessage &msg, int patternOffset) { char buf[8]; msg.getAddress(buf, patternOffset + 1, 8);

return atoi(buf); }

void servo_fade_handler(OSCMessage &msg, int patternOffset) { ch = getIndex(msg, patternOffset); pos = msg.getFloat(0);
oldTick = millis(); }

void bundle_send(OSCBundle *bundle) { Udp.beginPacket(remoteIP, 8888); bundle->send(Udp); Udp.endPacket(); bundle->empty(); }

void setup() { Serial.begin(115200); delay(1000);

IPAddress localIP = IPAddress(192, 168, 100, 2); IPAddress netmask = IPAddress(255, 255, 0, 0); IPAddress dns = IPAddress(192, 168, 1, 1); IPAddress gateway = IPAddress(192, 168, 1, 1);

Ethernet.begin(localIP, netmask, dns, gateway); Udp.begin(8888); }

void loop() { uint8_t data[UDP_TX_PACKET_MAX_SIZE]; uint16_t size = Udp.parsePacket();

if (size > 0 && size < UDP_TX_PACKET_MAX_SIZE) { Udp.read(data, size); remoteIP = Udp.remoteIP();

OSCBundle bundle;
bundle.fill(data, sizeof(data) - 1);
data[size] = '\0';

if (bundle.getError())
{
  Serial.print(&quot;[OSC] Error: &quot;);
  Serial.println(bundle.getError());
  return;
}

int bundleSize = bundle.size();
for (int i = 0; i &lt; bundleSize; i++)
{
  OSCMessage msg = bundle.getOSCMessage(i);  
  msg.route(&quot;/servo/fade&quot;, servo_fade_handler);
}  

} else Udp.flush();

if ((oldTick > 0) && ((millis() - oldTick) > 500)) { bundleServo.empty(); sprintf(answer, "/servo/fade/2/%u", ch); bundleServo.add(answer).add(pos); bundle_send(&bundleServo); oldTick = 0;
} }

Question

I do know the theory says the UDP protocol is not reliable. But after 15 years of experience I never lost a single packet even in very messy environments with hundreds of devices. Here we're working on a simple LAN: one PC, one switch and less than 10 boards. No Internet connection, no WiFi, no other stuff.

What are the possible causes for the issues? Understood them, I can investigate them one by one

Mark
  • 393
  • 2
  • 14

0 Answers0