TouchOSC via Ardosc/Bonjour

good info to me, thanks for posting this. It works. Especially once I've remembered to change the ip address in touch os

So here is a little more complete code sample to also get the Bonjour part to work.

//DHCP/Bonjour-based OSC server test code
//for use with IDE 1.0.x
//for use with W5100 or W5200 based ethernet shields

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetBonjour.h>
#include <ArdOSC.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address

//create instances of OSC server and client objects. 
OSCServer server;
OSCClient client;

int serverPort  = 8000; //TouchOSC (incoming port)
int destPort = 9000;    //TouchOSC (outgoing port)
int ledPin =  6;        //pin 13 on Arduino Uno. Pin 6 on a Teensy++2
int flag=0;


void setup(){
  Serial.begin(115200);
  Serial.println("DHCP-Bonjour-based OSC server test 12/28/12");
  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    while(true);
  }
  // print your local IP address:
  Serial.print("Arduino IP address: ");
  for (byte thisByte = 0; thisByte < 4; thisByte++) {
    // print the value of each byte of the IP address:
    Serial.print(Ethernet.localIP()[thisByte], DEC);
    Serial.print("."); 
  }
  Serial.println();
  Serial.println();
  
// Initialize the Bonjour/MDNS library. You can now reach or ping this
// Arduino via the host name "arduino.local", provided that your operating
// system is Bonjour-enabled (such as MacOS X).
// Always call this before any other method!
  
    if (EthernetBonjour.begin("arduino")){
       Serial.println("Setting Bonjour Name successful");
    }
    else{     
      Serial.println("Bonjour Name could not be set");
    }
  
// Now let's register the service we're offering (a web service) via Bonjour!
// To do so, we call the addServiceRecord() method. The first argument is the
// name of our service instance and its type, separated by a dot. In this
// case, the service type is _osc. There are many other service types, use
// google to look up some common ones, but you can also invent your own
// service type, like _mycoolservice - As long as your clients know what to
// look for, you're good to go.
// The second argument is the port on which the service is running. This could be 
// port 80 here, the standard HTTP port.
// The last argument is the protocol type of the service, either TCP or UDP.
// Of course, our OSC service is a UDPservice.
// With the service registered, it will show up in the Bonjour Browser on a Mac or
// in the Connections settings in TouchOSC

  if(
    EthernetBonjour.addServiceRecord("Arduino OSC Server._osc",
    8000,
    MDNSServiceUDP)){
    Serial.println("Bonjour Service Record added successfully");
   }
   else{     
      Serial.println("Bonjour Service could not be added");
   }  
  
  //Start the OSC server
  server.begin(serverPort);
  
  //Add callback functions for TouchOSC control element
  //One callback function is needed for each independent TouchOSC control element.
  server.addCallback("/OnOff/toggle1", &funcOnOff);
  server.addCallback("/Fader/Value", &funcValue);
}

void loop(){
  
// This actually runs the Bonjour module. YOU HAVE TO CALL THIS PERIODICALLY,
// OR NOTHING WILL WORK! Preferably, call it once per loop().
EthernetBonjour.run();

if(server.aviableCheck()>0){
     Serial.println("alive! "); 
    }    
} 


void funcOnOff(OSCMessage *_mes){
  float value = _mes->getArgFloat(0);
  
  //create new osc message
  OSCMessage newMes;
  
  //set destination ip address & port no
  newMes.setAddress(_mes->getIpAddress(),destPort);
  newMes.beginMessage("/OnOff/toggle1");
  
  if(flag==1){
    flag=0;
    Serial.println(value);
    digitalWrite(ledPin, LOW);
  }
  else{
    flag=1;
    Serial.println(value);
    digitalWrite(ledPin, HIGH);
  }
  newMes.addArgFloat(flag);
    
  //send osc message back to controll object in TouchOSC
  //Local feedback is turned off in the TouchOSC interface.
  //The button is turned on in TouchOSC interface whe the conrol receives this message.
  client.send(&newMes);
  
}

void funcValue(OSCMessage *_mes){

  long value = (int) _mes->getArgFloat(0);

  Serial.print("Value = : ");
  Serial.println(value);

   //create new osc message
  OSCMessage newMes;

  //set destination ip address & port no
  newMes.setAddress(_mes->getIpAddress(),destPort);
  newMes.beginMessage("/Fader/Value");
  newMes.addArgFloat(value);

  //send osc message
  client.send(&newMes);
}]//DHCP/Bonjour-based OSC server test code
//for use with IDE 1.0.x
//for use with W5100 or W5200 based ethernet shields

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetBonjour.h>
#include <ArdOSC.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address

//create instances of OSC server and client objects. 
OSCServer server;
OSCClient client;

int serverPort  = 8000; //TouchOSC (incoming port)
int destPort = 9000;    //TouchOSC (outgoing port)
int ledPin =  6;        //pin 13 on Arduino Uno. Pin 6 on a Teensy++2
int flag=0;


void setup(){
  Serial.begin(115200);
  Serial.println("DHCP-Bonjour-based OSC server test 12/28/12");
  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    while(true);
  }
  // print your local IP address:
  Serial.print("Arduino IP address: ");
  for (byte thisByte = 0; thisByte < 4; thisByte++) {
    // print the value of each byte of the IP address:
    Serial.print(Ethernet.localIP()[thisByte], DEC);
    Serial.print("."); 
  }
  Serial.println();
  Serial.println();
  
// Initialize the Bonjour/MDNS library. You can now reach or ping this
// Arduino via the host name "arduino.local", provided that your operating
// system is Bonjour-enabled (such as MacOS X).
// Always call this before any other method!
  
    if (EthernetBonjour.begin("arduino")){
       Serial.println("Setting Bonjour Name successful");
    }
    else{     
      Serial.println("Bonjour Name could not be set");
    }
  
// Now let's register the service we're offering (a web service) via Bonjour!
// To do so, we call the addServiceRecord() method. The first argument is the
// name of our service instance and its type, separated by a dot. In this
// case, the service type is _osc. There are many other service types, use
// google to look up some common ones, but you can also invent your own
// service type, like _mycoolservice - As long as your clients know what to
// look for, you're good to go.
// The second argument is the port on which the service is running. This could be 
// port 80 here, the standard HTTP port.
// The last argument is the protocol type of the service, either TCP or UDP.
// Of course, our OSC service is a UDPservice.
// With the service registered, it will show up in the Bonjour Browser on a Mac or
// in the Connections settings in TouchOSC

  if(
    EthernetBonjour.addServiceRecord("Arduino OSC Server._osc",
    8000,
    MDNSServiceUDP)){
    Serial.println("Bonjour Service Record added successfully");
   }
   else{     
      Serial.println("Bonjour Service could not be added");
   }  
  
  //Start the OSC server
  server.begin(serverPort);
  
  //Add callback functions for TouchOSC control element
  //One callback function is needed for each independent TouchOSC control element.
  server.addCallback("/OnOff/toggle1", &funcOnOff);
  server.addCallback("/Fader/Value", &funcValue);
}

void loop(){
  
// This actually runs the Bonjour module. YOU HAVE TO CALL THIS PERIODICALLY,
// OR NOTHING WILL WORK! Preferably, call it once per loop().
EthernetBonjour.run();

if(server.aviableCheck()>0){
     Serial.println("alive! "); 
    }    
} 


void funcOnOff(OSCMessage *_mes){
  float value = _mes->getArgFloat(0);
  
  //create new osc message
  OSCMessage newMes;
  
  //set destination ip address & port no
  newMes.setAddress(_mes->getIpAddress(),destPort);
  newMes.beginMessage("/OnOff/toggle1");
  
  if(flag==1){
    flag=0;
    Serial.println(value);
    digitalWrite(ledPin, LOW);
  }
  else{
    flag=1;
    Serial.println(value);
    digitalWrite(ledPin, HIGH);
  }
  newMes.addArgFloat(flag);
    
  //send osc message back to controll object in TouchOSC
  //Local feedback is turned off in the TouchOSC interface.
  //The button is turned on in TouchOSC interface whe the conrol receives this message.
  client.send(&newMes);
  
}

void funcValue(OSCMessage *_mes){

  long value = (int) _mes->getArgFloat(0);

  Serial.print("Value = : ");
  Serial.println(value);

   //create new osc message
  OSCMessage newMes;

  //set destination ip address & port no
  newMes.setAddress(_mes->getIpAddress(),destPort);
  newMes.beginMessage("/Fader/Value");
  newMes.addArgFloat(value);

  //send osc message
  client.send(&newMes);
}

EthernetBonjour.zip (35.1 KB)

Arduino_TouchOSC.touchosc (530 Bytes)

W5200 Ethernet Library.zip (10.5 KB)

Unfortunately I had to break this post into two parts as the forum only appears to allow messages up to 9500 characters(?), so here is the second part.

The EthernetBonjour library in it's original form http://gkaindl.com/software/arduino-ethernet was not compatible with the Arduino 1.0.x IDE, so I performed the necessary minor changes to allow using this library in the 1.0.x IDE. I also applied changes to get it to work with Ethernet shields or modules that employ the W5200 chip (vs. the usual W5100) and while it works, the ArdOSC part is laggy and screen feedback in TouchOSC is noticeably slower than with a W5100 based Ethernet shield or the WIZ812MJ Ethernet Module that I am using in conjunction with my Teensy++2 micro controller board. I am not sure where the problem is and may start another thread to get feedback from some more experienced folks.

Attached are the modified EthernetBojour library and rthe TouchOSC layout that the above code example works with.
If one wants to test out these on a W5200 basd Ethernet while or Module I have also attached an updated Ethernet library that I found a reference to here on the forum. The original is hosted on github. I don't have the links to the forum thread or to the github repository handy so I won't post these.
The Ethernet Library files are meant to replace the respective Arduio IDE libraries. To "switch" between which chip to compile for you have to comment/uncomment the "#define W5200" line in W5100.h. Don't forget to restart the IDE :wink:

Hope this is useful for someone. I have used it successfully in my project(s) to remotely control lighting systems trippylighting.com

Hey thanks for posting that code. I'll look into it.

I actually started using the z_osc library as opposed to Ardosc as I couldn't work out how to parse the incoming osc addresses using Ardosc (which I needed to do to use touch osc's multitoggle's).

I am sure this is due to inability on my part as opposed to any problems with the library. In fact I'm not even sure if there is any difference between the libraries!

I've got a basic wifi set up working now. Thanks alot for your help.

I'm wondering at what rate I can pass data to the Arduino via wifi. ie could I stream pixel data to my 20x10 array at >15fps. I never intended to do this before but now I'm wondering if its possible. Obviously it depends in part on the network. I guess OSC isn't necessarily the best way of doing this. In fact it might warrant another thread.....

hi guys, thanks for your wonderful code examples, i m trying to get a connection between open frameworks an an arduino ethernet, i can send data from the open frameworks application and i can receive some data, but not a certain value. Seems like some problems gavspav had too. I think i have some understanding problem of the addCallback function and things related. I'll also post my open frameworks code too, might be useful.

of in header

#define HOST "192.168.178.130" //arduino ip
#define RPORT 12000 //incoming
#define SPORT 10000 //outgoing
#define NUM_MSG_STRINGS 100

in cpp

cout << "listening for osc messages on port " << RPORT << "\n";
	receiver.setup(RPORT); //set up receiver
	sender.setup(HOST, SPORT); //set up sender

of sending function

void oscc::sendMessages(){
	
	ofxOscMessage m;
	m.setAddress("/Eth_ArdOSC/toggle2");
	m.addFloatArg(3.0);
	sender.sendMessage(m);
	}

the arduino code

#include <SPI.h>
#include <Ethernet.h>

#include <ArdOSC.h>

OSCServer server;
OSCClient client;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

int  serverPort=10000; //OF incoming port
int destPort=12000; //OF outcoming port

float wert;
int flag=0;

void setup(){ 

 Serial.begin(115200); 
  Serial.println("DNS and DHCP-based OSC server");
  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    while(true);
  }
  // print your local IP address:
  Serial.print("Arduino IP address: ");
  for (byte thisByte = 0; thisByte < 4; thisByte++) {
    // print the value of each byte of the IP address:
    Serial.print(Ethernet.localIP()[thisByte], DEC);
    Serial.print("."); 
  }
  Serial.println();
  Serial.println();
  
  //start the OSCserver
  server.begin(serverPort);
  
  //add OSC callback function. One function is needed for every TouchOSC interface element that is to send/receive OSC commands.
  server.addCallback("/Eth_ArdOSC/toggle2", &funcOnOff);
}
  
void loop(){
  
if(server.aviableCheck()>0){
     Serial.println("alive! ");
      Serial.println(wert);
    }    
} 


void funcOnOff(OSCMessage *_mes){
  float value = _mes->getArgFloat(0); 
  //create new osc message
  wert=value;
  OSCMessage newMes;
  
  //set destination ip address & port no
  newMes.setAddress(_mes->getIpAddress(),destPort);
  newMes.beginMessage("/Eth_ArdOSC/toggle1");
  
  newMes.addArgFloat(value);
  client.send(&newMes);
}

the serial board output (when starting the sending osc function in of by pressing a key):

?óDNS and DHCP-based OSC server
Arduino IP address: 192.168.178.130.

alive! 
0.00
alive! 
0.00
alive! 
0.00
alive! 
0.00
alive! 
0.00

so it should write 3.00 not 0.00.... :frowning:

I am not sure that is the entire solution to the problem, but I believe that the format of what you want to send in the open frameworks code is:

m.addFloatArg(3.0f);
rather than the

m.addFloatArg(3.0);

The "f" behind the "3.0" designates that it is actually a float value.

Also my gut feeling is that you'd be better off putting the :

Serial.println(wert);

Into the callback function right after you've assigned value to wert.

hey, thanks for your help :slight_smile:
i've changed the entry in OF -> no change, i placed Serial.println(wert) into the funcOnOff function but now there isn't any serial printout besides alive!

void funcOnOff(OSCMessage *_mes){
  float value = _mes->getArgFloat(0); 
  //create new osc message
  wert=value;
  Serial.println(wert);
  OSCMessage newMes;
  
  
  //set destination ip address & port no
  newMes.setAddress(_mes->getIpAddress(),destPort);
  newMes.beginMessage("/Eth_ArdOSC/toggle1");
  
  newMes.addArgFloat(value);
  client.send(&newMes);
}

replace the :

  wert=value;
  Serial.println(wert);

with:

  Serial.print("Value = : ");
  Serial.println(value);

And see what that does. That works in the example code I wrote. It's a bit shooting in the dark, however, if that works you've accomplished 2 things.

  1. You know your openFrameworks code sends a valid float.
  2. You know where the problem is in the Arduino code.

mh, only alive! in serial monitor. Nothing besides that.

i wonder if this has something to do with library problems, i had an ArdOSC library that was written for the Watterod RedFly wifi shield and i reinstalled this one for the Ethernet board to test the connection. mh but I removed the RedFly ArdOSC folder in my library path to avoid trouble... i think it's a very small problem. all the ports and ip settings seem to be okay. frustrating

What Arduino board are you using ?

I am asking because my sample code specifies :

 Serial.begin(115200);

On an Arduino Uno for example that would not work and I'd start with :

 Serial.begin(9600);

And don't forget to change that in the serial monitor as well :wink:

Also, perhaps, if your board has an LED pin you may want to start getting to turn the LED on and off. Then at least you know that you can send an receive a value.

Seems all to be ok, it's an arduino ethernet board i program with an usb2serial light adapter, the proper board is selectet, the baudrates are the same. i just read that the build in led is on pin 9, i'm going to test if i can cahnge something, tried it before with an external led, but no luck.

First, I'm very thankful for your help, great community here.
Second, I solved it :slight_smile: or to be precise someone pointed me to a problem with the ofxOsc library and bundled osc messages, so it was related to Open Frameworks. Here is the link for everyone who runs into the same issues and stumbles over this thread
http://forum.openframeworks.cc/index.php/topic,6563.0.html

so long, nixon

Cool! Thanks for posting the openFrameworks part of it too. It's often ant these software interfaces where one gets stuck.

Or in Obi Wan's words "Be mindful of the Interface Luke'" :grin:

Thanks HeadRoom and crew, this thread really got me unstuck.

I reserved DHCP IP on the router for the Arduino Ethernet Shield so I never have to change OSC settings on the iPad regardless what is connected.

Time to add the DMX shield and see if I can get that going too. I also bought a seeed Studio WiFly. Would like to ditch the router/EtherNet shield if I can.

Gratefully yours,
Carl

Replacing the Ethernet Shield with a WiFi shield will require some adaptions to the ArdOSC library. The ArdOSC library contains a few function calls to the lower level SPI functions of the Ethernet library.

I personally am not working with the ArdOSC library anymore as it is rather dated and not maintained anymore. I have rewritten my code to use the OSC library from CNMAT (Oscuino) GitHub - CNMAT/OSC: OSC: Arduino and Teensy implementation of OSC encoding. It is writen and maintained by the inventors of the OSC protocol and actively maintained.
It uses the "regular" Arduino Ethernet and EthernetUDP libraries and is not directly hardware dependent. However, using hardware that can make direct use of the the Arduino Ethernet libraries is a not to be underestimated advantage to getting things to work very quickly.
For example I use a WIZ820io Ethernet module instead of the Ethernet Shield.

Any change in Ethernet related hardware will require you to change code in the used libraries unless the libraries that come with these shields e.g. the Seedstudio WiFi shield have compatible function calls.

Thanks for replying and I will investigate CNMAT. Feel free to drop out of this thread.

I'm not at the Bonjour stage yet, and not sure why I would need it. If anybody wants to tell me the advantages, I'm listening.

I couldn't find Headroom's TouchOSC template, so I made my own, but Pin 13 LED just blinks on -then- off immediately. My TouchOSC template works, as the call to funcOnOff() is happening and I can see tx/rx LEDs working in TouchOSC on my iPAD.

TouchOSC control is: /Eth_ArdOSC/toggle1

But Pin 13 LED just Blinks ON/OFF when I push the toggle.

My Serial Monitor is funky too (I added some debugs to Headroom's code):

Serial looks like this (I matched the baud rates):

FLAG
0.00
alive!

LAG
1.00
alive!

Here's the code:

#include <SPI.h>
#include <Ethernet.h>
#include <ArdOSC.h>

//byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address

// Me Mal Arduino Ethernet shield MAC address
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xFB, 0xCF };


OSCServer server;
OSCClient client;

int serverPort = 8000; //Touch OSC Port (outgoing)
int destPort = 9000;   //Touch OSC Port (incoming)
int ledPin = 13;       //6 on a Teensy++2
int flag=0;

void setup(){
  Serial.begin(115200); //set your serial monitor's baud rate to 115200 or you won't be able to read the debugs
  Serial.println("DNS and DHCP-based OSC server");
  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    while(true);
  }
  // print your local IP address:
  Serial.print("Arduino IP address: ");
  for (byte thisByte = 0; thisByte < 4; thisByte++) {
    // print the value of each byte of the IP address:
    Serial.print(Ethernet.localIP()[thisByte], DEC);
    Serial.print("."); 
  }
  Serial.println();
  Serial.println();
  
  //start the OSCserver
  server.begin(serverPort);
  
  //add OSC callback function. One function is needed for every TouchOSC interface element that is to send/receive OSC commands.
  server.addCallback("/Eth_ArdOSC/toggle1", &funcOnOff);
}

void loop(){

if(server.aviableCheck()>0){
     Serial.println("alive! ");
    }  
} 

//When the button on the TouchOSC inteface is pressed, a message is sent from the iDevice
//to the Arduino to switch (togle) the LED on the Arduino on/off
//then a messeage is sent bak from the Arduino to the iDevice to toggle the buttom on/off

void funcOnOff(OSCMessage *_mes){
  float value = _mes->getArgFloat(0); //TouchOSC expects float values
  
  //create new osc message
  OSCMessage newMes;
  
  //set destination ip address & port no
  newMes.setAddress(_mes->getIpAddress(),destPort);
  newMes.beginMessage("/Eth_ArdOSC/toggle1");
  
  //added by me Mal 2013-09-21
  Serial.println();
  Serial.println("FLAG" + char(value));
  
  
  if(flag==1){
    flag=0;
    Serial.println(value);
    digitalWrite(ledPin, LOW);
  }
  else{
    flag=1;
    Serial.println(value);
    digitalWrite(ledPin, HIGH);
  }
  newMes.addArgFloat(flag);
  
  //send osc message
  client.send(&newMes);
  
}

You don't NEED Bonjour, but it is cool :wink:

I think I had the problem with the LED just blinking once too when I was figuring things out. IIRC the trick in TouchOSC is to use a toggle button (not a push button) and un-check the "local feedback" check box.

  • When you press the button once an OSC message is sent to the Arduino.
  • Then the LED is turned on.
  • then a message is sent back to the toggle button in TouchOSC to turn it on.

I did get the EtherNet and Conceptinetics DMX shields working with ArdOSC/TouchOSC/iPad.

Support told me Ethernet shield requires pin 2, so, connect middle pin of the Slave jumper on the DMX shield to Arduino Pin 7 and code to: DMX_Master dmx_master ( 100 , 7 );

No PWM gios sacrificed in this experiment.

Thanks again,
Carl

That's very good to hear. Congrats!