Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can only send after message received? #97

Open
pixelpusher opened this issue Dec 20, 2018 · 1 comment
Open

Can only send after message received? #97

pixelpusher opened this issue Dec 20, 2018 · 1 comment

Comments

@pixelpusher
Copy link

pixelpusher commented Dec 20, 2018

Hi, I'm trying to do something simple. I'd like to constantly send OSC messages over serial, and also sometimes receive them. I've found that I can send messages constantly (as fast as possible) as long as I don't also receive them. The Ardruino code below illustrates this problem. It will only send back a response via serial when a response is received via serial, when it should be constantly sending messages:

#include <OSCMessage.h>
#include <OSCBundle.h>
#include <OSCBoards.h>

#ifdef BOARD_HAS_USB_SERIAL
#include <SLIPEncodedUSBSerial.h>
SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB );
#else
#include <SLIPEncodedSerial.h>
SLIPEncodedSerial SLIPSerial(Serial1);
#endif

#define UPDATE_INTERVAL_MSEC 100

int32_t next_time;
uint32_t counter = 0;
boolean LEDState = false; // off

OSCBundle bundleOut;

void setup()
{
  pinMode(13, OUTPUT); // LED

  // begin SLIPSerial just like Serial
  SLIPSerial.begin(115200);
  while (!Serial)
    continue;

  next_time = millis() + UPDATE_INTERVAL_MSEC;
}


void LEDcontrol(OSCMessage &msg)
{
  if (msg.isInt(0))
  {
    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, (msg.getInt(0) > 0) ? HIGH : LOW);
  }
  else if (msg.isString(0))
  {
    int length = msg.getDataLength(0);
    if (length < 5)
    {
      char str[length];
      msg.getString(0, str, length);
      if ((strcmp("on", str) == 0) || (strcmp("On", str) == 0))
      {
        pinMode(LED_BUILTIN, OUTPUT);
        digitalWrite(LED_BUILTIN, HIGH);
      }
      else if ((strcmp("Of", str) == 0) || (strcmp("off", str) == 0))
      {
        pinMode(LED_BUILTIN, OUTPUT);
        digitalWrite(LED_BUILTIN, LOW);
      }
    }
  }
  else {
    LEDState = !LEDState;
    digitalWrite(13, LEDState);
  }
}



void loop()
{
  OSCBundle bundleIN;
  int size;

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

  if (!bundleIN.hasError()) {
    bundleIN.route("/OnMouseDownX", LEDcontrol);
  }
  bundleIN.empty();

  int32_t now = millis();

  if ((int32_t)(next_time - now) <= 0)
  {
    next_time += UPDATE_INTERVAL_MSEC;

    counter = (counter + 1) % 100;

    // the message wants an OSC address as first argument
    bundleOut.add("/CubeX").add((float)counter / 50);
  }

  SLIPSerial.beginPacket();
  bundleOut.send(SLIPSerial);       // send the bytes to the SLIP stream
  SLIPSerial.endPacket();     // mark the end of the OSC Packet
  bundleOut.empty();                // free space occupied by message
}
@pixelpusher
Copy link
Author

I'm stumped on this, so I'm calling it an issue for now - I can't figure out why this is the case, though. I'm trying to read SLIPSerial from across different loops so I can multitask and do other things (like send responses) but altering the simple receive example (which works fine) doesn't work. this produces decoding errors in the OSC bundle and I'm unsure why, since the logic is the same:

/*
* Set the LED according to incoming OSC control
*/
#include <OSCBundle.h>
#include <OSCBoards.h>

#ifdef BOARD_HAS_USB_SERIAL
#include <SLIPEncodedUSBSerial.h>
SLIPEncodedUSBSerial SLIPSerial(thisBoardsSerialUSB);
#else
#include <SLIPEncodedSerial.h>
SLIPEncodedSerial SLIPSerial(Serial1);
#endif

void LEDcontrol(OSCMessage &msg)
{
     if (msg.isInt(0))
     {
          pinMode(LED_BUILTIN, OUTPUT);
          digitalWrite(LED_BUILTIN, (msg.getInt(0) > 0) ? HIGH : LOW);
     }
     else if (msg.isString(0))
     {
          int length = msg.getDataLength(0);
          if (length < 5)
          {
               char str[length];
               msg.getString(0, str, length);
               if ((strcmp("on", str) == 0) || (strcmp("On", str) == 0))
               {
                    pinMode(LED_BUILTIN, OUTPUT);
                    digitalWrite(LED_BUILTIN, HIGH);
               }
               else if ((strcmp("Of", str) == 0) || (strcmp("off", str) == 0))
               {
                    pinMode(LED_BUILTIN, OUTPUT);
                    digitalWrite(LED_BUILTIN, LOW);
               }
          }
     }
}

void setup()
{
     SLIPSerial.begin(38400); // set this as high as you can reliably run on your platform
}

OSCBundle bundleIN;

//reads and dispatches the incoming message
void loop()
{
     int size;

     if (!SLIPSerial.endofPacket())
     {
          if ((size = SLIPSerial.available()) > 0)
          {
               while (size--)
                    bundleIN.fill(SLIPSerial.read());
          }
     }
     else
     {
          if (!bundleIN.hasError())
          {
               bundleIN.dispatch("/m", LEDcontrol);
          }
          bundleIN.empty();
     }
}

@pixelpusher pixelpusher reopened this Dec 21, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant