Receiving changing values from Pure Data to Arduino via OSC

Hi,

I've been taking a look at this osc example which shows how to send on off values from pd to arduino and analog and on off values from arduino to pd. But I'm wondering how I could modify this to receive changing values from a slider in pd to arduino to change the brightness of an led.

For pd I'm using the 'give get osc' example from this chapter 8.GitHub - Apress/arduino-music-audio-projects: Source code for 'Arduino Music and Audio Projects' by Mike Cook

/*
OSC Serial Give & Get - Mike Cook
Sends out OSC messages and receives them
For PD or Max. See the one line in the 
rxMessage() function to change for PD or Max
*/
#include <OSCBundle.h>
#include <OSCBoards.h>
#include <OSCMessage.h>

// I/O pin mapping
byte inPins[] = {12, 10, 8, 6, 4, 2};
byte outPins[] = {13, 11, 9, 7, 5, 3};
byte numberOfPots = 4;

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

void setup() {
  for(int i=0; i<6; i++){
    pinMode(inPins[i], INPUT_PULLUP);
    pinMode(outPins[i], OUTPUT);
    digitalWrite(outPins[i],LOW);
    }
  SLIPSerial.begin(38400);   // set this as high as you can reliably run on your platform
#if ARDUINO >= 100
  while(!Serial)
    ; //Leonardo requirement to establish USB device
#endif
}
   
void loop(){
  // sendAutoMessage(); // simulate analogue signals
  checkAnalogue(); // look at real analog ports
  if(SLIPSerial.available() > 0) rxMessage();
  checkDigital();
  delay(10);
}

void checkDigital(){
  static boolean lastSwitchState [6];
  char messageDigital[] ="/d/3";
  boolean currentSwitchState;
  for(int i = 0; i<6; i++){
     currentSwitchState = digitalRead(inPins[i]);
    if(  currentSwitchState != lastSwitchState[i]){
      lastSwitchState[i] = currentSwitchState;
       messageDigital[3] = char( i | 0x30);
      OSCMessage mssageD(messageDigital);
      mssageD.add((int32_t)currentSwitchState & 1);
      SLIPSerial.beginPacket();  
      mssageD.send(SLIPSerial); // send the bytes to the SLIP stream
      SLIPSerial.endPacket(); // mark the end of the OSC Packet
      mssageD.empty(); // free space occupied by message
    }
  } 
}

void checkAnalogue(){
  static int lastAnalogueValue [6];
  char messageAnalog[] ="/a/5";
  int currentAnalogueReading;
  for(int i=0; i<numberOfPots; i++){
    currentAnalogueReading = analogRead(i);
    if(abs(currentAnalogueReading - lastAnalogueValue[i]) > 2){
      lastAnalogueValue[i] = currentAnalogueReading;
      messageAnalog[3] = char(i + 0x30);
      OSCMessage msg(messageAnalog);
      msg.add((int32_t)currentAnalogueReading);
      // now send the message
      SLIPSerial.beginPacket();  
      msg.send(SLIPSerial); // send the bytes to the SLIP stream
      SLIPSerial.endPacket(); // mark the end of the OSC Packet
      msg.empty(); // free space occupied by message
    }
  }
}

void sendAutoMessage(){
  static int count = 10, ch =0;
  char messageAnalog[] ="/a/5";
  count +=10;
  if(count> 1023) count = 0;
  ch++;
  if(ch>6) ch=0;
  messageAnalog[3] = char(ch + 0x30);
  OSCMessage msg(messageAnalog);
  msg.add((int32_t)count);
  // now send the message
  SLIPSerial.beginPacket();  
  msg.send(SLIPSerial); // send the bytes to the SLIP stream
  SLIPSerial.endPacket(); // mark the end of the OSC Packet
  msg.empty(); // free space occupied by message
  }
  
void rxMessage(){
  // Max uses OSCBundle and PD uses OSCMessage
 OSCMessage messageIN; // uncomment for PD
// OSCBundle messageIN;  // comment out for PD
 int sizeb =0;
 while(!SLIPSerial.endofPacket() ) {
    if( (sizeb =SLIPSerial.available()) > 0)
    { 
       while(sizeb--){
          messageIN.fill(SLIPSerial.read());
       }
     }
  }
   if(!messageIN.hasError()) { // error free
    messageIN.route("/led", LEDcontrol);
    messageIN.dispatch("/w", Awink);
   }
 }

void LEDcontrol(OSCMessage &msg, int matched){
     boolean state = LOW;
     char whatLED[] = {'/','1',0};
      for(int i=0; i<6;i++){
        whatLED[1] = char(i | 0x30);
        if(msg.match(whatLED,matched)){
            state = LOW;
            if(msg.getInt(0) > 0) state = HIGH;
            digitalWrite(outPins[i],state);
        } 
  }
}

}


void Awink(OSCMessage &msg) {
  for(int i=0; i<8; i++){
  wink(300,0);
  }
}

void wink(int del,byte pin){
    digitalWrite(outPins[pin],HIGH);
    delay(del);
    digitalWrite(outPins[pin],LOW);
    delay(del);
}

bumpp

I managed to control one led's value from Pure Data, but am now trying to address multiple. Not quite sure whats wrong/missing. any thoughts?

#include <OSCBundle.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[] = {13, 11, 9, 7, 5, 3};


void setup() { 

  for(int i=0; i<6; i++){
    pinMode(outPins[i], OUTPUT); 
    }

  SLIPSerial.begin(9600);
}

void loop(){
}


void rxMessage(){
  // Max uses OSCBundle and PD uses OSCMessage
 OSCMessage messageIN; // uncomment for PD
// OSCBundle messageIN;  // comment out for PD
 int sizeb =0;
 while(!SLIPSerial.endofPacket() ) {
    if( (sizeb =SLIPSerial.available()) > 0)
    { 
       while(sizeb--){
          messageIN.fill(SLIPSerial.read());
       }
     }
  }
   if(!messageIN.hasError()) { // error free
    messageIN.route("/led", LEDcontrol);
   }
 }

void LEDcontrol(OSCMessage &msg, int matched){
      char whatLED[] = {'/','1',0};
        for(int i=0; i<6;i++){
          whatLED[1] = char(i | 0x30);
        if(msg.match(whatLED,matched)){
          analogWrite(outPins[i], (msg.getInt(0)));}
}
}

anything I could add/fix/clarify to get some advice?

thx!

Hello, I've solved my original problem but have run into a new one. I can only receive single digit osc numbers from pure data (ie. '/led/0' - '/led/9'). So right now I can only control 10 Leds.

I believe it has to do with the first and 3rd lines below.

 char whatLED[] = {'/','1',0};
for(int i=0; i<16;i++){
whatLED[1] = char (i | 0x30);

This part of the code I did not write and as result don't fully understand. Do I need to switch the char to a different data type to be able to recieve double digits numbers or could this be tweaked?

Full code below. Thanks!

#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 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);
            //analogWrite(outPins[i],brightness);  // addressing standard leds w/o tlc
            Tlc.set(outPins[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", routeSystem);
       
    }
}