OSC between OF and Arduino - Arduino buffering messages

Hello!

I have a good OSC protocol working between OF and Arduino. I’m running into a weird problem though. I think this is on the Arduino side, but I wanted to check if this is something that is known in the OF community.

OF starts by registering the Arduino attached to it, by receiving a message from it that identifies it. OF returns an ACK. The Arduino is receiving this and it’s working as expected. The Arduino then proceeds to check pins for messages to send to OF, and listens for messages from OF (a simple flag that tells the Arduino to blink a light).

Here’s where the problem starts. OF doesn’t receive any messages from the Arduino unless it sends a “blink” message. The Arduino seems to be buffering these, but not sending - for each “blink” that OF sends, it receives one Arduino message back from the buffer. I don’t know what might be stopping the Arduino from sending.

Here’s an abbreviated code sample from the Arduino:

void loop() {
  if (!identified) {
  // This sends an identification message:
    OSCMessage ident("/identification");
    ident.add(deviceId);
    SLIPSerial.beginPacket();
    ident.send(SLIPSerial);
    ident.empty();

    // This waits for a response:    
    OSCBundle incoming;
    int size;
    while (!SLIPSerial.endofPacket())
      if ((size = SLIPSerial.available()) > 0) {
    while (size--)
      incoming.fill(SLIPSerial.read());
    }
    if(!incoming.hasError()) {
        incoming.dispatch("/identificationACK", identificationHandler); // This works, it just toggles an LED if the ack is received, and switches identified to TRUE.
    }

  } else {

    // Read some pins, and if there is a change, send an OSC message:

    OSCMessage ping("/some/data");
    ping.add(0).add(1);

    SLIPSerial.beginPacket();
    ping.send(SLIPSerial);
    SLIPSerial.endPacket();
    ping.empty();

    // Also, be listening for incoming messages:

    OSCBundle comingIn;
    int size;
    while(!SLIPSerial.endofPacket()) 
      if ((size = SLIPSerial.available()) > 0) {
        while(size--)
          comingIn.fill(SLIPSerial.read());
      }

      if (!comingIn.hasError()) {
        comingIn.dispatch("/blink", blinkFunction); // The only messages that are incoming tell the Arduino to blink an LED, which is done in another function
      }
  } 
} 

I tried making the Arduino alternate between reading pins and listening for messages (with a toggle back and forth), but that doesn’t seem to help.

Any idea why the OF message might be clearing the buffer, but the Arduino’s send command doesn’t send when it’s supposed to? Thanks for any insight.

I have solved this and am reporting it here in case anyone else has this problem because I found precious little in online forums.

  1. I would not have been able to solve this unless I had 2-way communication enabled. If I hadn’t been able to see that the Arduino was buffering until it received a message, this problem would have been very hard to solve. Therefore, if you think an Arduino just isn’t sending messages to OF via ofxOSC/ofxOSCuino, get OF to send a message back on key press. It might be that your messages are being sent to the buffer, but not being fired off.

  2. The problem is here:

 while(!SLIPSerial.endofPacket()) 
      if ((size = SLIPSerial.available()) > 0) {
        while(size--)
          comingIn.fill(SLIPSerial.read());
      }

This block means that the thread will not return control until it reads an incoming message; it just hangs until it does. That means the other process is happily sending messages to the buffer, but the messages aren’t sent until this process receives something and breaks out of that while loop.

The solution is this:

if (SLIPSerial.available()) {
  while(!SLIPSerial.endofPacket()) 
        if ((size = SLIPSerial.available()) > 0) {
          while(size--)
            comingIn.fill(SLIPSerial.read());
        }
}

If there’s nothing incoming, the process doesn’t enter the while loop and just wait there; instead, all the messages are fired as they’re buffered instead of sitting there and waiting.

Hope this helps someone else at some point. :slight_smile: