Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 7 of 7

Thread: Receiving double digit numbers from Pure Data to Arduino over OSC

  1. #1
    Junior Member
    Join Date
    Sep 2018
    Posts
    9

    Receiving double digit numbers from Pure Data to Arduino over OSC

    Hi, I'm trying to trying to control an led matrix from pure data over osc. I'm able to control 10 leds (ie.'/led/1' - '/led/9'. However I'm not able to receive osc messages with double digit numbers.

    I believe the problem has to do with the following lines of code which I did not write and as a result don't fully understand. Could someone give me a better understanding of what's going on here so I might be able to adjust the code?
    Code:
    char whatLED[] = {'/','1',0};
          for(int i=0; i<16;i++){
            whatLED[1] = char (i | 0x30);

    Code:
    #include "Tlc5940.h"
    
    #include <OSCBoards.h>
    #include <OSCMessage.h>
    
    #ifdef BOARD_HAS_USB_SERIAL
    #include <SLIPEncodedUSBSerial.h>
    SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB );
    #else
    #include <SLIPEncodedSerial.h>
     SLIPEncodedSerial SLIPSerial(Serial1);
    #endif
    
    
    byte outPins[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};    //for tlc pins
    int brightness;
    int i;
    
    
    void setup() {
        SLIPSerial.begin(9600);   // set this as high as you can reliably run on your platform
        Tlc.init();               
    }
    
    
    void routeSystem(OSCMessage &msg, int matched ){
          char whatLED[] = {'/','1',0};
          for(int i=0; i<16;i++){
            whatLED[1] = char (i | 0x30);
            if(msg.match(whatLED,matched)){
                if(msg.getInt(0));
                int brightness = msg.getInt(0);
                Tlc.set(outPins[i],brightness);    // addressing tlcs
                Tlc.update();
                
            }
        }
    }
    
    //reads and routes the incoming messages
    void loop(){ 
        OSCMessage messageIN;
        int size;
        while(!SLIPSerial.endofPacket())
            if ((size =SLIPSerial.available()) > 0)
            {
               while(size--)
                  messageIN.fill(SLIPSerial.read());
            }
    
        if(!messageIN.hasError())
        {
            messageIN.route("/led", routeSystem);
           
        }
    }

  2. #2
    Senior Member
    Join Date
    Feb 2017
    Posts
    279
    If you do a logical OR (or an addition) of the numbers 0...9 with 0x30, you'll get 0x30, 0x31, .... 0x39. These happen to be the ASCII codes for the characters '0', '1', ....'9'.
    So, the code is building a set of null-terminated c-strings: "/0", "/1", .... "/9".

    It doesn't work when you go beyond 9 because 10 (decimal) + 0x30 = 0x3A which is the ASCII code for the character ":".

  3. #3
    Junior Member
    Join Date
    Sep 2018
    Posts
    9
    Thanks for the response! I understand what you're saying about the character codes, though I feel I'm a bit at a loss about how to proceed.
    Is there a simple way around this? Or is it simply not possible given the format of osc?

    I was able to double up the code as seen below, but this approach is messy and time consuming for number of leds that im working with.

    Code:
    #include "Tlc5940.h"
    
    #include <OSCBoards.h>
    #include <OSCMessage.h>
    
    #ifdef BOARD_HAS_USB_SERIAL
    #include <SLIPEncodedUSBSerial.h>
    SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB );
    #else
    #include <SLIPEncodedSerial.h>
     SLIPEncodedSerial SLIPSerial(Serial1);
    #endif
    
    
    //byte outPins[] = {9,10};      //for analogwrite pins standard leds w/o tlc
    byte outPins1[] = {0,1,2,3,4,5,6,7,8,9};    //for tlc pins
    byte outPins2[] = {10,11,12,13,14,15};    //for tlc pins
    
    int brightness;
    int i;
    
    
    void setup() {
        SLIPSerial.begin(9600);   // set this as high as you can reliably run on your platform
        Tlc.init();               
    }
    
    
    void led1(OSCMessage &msg, int matched ){
          char whatLED[] = {'/','1',0};
          for(int i=0; i<16;i++){
            whatLED[1] = char (i | 0x30);
            if(msg.match(whatLED,matched)){
                if(msg.getInt(0));
                int brightness = msg.getInt(0);
                //analogWrite(outPins[i],brightness);  // addressing standard leds w/o tlc
                Tlc.set(outPins1[i],brightness);    // addressing tlcs
                //Tlc.setAll(4000);                  //address all tlcs with set value of 4000
                Tlc.update();
                
            }
        }
    }
    
    void led2(OSCMessage &msg, int matched ){
          char whatLED[] = {'/','1',0};
          for(int i=0; i<16;i++){
            whatLED[1] = char (i | 0x30);
            if(msg.match(whatLED,matched)){
                if(msg.getInt(0));
                int brightness = msg.getInt(0);
                //analogWrite(outPins[i],brightness);  // addressing standard leds w/o tlc
                Tlc.set(outPins2[i],brightness);    // addressing tlcs
                //Tlc.setAll(4000);                  //address all tlcs with set value of 4000
                Tlc.update();
                
            }
        }
    }
    
    //reads and routes the incoming messages
    void loop(){ 
        OSCMessage messageIN;
        int size;
        while(!SLIPSerial.endofPacket())
            if ((size =SLIPSerial.available()) > 0)
            {
               while(size--)
                  messageIN.fill(SLIPSerial.read());
            }
    
        if(!messageIN.hasError())
        {
            messageIN.route("/led", led1);
            messageIN.route("/led2", led2);
           
        }
    }

  4. #4
    Senior Member
    Join Date
    Feb 2017
    Posts
    279
    Quote Originally Posted by TrueBlue View Post
    Is there a simple way around this? Or is it simply not possible given the format of osc?
    I don't know what "osc" is, what it does, or what it's format is.

  5. #5
    Junior Member
    Join Date
    Sep 2018
    Posts
    9
    Open Sound Control. The format that the messages from Pure Data are being sent and received in.

  6. #6
    Senior Member
    Join Date
    Feb 2017
    Posts
    279
    Sorry, don't know anything about it.

  7. #7
    Senior Member
    Join Date
    Jan 2017
    Location
    Maastricht
    Posts
    157
    I came up with this function for extracting an index from an OSC path:
    Code:
    int getAddresPartAsIndex(char* addres, int position){
      int number=0;   // function will return -1 if the position doesn't exist or doesn't contain an integer
      char* addresRest=addres;
      char* path=strtok_r(addresRest,"/",&addresRest);
      for (int i=1;i<position;i++){
        path=strtok_r(addresRest,"/",&addresRest);
      }
      number=atoi(path);
      return number-1;
    }
    It's essentially a tokenise '/' function to get a specific part in the OSC address
    I use it to get the track or other number from the path like this:
    Code:
        char adresStr[48];    
        msg.getAddress(adresStr);
        int index = getAddresPartAsIndex(adresStr,2);
        if (msg.match("/fxparam/*/name")){
          msg.getString(0,reaper.insertParameter[index].name,NAME_LENGTH); 
          if (index==reaper.selectedParameter) addToQueue(4);
          return;
        }
    Beware that the function returns -1 if the requested message part index does not exist or does not contain an integer.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •