UDP Receive Frequency Limit

Hello all.

I am trying to implement E1.31 control using the Photon. I have everything working fairly well, but I seem to be running into some sort of limit in the number of UDP packets/sec that the Photon can receive.

It seems that I am running into a limit of ~80 UDP packets per second. Or in E1.31 universe terms, ~7 universes. Once i start sending 8 or more universes worth of data, the packets seem to be dropped on the Photon.

I am using XLight/Nutcracker to send out the data. I have confirmed that Xlights is sending out 8+ universes of data if told to do so. You can setup Xlights by adding an E1.31 device and setting the info like this (changing to IP address to be the IP address of your Photon of course):

Once that is setup, you can go the the “Test” tab in Xlights. Select all. Change to RGB. Change to Chase 1/3 to get a good amount of data pumping. Then turn on the data output with the little lightbulb on the far right of the menu bar. Everything works fine with 6-7 universes of data. But once I add 8 or more, the latter universe data packets arrive very sporadically.

I have made a simple app to demonstrate my issue:

An interesting side note, I had this code up on running on a Core a couple months back by manually changing the UDP buffer size before that was natively supported and didn’t seem to have any problems.

Any ideas are greatly appreciated as to why I am hitting this limit.
Thanks!
James

Ping @mdma :smile:

Hi @MrRocketman

It might be interesting to know if you ever get UDP packets that are not the correct E1.31 length. Right now your code just drops those and does not report anything. Given how you are sending, I am not sure how that could happen, but you should double check.

Did your working code on the Core also use UDP.receivePacket(buffer,size) with a private buffer? This bypasses the buffer in the UDP object in favor of your own. I wonder if the lack of packet boundaries on the Core was actually helping you since you always want to read 638 bytes.

Good idea @bko . I just added a check and I’m only seeing valid length packets come through. I updated the gist to reflect this.

No I wasn’t using the UDP.receivePacket() on the core. Just the parsePacket().

Hmm, well interestingly enough it does not seem to be the frequency per se that is causing the problems. My network must have been bogged down because I ran the test again and was only seeing about 50 packets/sec. And it was still dropping the universes 7 and above packets sporadically…

You know UDP is an “unreliable” transport and packet drops are a fact of life. That said, it seems weird that it would drop only higher numbered universes–the dropped packets should be evenly distributed and infrequent on a local network.

Is there a way to look at the statistics of the other end of the connection?

Another thing I would try is calling your udpParse() function more times per loop. It seems like your code is setup for a maximum of 12 “universes” so why not call it 12 times a loop for each loop iteration? Another way to dramaticaly improve the time around the loop() function is to turn the cloud off.

2 Likes

Yes I did use Wireshark to verify that the packets are going out.

I also whipped up a quick iPhone app and sent the data to my iPhone instead. I received every packet.

I tried the theory of calling my udpParse() 12 times per loop and saw no noticeable difference. Also, I have tried manual mode and turning off the cloud connection as soon as i start receiving data. There seems to be a small performance gain. Maybe 10%. But I’m still seeing the packets only being dropped after the 6 universe/packet.

I did find this comment while scouring around: Strange UDP bug And it mentions 7 sockets. Not sure what that means but 7 is the number I’m running into problems with. Is there some inherit limit on the photon that has to do with 7? Just spitballing here.

Thanks,
James

@MrRocketman, unless the wifi readiness code is acting up, only one socket will be open at a time from what I can see. A “socket” is open whenever you do a UDP.begin(IP) and closed whenever you do a close(). You can want to check the readiness code to make sure UDP.begin() doesn’t get called unexpectedly.

Good thought on the wifi readiness code. I check that a didn’t see any issues. I also just tried using waitUntil(WiFi.ready) instead to see if that made a difference and it didn’t.

Here is a sample of the packet results I’m seeing:

pkts:115
pkts/sec:54
u1:19
u2:19
u3:19
u4:19
u5:19
u6:18
u7:0
u8:0
u9:0
u10:0
u11:2

pkts:124
pkts/sec:60
u1:19
u2:19
u3:19
u4:19
u5:19
u6:19
u7:4
u8:3
u9:2
u10:1
u11:0
2 Likes

@MrRocketman did you ever get a functional implementation? I was just going to start hacking on a basic E1.31 client for a photon but I’d love to know if you were ever successful.

@edalquist

It’s been so long I can’t remember all the details. But here’s the GitHub repo https://github.com/MrRocketman/E131PhotonPixel
It was very functional code.

And my website has a few details: http://mrrocketman.com

Also, if I’m remembering correctly, I had to flash it with custom firmware that upped the UDP buffer. Had to dig through the os source to find that.

I’ve since ditched the Photon because it was too unreliable for my needs.

1 Like

I did a quick test of Photon UDP receive performance. Photon was running 0.6.0 and using udp.receivePacket to receive the packets. I would avoid using udp.parse() as the performance isn’t great. Also, system thread was enabled.

Using 64 byte UDP data and sending to the Photon every 5 milliseconds (200 packets per second), all of the packets were received successfully. I ran the test for a several minutes (100000 packets).

Sending to the Photon every 1 millisecond (1000 packets per second) there is some loss, though only around 0.25%.

2 Likes

Awesome, thanks for the updates!