[SOLVED] System_thread breaks receiving UDP multicast?

Hi everyone,

I’ve been experimenting with the System thread functionality, but have run into an issue.
Since System Threads are a beta feature, I’m guessing that’s a good thing :smile:

It seems enabling the new System Thread prevents multicast UDP messages from being received on the user thread.
I’ve pared my program down to a minimal test program below.
The test program listens to UDP multicast messages on 225.0.0.37:21928 and toggles the D7 LED every time it receives a message.
Without the System Thread, the LED switches as expected every time I send a message.
After enabling the system thread the LED doesn’t toggle any more.
This is on firmware 0.4.9.

I currently send the message from a cobbled-together java program, but intend on using ipMidi in the future, to control the Photon (and an Adafruit LED ring) via MIDI.

Background:
I’ve previously worked with System Modes (semi-automatic and manual), because I won’t always have internet/cloud access where I intend to use these (festival stages, with a wifi router I’ll bring myself).
However, even losing the local wifi connection suspends the user code (and thus my LED animations) while the Photon re-establishes the connection.
The System Thread solves this problem (the animation continues while reconnecting the wifi), but breaks my ability to control it via multicast.
I can’t have my cake and eat it too, it seems :smile:

I’ve searched here on the forums, but all similar issues with UDP multicast are from before the system threads existed.
None of the system thread topics mention UDP multicast, though some have problems with Particle functions/variables it seems
My apologies if I’ve overlooked anything.

Test program:

//SYSTEM_THREAD(ENABLED); // uncommenting this means multicast is never received below

UDP ipMidiUdp;
int ipMidiPort = 21928;
IPAddress ipMidiIp(225,0,0,37);

void setup() {
  pinMode(led1, OUTPUT);
  digitalWrite(led1, HIGH);
  
  ipMidiUdp.begin(ipMidiPort);
  ipMidiUdp.joinMulticast(ipMidiIp);
}

bool toggle = true;

void loop() {
    int packetsize = ipMidiUdp.parsePacket();
    if (packetsize > 0) { // never TRUE with System thread
        toggle = !toggle;
        digitalWrite(D7, toggle ? HIGH : LOW);
    }
}
1 Like

I did not test it, but I think it is very plausible that this should happen. If you enable the system thread, then the setup function will be called before the WiFI is connected. That is documented here:

https://docs.particle.io/reference/firmware/photon/#system-thread

When the system thread is enabled, application execution changes compared to non-threaded execution: setup() is executed immediately regardless of the system mode, which means setup typically executes before the Network or Cloud is connected. Calls to Particle.function(), Particle.variable() and Particle.subscribe() will function as intended whether the cloud is connected or not. Particle.publish() will return false when the cloud is not available and the event will not be published. See waitUntil below for details on waiting for the network or cloud connection.

As such the multicast join (or any other WiFi related functionality) is very likely to not work at that stage.

To solve that, you can use

waitUntil(WiFi.ready);

In your setup call before calling any WiFI related stuff. Or you can do a check for WiFi.ready() before you do the multicast join in the loop() function.

Hope that helps!

Dear Stevie,

That did it!
I feel really dumb now :slight_smile:

Inserting waitUntil(WiFi.ready); just before the multicast join does indeed fix things.
I’ll shuffle my code a little so that the network init is the last part of my setup() code

Thanks for getting me past my mental block!

P.S. I’ve submitted a documentation pull-request that will hopefully make others realise this sooner: