0

I'm using this OSC library and TouchOSC to controls some motors. Right now I'm receiving those two kind of messages:

/u/1       // move motor 1 of default steps
/u/2       // move motor 2 of default steps

/u/1/5     // move motor 1 of 5 steps
/u/3/25    // move motor 1 of 25 steps

and so on.

Right now I have this piece of code:

void loop() {
  OSCMsgReceive();
}

void OSCMsgReceive() {

  OSCMessage msgIN;
  int size;
  if ((size = Udp.parsePacket()) > 0) {
    //Serial.println("incoming message.. ");
    while (size--) {
      byte n = Udp.read();
      msgIN.fill(n);
      Serial.print((char)n);
    }
    Serial.println();
    if (!msgIN.hasError()) {
      msgIN.route("/u", up);
    }
  }
}

void upValueExtraction(char *ca, int &num_motor, int &num_step) {
    String s = String(ca);
    String num_motor_s = "";
    String num_step_s = "-1";
    int n = 0;
    for(int i=0; i<s.length(); i++) {
      char c = s[i];
      if(c=='\\') {
        n++;  
      }
      if(n==0) num_motor_s += c;
      if(n==1) num_step_s += c;
    }
    Serial.print("num motor: "); Serial.println(num_motor_s.toInt());
    Serial.print("num step: "); Serial.println(num_step_s.toInt());

    num_motor = num_motor_s.toInt();
    num_step = num_step_s.toInt();
}


void up(OSCMessage &msg, int addrOffset) {
  static boolean flag = false;
  if (!flag) {
    Serial.print("route: up "); Serial.println(addrOffset);

    char ca[200];
    msg.getAddress(ca, addrOffset+1);

    int num_motor, num_step;
    upValueExtraction(ca, num_motor, num_step);

    if(num_step==-1) {
      num_step = defaul_steps;
    }

    Serial.print("Have to move motor n ");
    Serial.print(num_motor);
    Serial.print(" of step ");
    Serial.println(num_step);
  }
  flag = !flag;
}

Even if it is working and even if I'm using an Arduino DUE (much more memory then the UNO) I think it can be optimised.

Does it contains some leeks? How can I better use the OSC matching part of the library? Any kind of "embedded c++" guidelines? Can I do everything inline without a ca char array and s String variables? Is better to use Arduino Lib String class or plain old C str* functions? Any kind of comment?

Thanks in advance.

1 Answer 1

1

OSC is such a simple format that I ended up ditching libraries entirely, and just parsing the UDP packets directly with a state machine. Just learn the wire format of the bytes and parse the state machine explicitly.

It's just a trivial function calling format. The message starts with a 32-bit padded zero terminated string (important!) for the method name. I am not sure if the type tag is mandatory but it was always being sent (ie: ",iff"), then the binary values corresponding to what type tag says - like bigendian int32,float32,float32.

This was related to OSC generated by ChucK, SuperCollider, and CSound.

Real optimizations would come just from the design of the protocol itself. You will need to assume that any UDP packet can be dropped.

You are sending motor changes as diffs from current position, so you need to handle packet drops somehow. (ie: Do you have a TCP-like mechanism? Do you change the design to send absolute motor positions so that position reports are idempotent and subject to re-broadcast? Do you ack message receipt individually, or do you periodically poll the device for its current state?)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.