PDA

View Full Version : Open Sound Control



PaulStoffregen
02-23-2013, 07:16 PM
I am considering someday (perhaps in the distant future) adding a Teensy 3.0 Tools > USB Type option for OSC. This thread is intended to discuss how USB-based OSC might (eventually) work. If you're interested in OSC on Teensy3, please subscribe to this thread. When/if a test version is ever made, preliminary info or invitations to beta test will be posted here.

First, I must confess I have never really used OSC. Well, there was one project where I used KineticSpace (https://code.google.com/p/kineticspace/) to control a pyrotechnic fire art installation, but I just wrote a program in C that listened for UDP packets (on the same machine, 127.0.0.1) and parsed the text for a couple specific numbers. I've also read about OSC and exchanged several emails with Adrian Freed, but still my knowledge and experience about how people actually use Open Sound Control for real musical projects is rather limited. That's where I really need your input and help.

My thoughts on OSC so far are implementing a limited USB Ethernet interface. Fortunately, OSC uses only UDP protocol, which makes this doable, since all the complexity of TCP isn't needed. Lower level stuff like ARP, ICMP and maybe DHCP are probably needed, adding to the complexity a bit.

How the IP number, netmask & gateway are assigned is a big question. I believe all 3 operating systems will default to looking for a DHCP server, so if the OSC implementation responds to DHCP queries it should be able to set this stuff up, right? If it implements a response-only nameservice, it could give itself a name which could be used, but probably only on that computer.

This actually leads to all sorts of questions.....

Do you see OSC applications on Teensy 3.0 listening for messages, where the sender needs to know the name or IP number of the Teensy 3.0? Would the sender be on the same computer where the USB cable is plugged in, or somewhere else on the network.

Or would you need your OSC project to embed the name or IP number of some other OSC entity. Would it be on the same computer, or would the computer need to route packets to deliver your OSC messages elsewhere?

While a lot of this stuff is normal IP networking setup, I feel it's important to make a system that's easy to use. Sure, it's possible to make things work in lots of ways by manually editing network numbers and routing rules on your computer, but that's a difficult and error-prone process (and the reason protocols like DHCP and DNS exit). I want to consider how this stuff is actually going to work for any USB-ethernet OSC option.

Another question involves maximum packet size? I've looked at a few Arduino OSC implementations which limit the message size to only a couple hundred bytes. Presumably that's enough? There will be some sort of limit, but what is a useful threshold?

I'd also like to hear what sort of things you'd actually do with OSC, which can't be done with MIDI?

And again, I want to mention this is all very early discussion about a feature that might be implemented eventually, but highly unlikely to happen within the next few months.

adrianfreed
03-14-2013, 05:20 PM
Hi, Paul

Adrian here, coinventor of OSC.
We have done and continue to do lots of OSC projects with Teensy.

The best code base is here:
http://cnmat.berkeley.edu/oscuino
Yotam Mann wrote it while he was working with us at CNMAT.
It supports OSC over ethernet if you add the usual extra hardware
and OSC over serial.

OSC is an encoding not a protocol.
Some OSC libraries and apps only support UDP for some reason but from the beginning it has
been run over serial, TCP/IP and UDP. I have tunneled over MIDI too.
oscuino shows you how to separate the encoding from the protocol.

Because some applications only listen for OSC over UDP there is an advantage making the Teensy appear to be a
source and sink of UDP packets.

Here is a use case or two worth looking at:
1) We have been building fabric multitouch with the teensy. With teensy 2.0 we didn't
have the crunch to do the blob detecting on the Teensy side. With Teensy 3.0 we can
but then we would want to encode the blobs with the standard way everyone does multitouch
TUIO which is built on top of OSC. All the TUIO apps (there are dozens of them) are listening for
UDP OSC.
2) Control your favorite music app/sequencer from a control surface you have built with the teensy.
http://createdigitalmusic.com/2010/07/motu-digital-performer-adds-native-opensoundcontrol/
http://www.renoise.com/release-notes/260
This is what people are doing with all the iPhone and Android OSC apps. The programs are all listening for udp.
3) Beyond music: OSC is used for lighting control, robotics and all kind of things. I wish we had called it Open Systems Control.
Here is an example OSC arduino lighting application: http://makesomecode.com/2009/12/30/arduino-osc-iphone-and-dmx/
Most professional computer controlled lighting is done over the ethernet with boxes that break out to DMX. Sometimes they use OSC
encoding other times with protocols like art-net: http://en.wikipedia.org/wiki/Art-Net
My point here is that there are reasons other than just OSC for teensy 3.0 to be able to do TCP/IP. One that comes to mind
immediately is Skype devices. We know the Teensy 3.0 ARM can do the audio I/O for a phone-like device. It can probably run the audio compression/decompression too.


Buffering
Most simple apps can use small OSC packet buffers. There are lots of applications that generate or can listen for huge
OSC buffers. One application we just wrote encodes a bunch of features computed on every part of the body from the Kinect
skeletonization software. That's hundreds of OSC parameters/bundle. Yotam struggled with this with oscuino because embedded
programming often calls for the fixed buffer model which doesn't scale very well to lots of libraries all needing buffers.
oscuino uses the Arduino "style" but I think this will evolve towards the malloc model eventually as the memory on the microcontrollers continues to climb. The tricky thing the library takes care of is checking incoming packets to avoid overrunning the buffer.

msutherl
03-15-2013, 07:38 PM
Do you see OSC applications on Teensy 3.0 listening for messages, where the sender needs to know the name or IP number of the Teensy 3.0? Would the sender be on the same computer where the USB cable is plugged in, or somewhere else on the network.


Hey Paul. I use OSC in just about everything I do for control from lighting, sound, physical actuators, to inter-process communication in software. Without delving too deep into technical details, here's what I would expect from Teensy:

I plug Teensy via USB into a computer

A DHCP handshake happens and both computer and Teensy are assigned an IP in the 10.0.0.x range. Ideally this is predictable, i.e. Teensy always gets 10.0.0.1.
It should be possible to set a manual IP to avoid collisions on a larger network.

I plug Teensy into a router

A DHCP handshake happens and an IP + port is assigned according to the router configuration.

In either case


Everything should be over UDP, simply because UDP is the de facto standard. Most non-technical people, when they say "OSC", imply UDP as the transport protocol.
There is an option to force assign Teensy the router's broadcast IP (i.e. 10.0.0.255, or even automatically like *.*.*.255).
There is a default Teensy port (i.e. 7335). There is an option to set an arbitrary port.
I don't want to run custom PJRC software on my computer. Everything should just work with no extra software required.
Inspection and configuration of Teensy's network/OSC settings should happen over OSC, and you could provide a client to do this, but I should also be able to configure Teensy programmatically from my own software just by sending OSC messages (i.e. /teensy/1/config/ip/set 10.0.0.255, /teensy/1/config/ip/setbroadcast [sets IP to *.*.*.255]).
Each Teensy should come with a unique-ID so that it can be referenced uniquely on then network (i.e. /teensy/frodo/..., /teensy/gandalf/...). The UID's should be human-readable, memorable names and ideally references to films/literature. There should be both a hard-coded UID that always works and a user-configurable UID.


Other nice to have features


The full OSC spec is implemented, including globbing, time-tags (however, you probably need an RTC for this), etc.
Network device-discovery is hard problem without an accepted solution right now, but it would be nice if Teensy could somehow get a list of all devices on the network using zeroconf or whatever. Likewise, it would be nice if it could register itself in existing network discovery systems.


I'm not sure if that's everything, but that's what I can think of for now. Really excited about this!

adrianfreed
04-01-2013, 09:30 PM
Oscuino implements the full encoding spec.
I just sent an alpha version of oscuino for Teensy 3.0 to CNMAT's release process.
Oscuino has to be tested on a rather large number of platform/device combinations so if you need a copy earlier
please e-mail me: adrian@cnmat.berkeley.edu.
Time tags don't need a real-time clock, they need a synchronization protocol between the two parties.
We developed one in 2008 and AVB includes one that is now on all Apple computers. It will take a while before this stuff makes
it into Arduino and Teensyland but we know how to do it and the footprint is small.

adrianfreed
04-17-2013, 03:52 PM
What does the "plug and play" OSC dream require?

There are a few routes to this but a relatively easy path is to implement one of the ethernet-over-USB standards (RNDIS and/or ECM)
in the Teensy. Muiltiplatform support has been challenging in the past (the usual, boring Microsoft vs Apple thing).
This driver may solve the RNDIS problem for OS/X: http://joshuawise.com/horndis
The Teensy code footprint will be small for this and the performance quite good on a Teensy 3.0. You don't even need to provide
all of TCP/IP because OSC commonly uses UDP packets which are easy to assemble for an IP stream.

It's not hard to find people around the net who want this badly, e.g., http://code.google.com/p/hiduino/source/browse/wiki/HiduinoFAQ.wiki?r=82
There are lots of "solutions" involving proxy daemons with node.js to translate between serial/midi etc. and ethernet but we have shown (Andy Schmeder and I) that these introduce latency and latency variation and the number of steps to install these solutions is daunting to many people.

Other routes for "plug and play" are making the Teensy a PPP device (this is what OS/X seems to ask about when you first plug in a Teensy).
It is also possible to make it a SLIP device but enabling SLIP requires some different ifconfig commands on each of the platforms.


Another, related use of Teensy and OSC is for the community of users who want to build the host interactions in their web browser.
Again they rely usually on proxy daemons because of the security sandboxing in the browser. A teensy that can move ethernet over USB would solve this because it could run a simple httpd daemon the browser can talk to. There are cloud based solutions for this but they are only viable for slow datalogging applications.
A lot of people are building powerful sound synthesis and graphics into the browser these days and they want tight interaction with devices.
I also reviewed serial port extensions to web browsers to address this but there is no multiplatform implementation (Microsoft Explorer in the way) yet.

adrianfreed
04-25-2013, 06:25 AM
We put the latest OSCuino beta release code up on http://github.com/CNMAT/OSCuino

While others test and fix this I will be moving from this to the roadmap for the main missing feature in all the Arduino OSC attempts: time tags. The api to set and get them is there but we need two elements in Arduino/Teensy land to implement them: deadline scheduling and time synchronization. The theory and practice of this is decades old but
to pull it of on Arduino will require harmonization of two models of timing represented rather well now on Teensy 3 as the Time library and the IntervalTimer library.
These libraries model time as a "thing calibrated from somewhere else in seconds" and "time that goes by in locally measured intervals" respectively.
One useful step will be to get the UTC seconds stuff in Time fixed to do NTP synchronization using something like "The Kernel Discipline" http://www.ntp.org/ntpfaq/NTP-s-algo-kernel.htm#AEN2169 which brings it to microseconds like the resolution of the Arduino baseline "time flowing with a wrapping phasor" API.
We may publish the code to our version of this sort of discipline developed some years ago for 8-bit microchip controllers (uOSC) to help with this task.
As it turns out UTC is probably the wrong time standard to build these things on because it requires consultation of a table of leapseconds to correctly measure time differences. Most modern timing standards being developed for the "Internet of Things" use PTP as the base format with conversions to UTC mostly for display purposes.

adrianfreed
04-27-2013, 06:02 AM
One of our testers noticed that OSC is faster over USB serial than with Arduino ethernet shields with the Wiznet 5100.
I checked the specs and found that yes indeed that ethernet chip is very slow: http://arduino.cc/forum/index.php?topic=139147.0
For applications like (Teensy -> Rasberry PI, Beaglebone or Teensy->laptop) there is not much benefit over ethernet wiring. With
USB you get reasonable performance and power. This is why we have been doing OSC over SLIP serial-USB for many years instead of UDP OSC.
This situation may change as Arduinos migrate to better ethernet connections or use chips that have integrated Ethernet Macs.

adrianfreed
05-29-2013, 06:53 AM
Our OSC library work is now in the Teensyduino 1.14 release. We focussed on stability in this first release and
we are now working on performance tuning and increasing the number of examples. The good news for this community is
that we are optimizing for Teensy 3.0 and Teensy 2.0 first. I checked in a few improvements today, so if performance is a concern for your application
pick up the regular updates from the github repository: http://github.com/CNMAT/OSC

Headroom
06-11-2013, 05:53 PM
I have just come across OSC and in previous projects I used ArdOSC (UDP only). I use this to communicate with TouckOSC for a remote control solution for my lighting systems (http://trippylighting.com) . Per WiFi usng an WIZ812MJ Ethernet module but I also had it runnig on a WIZ820io.

I order not to really have to configure the network connection I am using the Arduino Bonjour library. The OSC server running on the Teesny++2 is announced on my network and I can simply select it in TouchOSC. while TouchOSC only woks with UDP the Bonjourt part should generally also work with TCP.
Gien that TouchOSC was very recently also released for Androind I am sure it will gain even more popularity.

A such, some TouchOSC examples for the new OSC library would be very nice!

adrianfreed
06-12-2013, 02:28 AM
Thanks for your interest. Yotam Mann is busily working on TouchOSC examples. He just put in some more Processing examples. Keep an eye on the GIT repository in the coming weeks and some TouchOSC examples should appear.

Headroom
06-16-2013, 03:38 AM
Adrian, that is great to hear. I have the WIZ820io working with the Teensy3. So far I can get an Ethernet Address per DHCP and register the OSC service per Bonjour.
The next logical step would be to replace the ArdOSC part of my little app with OSC so the TouchOSC examples will come in handy ;-)

adrianfreed
06-16-2013, 03:54 AM
It's good to hear you got the Wiz820io working. This can be challenging. Do you reset the module with a pin from the Teensy 3.0?

Headroom
06-16-2013, 04:23 AM
Yes, I followed user manitou's (http://forum.pjrc.com/threads/17951-WIZ820io-Ethernet-and-2nd-power-supply-with-teensy-3-0) example an use pin 7. Still it did not work until I connected the PDWN pin on the WIZ820io to GND. This is all still connected on a breadboard so the wiring may also not be the most reliable.
Now that I can see that this will be working I am soon going to lay out a little board similar to the one in the image. This combined a Teensy++2 and a WIZ812MJ. On the left side the WIZ812MJ is connected to a TP-Link WiFi router and to the right side the Teesnsy++2 is connected per I2C and Ethernet cable to one of my LED shields (http://ledshield.wordpress.com). That same set-up in installed in my lighting systems (http://trippylighting.com/2012/10/09/colorful-led-lighting-systems/) just with 4 more LED shields.
I am hoping to recreate the same with a Teensy3 and WIZ820io, however, with much higher performance, perhaps for some music responsiveness and something interactive.
576

adrianfreed
06-16-2013, 04:35 AM
This is exciting work.
Thanks for sharing it. There will be a lot of interest in the combination of Teensy 3 + ethernet + audio.

camille
06-21-2013, 02:15 PM
Hi there,

I'm Camille, author of the Mac application OSCulator (http://www.osculator.net). I've recently received requests from some users that would like to use OSC with Arduino or Teensy boards so I worked on a small application that acts as a router between the serial port and OSC.

The specs are:

- plug and play connection to the serial port via a drop down menu, if connection is lost, then try to reconnect a bit later (e.g. useful when developping with the Arduino IDE).
- plug and play OSC service discovery using DNS-SD (aka Zeroconf).
- a priori not restricted to Arduino, should work with any serial device that encodes OSC with SLIP.

Current limitations:
- no support for manual OSC host and port configuration, but I can add it on request, not a big deal.
- OSC over UDP only, no TCP at the moment.
- currently runs in a window, in the future I would like to see that in the system tray (Windows) or menu (OS X).

Right now, I have a working prototype for Mac that I am porting to Windows (struggling with Windows 8 to install the Teensy drivers!).
I would be happy to share it with those who are interested, please contact me.

Best Regards,
Cam

adrianfreed
06-21-2013, 07:50 PM
Hi Cam,

Thanks for letting us know what you are doing.

Please take a look at things we are checking into the CNMAT/OSC repository during these coming weeks. We are working on building the kind of bridge application you are talking about into the Arduino and Processing IDE's. I suspect that at some point we will want to develop a way for the IDE and applications like yours (or Max/MSP or PD) to coordinate
so that there isn't a fight over the serial port.

camille
06-22-2013, 09:44 PM
Hi Adrian,
Good to read you, thanks for the info!

Headroom
07-14-2013, 04:14 AM
As indicated in a post above I created a board that combines a Teensy3 the WIZ820io, I2C etc. While the main purpose was to be able to directly connect it to one of my LED shields it turned more into a Frankenduino:

675

While I am waiting for the board from OSH Park, it would be nice to have some look at OSC examples for TouchOSC. Any word on a ETA ?

adrianfreed
07-14-2013, 04:25 AM
There should be some examples posted on Tuesday.

Headroom
07-14-2013, 12:04 PM
Great. Thanks!

Headroom
07-25-2013, 03:34 AM
The boards for my Frankenduino and the components will arrive on Monday and I hope to have everything assembled and working not later than by the end of next week. Then I could really use some examples of how TouchOSC would work with the OSC library.
Also there seems to be interest in coming up with a good Benchmark to measure performance. Developing such thing would exceed my abilities at the current time, so I am hoping for some advice, and collaboration and hopefully an interesting learning experience!

What happened to Tuesday ?

adrianfreed
07-27-2013, 07:36 PM
Tuesday? My colleague went on holiday. Oops!
I will see if I can conjure something useful up myself while they are away.

adrianfreed
07-27-2013, 07:43 PM
There are some interesting dedicated hardware devices that support OSC well coming out for those of you who don't want to do
the heavy lifting with Arduino or Teensy, i.e., https://github.com/tkrworks/PICrouter and http://www.x-io.co.uk/products/x-osc/
These will fill some of the gap left by the exit of the best supported OSC device I have seen built so far: http://makezine.com/2009/09/10/review-make-controller-kit-v2/.

There are also some Rasberry PI examples: http://www.astlab.de/rpi/rpi.shtml
I would expect some nice Beagle Bone things soon too.

And a wireless OSC to MIDI box: http://wifimidi.com

Nantonos
07-27-2013, 11:19 PM
I also came across USB Octomod (https://bitbucket.org/pucktronix/usb-octomod/wiki/Home) by Greg Surges, whch is Teensy 2.0-based, MIDI over OSC over USB, 8 channel control voltage (CV) generator for analog modular synthesizers. ThePCB is sold on Tindie (https://www.tindie.com/products/pucktronix/usb-octomod-1/).

adrianfreed
07-27-2013, 11:23 PM
Thanks.
I am curious about that.
PCB is sold out.

Headroom
08-03-2013, 02:44 AM
The Frankie board (http://forum.pjrc.com/threads/23904-teensy3-WIZ820io-adapter-And-then-some?p=33998&viewfull=1#post33998) is ready to play. I2C yet has to be tested but Ethernet is up and running and it takes 3 seconds to register the OSC service on the Network via ZeroConf/ Bonjour.
Looks like I'll have to try my own hand at making this communicate with TouchOSC :p

adrianfreed
08-14-2013, 06:10 PM
There are some interesting dedicated hardware devices that support OSC well coming out for those of you who don't want to do
the heavy lifting with Arduino or Teensy, i.e., https://github.com/tkrworks/PICrouter and http://www.x-io.co.uk/products/x-osc/
And a wireless OSC to MIDI box: http://wifimidi.com

I have been using x-osc for a few weeks and it works very well and has good provision for connection of Teensy - 4 fast serial ports can be enabled and the data merged in and split out of the OSC wireless stream. It uses a Microchip 802.11 module.


I have also been studying small WIFI modules as OSC candidates for connection with Teensy's. One of the more promising ones used in recent designs (e.g. sparkcore), the TI CC3000 has some worrisome problems in the current firmware for UDP and long latencies through their API reported (20mS).
I am curious whether anyone here has had good luck with any of the other modules, (e.g. Red Pine Signals, iWiFi, Digi Wifi XBee, Roving Networks Wifly).

Headroom
08-14-2013, 10:28 PM
The WiFi module on the Arduino Yśn is promising. OTOH you could also go ahead and get a TP-Link Router and hook it to your Favorite Arduino flavor ( I assume Teensy3), which is what I am doing. The WiFi hardware on the Yśn the same as on the TP-link WR703n running an embedded Linux router software.

I have found a TouchOSC example in an older implementation of Yotam's OSC library and think I should be able to get that working on my Teensy3 WIZ820io combo.

adrianfreed
08-14-2013, 10:53 PM
Thanks, I will definitely explore those solutions. My more urgent need is for a small wearable module for dance and body interaction work.

Headroom
08-14-2013, 11:16 PM
I see. Getting something that small and light is a challenge for WiFi. WiFi is also rather power hungry!
Would that have to be WiFi or would Bluetooth 4.0 also be an option ?

adrianfreed
08-14-2013, 11:27 PM
We are building OSC support for TI's SensorTag which is an affordable interesting Bluetooth LE device.
The hardware tends to be underpowered for BLE and over complex for WiFI. Fortunately in the kind of dance I am working on it is hard to perform for more than 20minutes which is feasible with WIFI.

Headroom
08-15-2013, 12:19 AM
We are building OSC support for TI's SensorTag which is an affordable interesting Bluetooth device

I had this (http://www.inmojo.com/store/jeff-rowberg/item/wt12-bluetooth-breakout-board/) in mind when I posted. Seems to have pretty good software support.

The sensor tag would be another nice alternative.

Headroom
08-17-2013, 02:15 PM
Having a problem not receiving, but routing an OSC bundle.

I have not posted the entire code below but only the code in question:


void loop()
{
//Add your repeated code here

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

//read the incoming message
bundleReceive();

}



void bundleReceive(){
int packetSize;
int numOSCMessages = 9999;
if((packetSize = Udp.parsePacket())>0){
while(packetSize--)
bundleIN.fill(Udp.read());
if(!bundleIN.hasError()){
Serial.print("Received Bundle with ");
numOSCMessages = bundleIN.size();
Serial.print(numOSCMessages);
Serial.println(" messages");
bundleIN.route("/TriClops/toggle1", handleAnalog);
bundleIN.empty();
}
}
}


void handleAnalog(OSCMessage &msg, int addrOffset){
Serial.println("Received Bundle : ");
}


The serial monitor printout :


Connected to /dev/tty.usbmodem1441 at 115200
DHCP-Bonjour-based OSC server test 12/28/12
Reading MAC from hardware...
MAC: 04:E9:E5:00:05:A9
Frankies IP address: 10.0.1.7.

Setting Bonjour Name successful
Bonjour Service Record added successfully
Received Bundle with 0 messages
Received Bundle with 0 messages
Received Bundle with 0 messages
Received Bundle with 0 messages
Received Bundle with 0 messages


So I can receive bundles, but there is no OSC message inside ?
Somehow I believe there is a conceptual error in my thinking as I am sure that TouchOSC is not sending empty packets. That same TouchOSC layout works using ArdOSC in conjunction with a Teesny++2 and WIZ812io. Id greatly appreciate some guidance!

831

Headroom
08-24-2013, 04:39 AM
Problem solved! Touch OSC appears not to send OSC Bundles, but OSC Messages.

I tried to replicate the code I had found in an Arduino sketch example for and earlier version of the OSC library (https://github.com/tambien/oscuino) that was on Github before the library was moved to the current CNMAT Github repository.
In That Example (https://github.com/tambien/oscuino/blob/master/examples/Transmission/touchOSC/oscuinoEthernetTouchOSC/oscuinoEthernetTouchOSC.ino) everything works with OSC bundles and I am assuming the previous library version that Arduino sketch worked with included a detection mechanism for determining whether an OSC message was received (incomingByte is "/") or if a bundle was received (incomingByte is "#"). the current library does not have that mechanism, or if it does , it does not work.

The message never gets decoded as numMessages is set to zero when the object instance is created, but when a message is received it never gets increased by a numMessages++ and OSCBundle::decodeMessage does nothing.


void OSCBundle::decodeMessage(uint8_t incomingByte){
//get the current message
if (numMessages > 0){
OSCMessage * lastMessage = messages[numMessages - 1];
//put the bytes in there
lastMessage->fill(incomingByte);
//if it's all done
if (incomingBufferSize == incomingMessageSize){
//move onto the next message
decodeState = MESSAGE_SIZE;
clearIncomingBuffer();
} else if (incomingBufferSize > incomingMessageSize){
error = INVALID_OSC;
}
}


The following code routes the OSC Message nicely.


void loop()
{
//Add your repeated code here

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

//read the incoming message
bundleReceive();

}

void bundleReceive(){
OSCMessage msgIN;
int size;
if((size = Udp.parsePacket())>0){
while(size--)
msgIN.fill(Udp.read());
if(!msgIN.hasError()){
msgIN.route("/TriClops/toggle1",handleMessage);
}
}
}

void handleMessage(OSCMessage &msg, int addrOffset ){
Serial.println("Message Received");
}

Headroom
08-25-2013, 05:13 PM
Another issue I noticed using the OSC library is that it's allocating memory that does not get released again, depending on where the object instances for OSC bundles, or messages are created.

For example in the code listed in the post above, when the object instance "OSCmessage msgIN;" is created within the function "bundle receive()" everything works as expected as memory is releases when the function ends.

However when I create the instance in the main body before "setup()" and "loop()" it keeps allocating memory and appears not release all of it, even when using msgIN.empty().
After receiving enough OSC messages, or bundles the Teensy3 simply crashes - for lack of better words - indicated by the led turning off and lack of response on the serial side. It has to be powered off and the teensy loader has to be restarted to get it going again.

I used this function in that I found in a thread:


int heapSize(){
return mallinfo().uordblks;
}

and printed out the "heap size" after receiving bundles and messages and emptying them and memory consumption kept increasing with every received message.

I am not sure whether this is intended or not so I would assume it is not!

Yotam
10-30-2013, 04:39 AM
Thanks Headroom for finding that leak.

empty() was in fact not freeing the incomingBuffer which both OSCBundle and OSCMessage fill as the data comes in.

I did some quick testing on a similar setup as you describe and found that the issue was resolved. Please let me know if that change fixed the bug for you.

PaulStoffregen
10-30-2013, 09:10 AM
Is there a newer or better version of the OSC library that I should put into the Teensyduino installer?

Headroom
10-30-2013, 11:38 AM
@Paul,

The OSCuino library is located here on Github (https://github.com/CNMAT/OSC)

That was a super speedy fix. After not receiving any response here on the forum in quite a while I decided to get a little bolder. I found an email address for Yotam on the Internet and decided to approach him directly. I wrote the email yesterday at 8:00PM EST and had a response with the fix in less than 3 hours. Unbelievable!

Thanks to both of you for the help!

Neurogami
03-30-2014, 06:59 AM
This is an extremely interesting thread. I've been using OSC with Renoise and Processing for a while, and the prospect of interacting with Arduino/Teensy hardware is quite appealing.

I'm quite interested in the Internet of Things. Usually when I read of something along these line it ends up being [small-device]-> [hard-wire]->PC-> [cloud] and back again; it's really PC-to-PC communication; the "things" are not the main drivers of messaging and intercommunication.

I'm curious about one Teensy being able to exchange OSC messages with another Teensy anyplace in the world. I realize that there's a good deal of intermediation required, but those middle devices can be mostly dumb message routers (much the way two laptops can communicate over the 'Net).

I thinking of how a device could use OSC to query some server for the OSC address of another device that's registered it's information and (assuming perhaps some means of authentication) move on to direct further OSC messages more or less straight to that other device.

Is something that's already been done or worked on?

I've seen somewhat similar things done using socket.io/websockets and Node.js, but it seems that ends up being too heavyweight to run directly on a small board like the Teensy. The actual messaging protocol is never run on the end device.

This is where I think OSC has the edge. The part I have not seen addressed is general device registration/lookup and wide-area networking (e.g. my phone getting or sending OSC messages from/to my home thermostat when I'm out shopping.)

Headroom
03-30-2014, 02:17 PM
I don't want to dampen your spirits but believe it'd suit you well if you inform yourself a bit more about internet technologies and the purpose of the different TCP/IP protocols.

There are several problems that you would have to overcome when sending OSC through the internet. For one, OSC is based on the UDP protocol. It is a connectionless protocol and UDP packages can get lost as there is no transmission control. In a LAN that's no problem, but on the internet it would definitely be! Of course OSC could theoretically also be transmitted through TCP but it's mainly aimed at speed and real time sound control.

A protocol that does address resolution where a device "queries some server" already exists and is one of the main drivers of the internet called DNS. In order not to just resolve IP addresses but also "resolve" or better detect services ZeroCon/Bonjour and the associated protocols mDNS and DNS-SD were developed. As their name suggests these use the same structure as "regular" DNS. Again, those also work based on UDP.

On a local network it is possible to program several Teensys to register services e.g. an OSC service on the network and discover each others services and exchange OSC messages with each other. Also OSC addresses are very application specific. on a LAN where you program all the devices you have full control over what is exchanged, on the Internet you don't so you need to rely on standard protocols.

I woud disagree that most Internet of things devices are wired through a PC as the mediator. There is a whole host of WiFi and other RF solutions available that talk through a router to the cloud without the help of a PC. E.g. the CC3000 WiFi module from Texas Instruments is a popular choice in the Arduino world. The Arduino Yśn is another popular choice, the SparkCore, the Electric Imp etc...

Neurogami
03-30-2014, 08:49 PM
I don't want to dampen your spirits but believe it'd suit you well if you inform yourself a bit more about internet technologies and the purpose of the different TCP/IP protocols.


Thanks; I'm already informed about Internet technologies and the purpose of the different TCP/IP protocols.



There are several problems that you would have to overcome when sending OSC through the internet. For one, OSC is based on the UDP protocol.


Sort of an odd comment to make in a thread discussing the use of OSC over non-UDP transport. Indeed, that prospect of OSC over serial, etc., is what encouraged me to think of using the OSC format for a more general-purpose IoT medium. As the spec says, "OpenSound Control (OSC) is an open, transport-independent, message-based protocol." So long as each client/server part of a chain understands what transport is in use things should be OK.

A Teensy might do OSC-over-serial to my laptop; the laptop does OSC-over-UDP to some local server; that server does OSC-over-TCP or something to some other server, etc.



It is a connectionless protocol and UDP packages can get lost as there is no transmission control. In a LAN that's no problem, but on the internet it would definitely be! Of course OSC could theoretically also be transmitted through TCP but it's mainly aimed at speed and real time sound control.


OSC may have been intended as a better MIDI, where UDP is an excellent fit, but there's no reason it has to be so, especially if one is OK with some latency. I'm OK if sending an OSC message to turn off lights take s few (or many) seconds. I see no reason I cannot use, say, Websockets to bridge more conventional OSC clients and servers across different networks.



A protocol that does address resolution where a device "queries some server" already exists and is one of the main drivers of the internet called DNS. In order not to just resolve IP addresses but also "resolve" or better detect services ZeroCon/Bonjour and the associated protocols mDNS and DNS-SD were developed. As their name suggests these use the same structure as "regular" DNS. Again, those also work based on UDP.


Some form of ZeroCOnf could be handy, but so too an OSC server that handles registration and queries. USe OSC to register yourself. Use OSC to ask about registered devices. I think it simplifies things for the end-point devices.



On a local network it is possible to program several Teensys to register services e.g. an OSC service on the network and discover each others services and exchange OSC messages with each other. Also OSC addresses are very application specific. on a LAN where you program all the devices you have full control over what is exchanged, on the Internet you don't so you need to rely on standard protocols.


Going over the Internet I would expect to do the same thing as happens with PCs: use routers to connect a LAN to the outside world. I'm curious about doing this with OSC. It's certainly doable; just matter of what's a good way.


I woud disagree that most Internet of things devices are wired through a PC as the mediator. There is a whole host of WiFi and other RF solutions available that talk through a router to the cloud without the help of a PC. E.g. the CC3000 WiFi module from Texas Instruments is a popular choice in the Arduino world. The Arduino Yśn is another popular choice, the SparkCore, the Electric Imp etc...

Things like SparkCore and the Electric Imp, if I understand them, work by requiring a centralized service. The commands exchanged are not interpreted directly by the receiving device.

My interest in using OSC here is so that any device (not just specific hardware from specialized vendors) can operate in terms of a fairly simple set of well-defined standard messaging concepts. OSC fits that description.

When I write the logic on my Teensy I'd prefer it not be coupled to some specific vendor. I don't want the code to be Imp-specific or SparkCore specific. OSC seems like it would provide a good abstraction layer without vendor lock-in.

The technical issue is devising some conventions for device discovery and in bridging local networks across the Internet.

I just don't want to reinvent stuff if I can avoid it, but I think this may be a case where I have to write some code to proof some concepts.

Headroom
03-30-2014, 11:24 PM
My comment on OSC being based on UDP stems not from the theoretical spec, but from the actual implementation in OSCuino (http://cnmat.berkeley.edu/oscuino). OSCuino can "Send and receive messages over any transport layer that implements the Arduino’s Stream Class such as Serial, EthernetUdp, and more." the "and more" as far as I am aware has not yet happened. Of course there is really no reason this couldn't also work over, say TCP and my own creations would be fine with some latency. It just is not yet implemented in OSCuino. In fact, I believe most actual non-cable implementations use OSC over UDP.

You mentioned the desire for a wireless connection directly through a router without the involvement of a cable to a PC. The Arduino Yśn or a CC3000 connected per SPI to a Teensy allow you to connect directly to a router using TCP/IP without being tied to a specific vendor. In my own creations I use a Teensy connected per SPI to a WIZ820io that is cabled to a little WiFi pocket router. There is also no dependence on a specific vendor. I also use Bonjour to register an OSC service that then is discovered by TouchOSC.

What I was trying to say is that the service registration part including on WAN is already invented with mDNS and DNS-SD. A DNS server infrastructure already exists and would not have to be re-invented. If you want to do this with OSC I'd still encourage youth read Zero Configuration Networking: The Definitive Guide as it also generaly explains the technical problems that have to be solved. Whether you use ZeroConf or try to implement your own ideas, the problems would be very similar.

Electrumpetplayer
04-18-2014, 06:08 PM
Dear all,

Since all my favorite people are linked to this thread it seems to be the best place to add my question and it seems related to the topic. (Hi, Adrian, Yotam, Paul and Headroom)

With help from Headroom I have a good connection between my teensy 3.1 the WIZ820io and my MAC.

The only thing is that I cannot plug and play at the moment since broadcasting on my teensy does not seem to work. In practice this means that when I want to connect my teensy WIZ combination I first have to make a local Network (but I have to do that anyway so no problem there) but then I have to manually set my wifi address to the address that the teensy is using in the sketch. The broadcast address (in my case 169.254.255.255) does not work.

Thanks in advance,

Hans Leeuw.



In answer to the original question in this topic from Paul: I am happy with the ethernet shield solution. But if there would be a USB implementation I would support the first four remarks by msutherl.


My current code with the broadcast address (connecting three XBEE incoming streams to one stream over ethernet):



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

EthernetUDP Udp;

//the Arduino's IP
IPAddress ip(192, 168, 2, 4);
//destination IP
IPAddress outIp(169, 254, 255, 255);
const unsigned int outPort = 9999;

byte mac[] = {
0x04, 0xE9, 0xE5, 0x00, 0x63, 0x54 }; // This is the current teensy's MAC address and can be found with the teensyMAC sketch.

int32_t XBEE1[12] = { 1, 2, 3, 4, 5, 6 };
int32_t XBEE2[12] = { 1, 2, 3, 4, 5, 6 };
int32_t XBEE3[12] = { 1, 2, 3, 4, 5, 6 };
byte checkArray1[] = {
126, 0, 20, 131, 0, 1, 0, 0, 1, 126, 0 };
byte checkArray2[] = {
126, 0, 20, 131, 0, 2, 0, 0, 1, 126, 0 };
byte checkArray3[] = {
126, 0, 20, 131, 0, 3, 0, 0, 1, 126, 0 };
byte bytenr1 = 0;
byte bytenr2 = 0;
byte bytenr3 = 0;
int32_t incomingByte1;
int32_t incomingByte2;
int32_t incomingByte3;
int32_t value1;
int32_t value2;
int32_t value3;
OSCMessage msg1("/XBEE1/");
OSCMessage msg2("/XBEE2/");
OSCMessage msg3("/XBEE3/");

void setup() {
Serial1.begin(115200);
Serial2.begin(115200);
Serial3.begin(115200);
Ethernet.begin(mac,ip);
Udp.begin(8888);
}

void loop() {

if (Serial1.available() > 0) {
incomingByte1 = Serial1.read();
if (bytenr1 < 11) {
if (incomingByte1 == checkArray1 [bytenr1] || bytenr1 == 6){
bytenr1 += 1;
}
else {
bytenr1 = 0;
}
}
else {
if (bytenr1 < 19) {
bytenr1 += 1;
}
else {
if (bytenr1 < 23) {
if (bytenr1 % 2) {
value1 = incomingByte1 << 8;
bytenr1 += 1;
}
else {
value1 = value1 + incomingByte1;
msg1.add(value1);
bytenr1 += 1;
}
}
if (bytenr1 == 23) {
Udp.beginPacket(outIp, outPort);
msg1.send(Udp); // send the bytes to the SLIP stream
Udp.endPacket(); // mark the end of the OSC Packet
msg1.empty(); // free space occupied by message
bytenr1 = 0;
}
}
}
}

if (Serial2.available() > 0) {
incomingByte2 = Serial2.read();
if (bytenr2 < 11) {
if (incomingByte2 == checkArray2 [bytenr2] || bytenr2 == 6){
bytenr2 += 1;
}
else {
bytenr2 = 0;
}
}
else {
if (bytenr2 < 23) {
if (bytenr2 % 2) {
value2 = incomingByte2 << 8;
bytenr2 += 1;
}
else {
value2 = value2 + incomingByte2;
msg2.add(value2);
bytenr2 += 1;
}
}
if (bytenr2 == 23) {
Udp.beginPacket(outIp, outPort);
msg2.send(Udp); // send the bytes to the SLIP stream
Udp.endPacket(); // mark the end of the OSC Packet
msg2.empty(); // free space occupied by message
bytenr2 = 0;
}
}
}


if (Serial3.available() > 0) {
incomingByte3 = Serial3.read();
if (bytenr3 < 11) {
if (incomingByte3 == checkArray3 [bytenr3] || bytenr3 == 6){
bytenr3 += 1;
}
else {
bytenr3 = 0;
}
}
else {
if (bytenr3 < 23) {
if (bytenr3 % 2) {
value3 = incomingByte3 << 8;
bytenr3 += 1;
}
else {
value3 = value3 + incomingByte3;
msg3.add(value3);
bytenr3 += 1;
}
}
if (bytenr3 == 23) {
Udp.beginPacket(outIp, outPort);
msg3.send(Udp); // send the bytes to the SLIP stream
Udp.endPacket(); // mark the end of the OSC Packet
msg3.empty(); // free space occupied by message
bytenr3 = 0;
}
}
}

}

Headroom
04-18-2014, 08:58 PM
What exactly do yo mean with "Broadcasting" ?

Usually when connecting a device per Ethernet to a network I would assume it will connect a router either per cable or per WiFi .

The Router, if configured to do so, will assign an IP address to your Teensy per DHCP.
Each Teensy 3.x has its own mac address burned in. As you have commented in your sketch, this can be read out and used as the Ethernet mac.
With the Ethernet Bonjour library (http://forum.pjrc.com/threads/24481-ZeroConf-Bonjour-Library?p=45483&viewfull=1#post45483) you can then register an _osc._udp service. This works particularly flawlessly on MAC OSX as Bonjour/ZeroConf is part of the operating system. However it can be installed on Linux (Avahi) or Windows as well.
Once you have registered the OSC service, other software, either running on a computer or other devices (teensy for example) can discover the service and use it. I use this scheme to control devices through TouchOSC on an iPhone and iPad.
The EthernetBonjour library also enables the Teensy to discover a service running on other devices.


Service registration and discovery per Bonjour/ZeroConf should allow you to have that Plug-and-Play experience.

A slightly different approach is employed by the monome devices (http://monome.org). These also work with the OSC protocol through USB. They require to run a little server software called serialosc (http://monome.org/docs/app:serialosc). Seril OSC detects when a monome device is plugged into a USB port. Once it has detected the device it will register a _monome._udp service per Bonjour. this _monome service is basically a OSC service. I believe serialosc is open source software. I am not exactly by what mechanism it detects the device but I believe the Arduinome has solved that problem. Needs a little gouging and instigation.

Still hoping that my multicast mods (http://forum.pjrc.com/threads/25561-Proposal-for-additions-to-Ethernet-EthernetUDP-library?highlight=bonjour) to the Ethernet library will make it into the next Teensyduino release! Paul ?

Electrumpetplayer
04-18-2014, 10:55 PM
Dear Headroom,

First of all thanks for answering my question and quick as always. I don't think that my question was completely clear to you though so I'll try to explain a little bit more.

Broadcasting means that you do not send your data to a specific network address but that you send it to all the computers on the network. This depends on the network mask. If your network mask is 0.0.255.255 it means that you should be able to broadcast to all computers on the network using the ip address *.*.255.255 (*.* mostly stays the same and says something about the type of network. In my case *.* = 169.254 is typically assigned on MAC computers when they can't reach the wifi_router (which is exactly what I want)). So if I tell my teensy to send to 169.254.255.255 I tell the teensy to broadcast on the network when it is in local mode. It should not matter then what the exact address of my WIFI adhoc network or my ethernet connection is (they will both have a 169.254.*.* address and both receive the data).
There are a number of articles on the internet describing pro's and con's of multicast vs broadcast if you google for it. The reason I want to use broadcast is because it is more simple and I did not know about multicast until you mentioned it anyway. I do not really understand how it works either. I'd like to understand before using.... Would it work on a local network and not interfere with my shared desktop program? And how much time do I need to understand and implement it?

I am not using a router in my set up. I don't need one. I am using another mode on the mac which enables the mac to make a so called 'local network'. The MAC then operates as sort of a router in itself but there is no connection to the internet. You can then use this local network to connect diverse devices to it also over WIFI. (if you have a MAC you'll find it under your wifi symbol in the menu bar).
As explained earlier my setup does work so I am not to happy to change it and loose precious time again figuring out a different scheme..... The OSC examples provided by CNMAT use just normal networking and not bonjour so if I can get them to broadcast I am happy. And for now I can still do the extra steps (no plug and play) when I perform. It works.... Besides that I use my local network for example to connect my iphone to the macbook. I can then use a desktop sharing program to look at my computer screen. I don't have to rely on any network that is not mine in this way!!!

About the bullets:
The IP address of my teensy is assigned. In my case that is always the same. That problem has been overcome.
No problems with my MAC address either.
As said I am a bit hesitant towards the bonjour library if someone else can help me with the broadcasting. I forgot to mention that I see my data packages coming in through the ethernet port with the destination address 169.254.255.255 (checking this with CocoaPacketAnalyzer).
Does that service create extra latency as far as you know? As you describe I understand that there is a service running on the MAC that is forwarding the OSC packages to the program?
I am only interested in sending data from the teensy not in receiving...

I am happy to finally be away from serial for my DATA. I'd like to keep it that way...

Best, Hans.

Headroom
04-19-2014, 12:30 AM
I was aware what Broadcasting means in terms of TCP/IP networking :cool:

It is simply not clear what the overall purpose of your application is as you only explain a problem without the overall context of what you are actually trying to accomplish.
For example what are you doing with the OSC messages that you are sending. What software is processing these OSC messages and what is it doing with them ?

This will make it a lot easier to determine what could be done to make thins more plug-&-play. In general broadcasting on the network in order to avoid having to configure things is a brute force method and I would not recommend it. I think Bonjour could really help you, pending an explanation what you are actually trying to do.

For example let's assume you don't want to use an IP address hard coded in your teensy sketch. You would prefer DHCP but then you don't have any guarantee what IP address will be assigned to the Teensy and you don't want to configure the other devices or software your Teensy connects to. So you want to be able to ping your teensy not with an IP address but for example with ping teensy.local and you want that teensy.local to be resolved into the actual IP address automatically without you having to know what it is. Thats the most basic thing Bonjour does - Link Local Address resolution.

Bonjour uses UDP as its underlying protocol just like OSC. Instead of sending only OSC messages per UDP you'd be sending a few mDNS messages.

Electrumpetplayer
04-21-2014, 04:22 PM
Dear Headroom,

I send sensor data from the teensy to MAXMSP. about 500 messages per second and a payload of 24 bytes per message. It is control data to control sound processing with hopefully very low latency on the control data. Prior bad experience with serial data and diverse serial objects in MAXMSP led me to try out ethernet with OSC and thus far the experience is positive (better and more stable performance). Reading (NIME) articles from both CNMAT and IRCAM convinced me to take this route.

How would hard coding my IP address help me in setting up the connection? It is the ip-address of my local network that keeps changing. Unless there is a method to connect to it through a name (like I do with my mobile phone when I connect to my local network) but I guess that is what bonjour can do?

My application is a musical instrument. i have to set up a lot of things prior to my performance so cutting down on these tasks will create rest and concentration. That is why I would like plug and play instead of having to set up IP addresses each time. But time in general is limited as well. In my experience implementing a new protocol can sometimes take me a week when things are not straightforward so that is why I am not to eager to try your solution unless the implementation is straightforward.

But I am willing to give it a try anyway. I suppose I have to install the Ethernet118bonjour library in my arduino library instead of the normal ethernet library. Is there an example patch on how to use bonjour?

My latency question is related to the fact that the application is a musical instrument (www.electrumpet.nl) but I guess that is not influenced if bonjour only helps in setting up the right ip-connection.

Thanks for thinking along.

Best, Hans.

Headroom
04-21-2014, 05:33 PM
I guess my explanation was a little convoluted ;-) You don't want to have to configure the IP address on your Teesny every time you connect it to your computer. Lets see how I imagine for this to work:

1. You connect your device to the computer. I am not exactly sure how that is done. Based on your description you are not using Internet Sharing but "create a new Network" and then connect to that. I am not at my home computer right now but will try test either tonight or tomorrow how that works.

2. The Teensy requests an IP address from the computer per DHCP and the computer picks one from the pool of available adresses and assigns it to the Teensy.

3. The Teesny registers an _osc._udp service per Bonjour. This registration will also include a name "e.g. "etrumpet.local" to the IP address the Teensy received from the DHCP server. When this step is completed you can open the "ping" command in a terminal window on your mac and ping etrumpet.local instead of having to know the IP address of the Teensy. The service registration will also include on what port this service is registert and whether it is a UPD or TCP service.
Beeing able to resolve etrumpet.local into an actual IP address actually may already all you need to do as you are in full control of the UDP ports on the Teesny as well as on the MaxMSP side.

4. You start your Max MSP application which will browse the available services for _osc._udp and will be able to show available services you can then select from. There is a MaxMSP plugin available that will do this for you http://maxobjects.com/?v=objects&id_objet=3975&requested=osc&operateur=AND&id_plateforme=0&id_format=0
But, again as you are in full control of the port assignements you may not need the plugin.

That's it. The only "action you wuill have to perform is to connect the etrumpet-teesny to the computer. The rest is automatic!

I really would love to help you getting this to work. Your use case is a picturebook example of what can be done with OSC and Bonjour and you are using a very popular software in MaxMSP. I'd love to write an article of how to get this to work for my trippylighting.com blog.

I personally use OSC and Bonjour in a very similarly fashion to control my LED lighting systems. The Teensy in my LED system signs on to the router my home computes and iDevices connect to. Then it registers an OSC service per Bonjour, which in turn is picked up by TouchOSC on my iPhone or iPad and I can remotely controll my creations without having to configure an IP address or port or have to think about what protocol is in involved.

Electrumpetplayer
04-21-2014, 06:17 PM
In answering

1. I have internet sharing on but probably I don't have to. Did not try without yet.

2. Yes. In my case that is always 192.168.2.4 so no worries there.

3. This is the step I don't understand.
The Teesny registers an _osc._udp service per Bonjour. Is there any code involved or does this work automatically when including the ethernet library in my sketch?
Then the second step:
This registration will also include a name "e.g. "etrumpet.local" to the IP address the Teensy received from the DHCP server. Where do I set this name? Is that in the software as well?
The rest is clear.

4. Ok. If I listen on the correct port and the teensy is connected to the local network and sends data to the IP address of that local network than I should see the data coming in in MAXMSP. The object for that is UDPreceive (formerly developed by CNMAT and now part of MAXMSP) which listens on the specified port address of the network that the computer is part of. (I am not totally clear where MAXMSP is listening exactly I must be honest)

Thanks for all your time again.

Best, Hans.

Headroom
04-22-2014, 02:26 AM
@ElectrumpetPlayer
Our exchange strays from the actual topic of this Tread. While OSC and Bonjour very nicely complement each other IMHO, I suggest that we move this over to the ZeroConf / Bonjour Library thread.
Yes, you need the EthernetBonjour library. This does not Replace the EtherntUDP library but rather inherits and uses it's methods. So both are needed.

JulienB
05-19-2014, 07:12 PM
Hi,

I am encountering some speed problem with OSCBundle sent through SLIPserial. It seems to be quite slow and I would like to know if I am doing something wrong with my code?

Here's a simple speedtest I have made to measure the time taken to build and send OSCBundles.



#include <OSCBundle.h>
#include <OSCTiming.h>


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

// Global variables
uint16_t timetagSent;
long timestamp;

void setup()
{

//begin SLIPSerial just like Serial
SLIPSerial.begin(38400); // set this as high as you can reliably run on your platform
Serial.begin(38400);
#if ARDUINO >= 100
while(!Serial)
; // Leonardo bug
#endif
}

void loop()
{
OSCBundle bndl;
// Prepare the OSC Bundle
timestamp = micros();
bndl.add("/i").add((int16_t) 1).add((int16_t)1).add((int16_t)1).add((int16_t)1) ;
timetagSent = micros() - timestamp;
Serial.print("Add a long OSC Message: ");
Serial.println(timetagSent);
timestamp = micros();
bndl.add("/f").add((int16_t) 1);
timetagSent = micros() - timestamp;
Serial.print("Add a simple OSC Message: ");
Serial.println(timetagSent);
Serial.println("");
Serial.println("");
timestamp = micros();

// Send the OSC Bundle through the Serial Port
SLIPSerial.beginPacket();
bndl.send(SLIPSerial); // send the bytes to the SLIP stream
SLIPSerial.endPacket(); // mark the end of the OSC Packet
bndl.empty(); // empty the bundle to free room for a new one
timetagSent = micros() - timestamp;
Serial.println("");
Serial.println("");
Serial.print("Send the bundle through SLIPserial: ");
Serial.println(timetagSent);
}


Here's the timing measured:


Sending an OSC Bundle with 5 items : 216 µs
Adding 4 items in the same OSC Message : 41 µs
Adding 1 OSC Message : 18 µs


As you can see, building an OSCBundle takes time, but sending through SLIPserial is very long too.

Thank you for your help !

Headroom
05-23-2014, 02:42 AM
Opening SLIPSerial and Serial at the same time does not work for me.

However, I have been curious as to what the Ethernet performance would be using a WIZ820io. I have not broken it out to creating a bundle, sending a bundle etc. but one complete loop takes 860micro seconds so it is about three times slower than using the USBSerial with the numbers you are reporting (275us).

Neurogami
06-30-2014, 02:04 AM
I picked up a WiFly RN XV a few weeks ago and got it working with a Teensy 3.1. I modded some code for the RNXV that I first came across at http://jamesgregson.blogspot.com/2013/03/setting-up-wifly-rn-xv-with-teensy-30.html. My version is here: https://gist.github.com/Neurogami/dcc819b64c88f22b008d

I first copied that initial example and hand-rolled the OSC. and that worked well enough as to demonstrate sending OSC over the WiFly.

I then grabbed the CNMAT OSC library to handle parsing, routing, constructing, and sending OSC messages.

The only OSC library file i pulled in was OSCMessage.h


#include <OSCMessage.h>

and I was able to accept, processes, and send back OSC. Pretty sweet.


You can see how I'm connecting to the WiFLy using the TX3 and RX3 , and using parts of the OSC library, here:

https://gist.github.com/Neurogami/08d7c876e35cc3359b42#file-oscteensylibexample-ino


My next step was to also have the Teensy emit MIDI over USB. This is where I ran into a problem.

In the Arduino IDE I need to set the USB type to "MIDI" instead of "serial" in order to get usbMIDI to behave. But the OSC library defines a set of SLIPEncoded* files and these conflict with using the USB port for MIDI.

My workaround has been to just remove all the SLIPEncoded* files from the library. So far that breaks nothing for me.

However, that seems a bit too hackish; one day I may want to actually send OSC over the USB serial port.

Is there some way to block the inclusion of the SLIPEncoded* stuff in a sketch, or otherwise prevent this collision? For example, can I add a #define or something?

The error I get if I have those SLIPEncoded* files in place looks like this:


In file included from /home/james/data/vendor/arduino-1.0.5/libraries/OSC/SLIPEncodedUSBSerial.cpp:1:0:
/home/james/data/vendor/arduino-1.0.5/libraries/OSC/SLIPEncodedUSBSerial.h:44:5: error: 'usb_serial_class' does not name a type


Thanks much for any pointers.

adrianfreed
08-05-2014, 12:00 AM
I got the same error trying to compile our OSC library on 86Duino. I am still tracking it down.
It is on the issue queue for the next release of the library.

adrianfreed
08-05-2014, 04:19 AM
Neurogami,
I checked the fixes to the usb_serial_class problem into the OSC github code base. It will be tested thoroughly in the coming week.

It is good to hear that the OSC library was useful to you. OSC is an encoding designed to be protocol independent and the library reflects that.

Incidentally, just pulling the OSC Message library function means you are not supporting OSC bundles which are a key part of OSC. They allow you to frame values that should be processed concurrently. This results in greater efficiency in many situations because most protocols have an especially efficient packet size, (e.g. 64bytes for USB, around 1000bytes for UDP etc).

Neurogami
08-05-2014, 05:10 AM
Neurogami,
I checked the fixes to the usb_serial_class problem into the OSC github code base. It will be tested thoroughly in the coming week.


Sweet, thanks.



It is good to hear that the OSC library was useful to you. OSC is an encoding designed to be protocol independent and the library reflects that.


Yeah, I'm a big fan of OSC and once I sorted out the serial conflict it was pretty easy to get rolling over the WiFly. Thanks for that.




Incidentally, just pulling the OSC Message library function means you are not supporting OSC bundles which are a key part of OSC. They allow you to frame values that should be processed concurrently. This results in greater efficiency in many situations because most protocols have an especially efficient packet size, (e.g. 64bytes for USB, around 1000bytes for UDP etc).

For this particular case I don't yet have a need for bundles. This started out as a simple piezo-dirven MIDI thing, and as time went by and I thought about how to manage/config the settings the OSC library popped up on my radar.

I had thought about using assorted dials and switches, then considered using SysEx messages to send config details, and settled on making it configurable over UDP OSC.

Of course, now that I have basic OSC handling in place the device can send OSC as well as MIDI in response the piezo pads. I'm trying to reign in the options so I can just get something completed. :)

But I'm excited at the prospect of quirky, hand-held, battery-powered OSC controllers. I'm sure sending/receiving bundles will come into play.

adrianfreed
08-05-2014, 05:33 AM
But I'm excited at the prospect of quirky, hand-held, battery-powered OSC controllers.

Me too. I use x-OSC for these though.
Why? Because they don't have the complex problems the RN-XV has that people are "solving" with various timeouts and delays.
I have looked at the RN-XV command manual carefully and the many threads on this subject (from around 2012) and I don't feel there is a reliable way to use the serial byte stream to do UDP.

Neurogami
08-05-2014, 06:42 AM
Me too. I use x-OSC for these though.


Are you referring to this: http://www.x-io.co.uk/products/x-osc/

£160 (~ $215) is a whole lot of money for wireless. If that price is correct, it seems a bit crazy.

Does it allow for sending arbitrary OSC address patterns and arguments? Does it accept arbitrary OSC address patterns and arguments? (That is, it will send and receive whatever I decide to program for.) The user manual seems to indicate you're stuck with a set of predefined address patterns.




Why? Because they don't have the complex problems the RN-XV has that people are "solving" with various timeouts and delays.


The only issue I have run into is that a straight-up "while(read more UDP bytes)" loop exits after the first byte; I had to add a delay(3) in there.

It's a hack but it works well for me so far and a plugable, multipurpose WiFly for $35 is a easier part for me to manage.

adrianfreed
08-05-2014, 08:06 AM
It has a good IMU, a fast DSP micro controller in it, a web server for configuration and yes, you work with their namespace. x-OSC saves thousands of dollars worth of my time for my employer. The last e-textile project I did took 3 minutes to get from the finished fabric sensor to sound synthesis control. x-OSC can support ad hoc mode so it takes a few seconds to find it on your wifi menu and then it is streaming OSC sensor data. I built an autonomous vehicle with OSC remote control in it in a few hours with IMU, optical sensors, motor speed control etc.
If you want to use Teensy 3.x with it, you can configure up to 4 serial interfaces that it streams over the wifi. I believe the new x-OSC will have the lipo charger too. It is quite hard to engineer all these things well from stacked Arduino thingies.

adrianfreed
08-05-2014, 08:15 AM
Hi,

I am encountering some speed problem with OSCBundle sent through SLIPserial. It seems to be quite slow and I would like to know if I am doing something wrong with my code?


Thanks for the measurements Julien. I am concerned about the interleaved Serial.print's. They are quite slow too. When I measure
performance in these situations I prefer to flip bits on spare digital pins and time with a scope or logic analyzer.

amundsen
08-24-2014, 08:56 PM
Hello,

Has anyone managed to connect a Teensy to Lemur as an OSC device over the camera connection kit?

Headroom
08-24-2014, 09:32 PM
Hello,

Has anyone managed to connect a Teensy to Lemur as an OSC device over the camera connection kit?

To do what ?

nlecaude
08-24-2014, 10:27 PM
amundsen: That's not possible... The CCK doesn't support normal Serial USB, you can only do MIDI when connecting to a Teensy.

amundsen
08-25-2014, 06:07 AM
To do what ?

To connect analog sensors to Lemur, without the 7-bits resolution associated with standard MIDI messages.

I understand only MIDI is possible with such a connection but it's not clear whether Lemur can decode incoming 14-bits ("high res") MIDI control change messages. I'll check on the dedicated forum.

Thank you.

nlecaude
08-25-2014, 01:53 PM
The Lemur app can decode 14 bits midi messages, you can also send any data using sysex messages. This requires scripting on the lemur side however.

Headroom
09-01-2014, 05:26 PM
I've committed a little example Arduino sketch (https://github.com/TrippyLighting/OSCuino_TouchOSC) to my Github account that shows how to exchange messages with TouchOSC using the CNMAT Oscuino libary that ships with Teensyduino.
Tested on an Arduino UNO but should work without modifications on any Teensy

Edit: I've also added a little tutorial to my blog:
http://trippylighting.com/teensy-arduino-ect/touchosc-and-arduino-oscuino/

cedhon
04-26-2019, 12:55 PM
I am considering someday (perhaps in the distant future) adding a Teensy 3.0 Tools > USB Type option for OSC. This thread is intended to discuss how USB-based OSC might (eventually) work. If you're interested in OSC on Teensy3, please subscribe to this thread. When/if a test version is ever made, preliminary info or invitations to beta test will be posted here. (...) My thoughts on OSC so far are implementing a limited USB Ethernet interface. Fortunately, OSC uses only UDP protocol, which makes this doable, since all the complexity of TCP isn't needed.

Dear Paul,
New forum member here, but old Teensy user (about a decade).

It looks like this problem is not solved yet, and after discussing with Adrian Freed, it seems that there is hope.
We're thus harvesting potential sources with a few hackerspace friends, it's documented in this wiki:
https://wiki.fuz.re/doku.php?id=projets:fuz:USB-OSC

Is there anything you started (code, documentation, etc), that you could share so we can contribute or finish it?

Thanks in advance,
Cedric ; )
honnet.eu (http://honnet.eu)

amundsen
05-14-2019, 08:17 PM
Dear Paul,
New forum member here, but old Teensy user (about a decade).

It looks like this problem is not solved yet, and after discussing with Adrian Freed, it seems that there is hope.
We're thus harvesting potential sources with a few hackerspace friends, it's documented in this wiki:
https://wiki.fuz.re/doku.php?id=projets:fuz:USB-OSC

Is there anything you started (code, documentation, etc), that you could share so we can contribute or finish it?

Thanks in advance,
Cedric ; )
honnet.eu (http://honnet.eu)

This would be a great achievement! I am looking forward to this development!

PaulStoffregen
05-14-2019, 08:27 PM
Is there anything you started (code, documentation, etc), that you could share so we can contribute or finish it?


Nope, this was only ever at the initial planning stage.

Ask me again in a couple months. Right now, all dev cycles are going into Teensy 4.0.

amundsen
01-09-2020, 07:54 PM
We're thus harvesting potential sources with a few hackerspace friends, it's documented in this wiki:
https://wiki.fuz.re/doku.php?id=projets:fuz:USB-OSC

Any follow-up or is it dead?

cobtob
06-06-2020, 08:21 PM
Hello everyone.
- sorry to reactivate this old post, but I have a related problem:

Trying to transmit OSC (from Max/MSP) via slip-encoded Serial using CNMAT“s OSC lib. My code runs without problem on Leonardo-based Arduino ProMicro as well as on Teensy2. But it doesn“t really work on Teency LC or 3.2 (don“t have any other Teensy to test): while Integers are received fine, floats don“t get through. Weird.

There are several other posts in these forums with similar issues, but i didn“t find the solution to my problem.
Does anyone have an idea to get this to work?




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

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


float value0 = 0;
int state = 0;

void setup()
{
SLIPSerial.begin(9600); // set this as high as you can reliably run on your platform
pinMode(LED_BUILTIN, OUTPUT);
}


void CV1(OSCMessage &msg)
{
if (msg.isFloat(0))
{
value0 = (msg.getFloat(0) * 2);
state = !state;
digitalWrite(LED_BUILTIN, state);
}

if (msg.isInt(0))
{
value0 = (msg.getInt(0) * 2);
state = !state;
digitalWrite(LED_BUILTIN, state);
}
}


void loop()
{
OSCBundle bundleIN;
int size;

while(!SLIPSerial.endofPacket()) {

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

bundleIN.dispatch("/CV/1", CV1);


bundleIN.add("/CVout/1").add(value0); //echo *2
bundleIN.add("/state").add(state);

SLIPSerial.beginPacket();
bundleIN.send(SLIPSerial);
SLIPSerial.endPacket();
bundleIN.empty();
}

}




/* **maxpatch**
* <pre><code>
----------begin_max5_patcher----------
789.3ocwWs0aaBCF8YxuBjeNKEyc1qUZutIsp8xTUjC3jRGXiL ltzU0+6yWH
ozVfPR8XODh70iOe2N1OsvBrgtGWCr+r8OssrdZgkkpKYGVsss .kn8oEnZ0z
.D7uoatGrTODGumq5tfhxJw001vCCQZJoM7BLWsNXau5t3OVg0 fB.121NTEh
mdWNY2ZFNkqGMLbkyR6jD42HG4WW2UNGWQdlBaw44StcfMmbDU YeOuXg7yxI
RPIKP6vuigUrbB2jjyyOVxHXTj7OO2wnWPuzy8BnmXC1fY8yC2 A4wRavFDY2
37wQ4sfNJGUvntKOm98WG2cFpDywr0XBZSg5X3bAjktJkVVQqw lzu45ocX9d
qBDzMDpHpeGhtkR3aQo5icOwpwfNSrN+OpIBkA.84ja6rF8.Na 8lFRVAdcAl
rieW28+UCmg3H8g091KIFo+b75h7pu98q62V5MVri7mXk2jWhu A0IJpl+n14
BxvaQMEGyu5yrG3qLzQp+B7FsZPjwxW3zc6JN23GYkhwBghzY9 AwGBcdS.TW
p.mkLkAb4hslQEozmI+OYshVCPhtTQ3X9RXhw7kh.3rgp8cY0B fwJsoXcwN0
2H3.73XM7sBwRt.mpFdWjOVHn+5.l1iOnNGkwsSMpPWPj17Dnp alLp212Xd6
QIHxnJBIwSmftFifh3Hwd7hVBqDoNPg+CD2aE8lj3Nz4+YIK5p JT5uru55eb
04dWzuzTT7Mwhw7IYK7UZP5quMjsH1X2Kc1DkGgw5x1iq8ZtD3 gXLlkiJrSs
SBcbNyKxptB+oxlaungm+ocuvS5dUqBTjSd6yrTHK6+0VfZZCK 8vws8kM1uf
cFtlmSP7bJo6bf5I0qQdx.Am.RR03OLRG1jwQxD.ELEfbL.RdN S.oXC.T7Dv
w2Dlt4hPxCKbFhEBloXN4aONcBarl0eLWj+bkF4NW.MESWz6.R WiEUU8.lU2
NaEFB8j6oLYy3kpl4DcS0U..L7C4GluRpDfXB0.tPJngoeW59P sdFnjJd5.o
Ius9tfcBHUZUDwsYpqZetuRRawyK9KPahLG3
-----------end_max5_patcher-----------
</code></pre>
*/


thanks!

cobtob
06-06-2020, 10:43 PM
Hello everyone.
- sorry to reactivate this old post, but I have a related problem:

Trying to transmit OSC (from Max/MSP) via slip-encoded Serial using CNMAT“s OSC lib. My code runs without problem on Leonardo-based Arduino ProMicro as well as on Teensy2. But it doesn“t really work on Teency LC or 3.2 (don“t have any other Teensy to test): while Integers are received fine, floats don“t get through. Weird.

There are several other posts in these forums with similar issues, but i didn“t find the solution to my problem.
Does anyone have an idea to get this to work?




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

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


float value0 = 0;
int state = 0;

void setup()
{
SLIPSerial.begin(9600); // set this as high as you can reliably run on your platform
pinMode(LED_BUILTIN, OUTPUT);
}


void CV1(OSCMessage &msg)
{
if (msg.isFloat(0))
{
value0 = (msg.getFloat(0) * 2);
state = !state;
digitalWrite(LED_BUILTIN, state);
}

if (msg.isInt(0))
{
value0 = (msg.getInt(0) * 2);
state = !state;
digitalWrite(LED_BUILTIN, state);
}
}


void loop()
{
OSCBundle bundleIN;
int size;

while(!SLIPSerial.endofPacket()) {

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

bundleIN.dispatch("/CV/1", CV1);


bundleIN.add("/CVout/1").add(value0); //echo *2
bundleIN.add("/state").add(state);

SLIPSerial.beginPacket();
bundleIN.send(SLIPSerial);
SLIPSerial.endPacket();
bundleIN.empty();
}

}




/* **maxpatch**
* <pre><code>
----------begin_max5_patcher----------
789.3ocwWs0aaBCF8YxuBjeNKEyc1qUZutIsp8xTUjC3jRGXiL ltzU0+6yWH
ozVfPR8XODh70iOe2N1OsvBrgtGWCr+r8OssrdZgkkpKYGVsss .kn8oEnZ0z
.D7uoatGrTODGumq5tfhxJw001vCCQZJoM7BLWsNXau5t3OVg0 fB.121NTEh
mdWNY2ZFNkqGMLbkyR6jD42HG4WW2UNGWQdlBaw44StcfMmbDU YeOuXg7yxI
RPIKP6vuigUrbB2jjyyOVxHXTj7OO2wnWPuzy8BnmXC1fY8yC2 A4wRavFDY2
37wQ4sfNJGUvntKOm98WG2cFpDywr0XBZSg5X3bAjktJkVVQqw lzu45ocX9d
qBDzMDpHpeGhtkR3aQo5icOwpwfNSrN+OpIBkA.84ja6rF8.Na 8lFRVAdcAl
rieW28+UCmg3H8g091KIFo+b75h7pu98q62V5MVri7mXk2jWhu A0IJpl+n14
BxvaQMEGyu5yrG3qLzQp+B7FsZPjwxW3zc6JN23GYkhwBghzY9 AwGBcdS.TW
p.mkLkAb4hslQEozmI+OYshVCPhtTQ3X9RXhw7kh.3rgp8cY0B fwJsoXcwN0
2H3.73XM7sBwRt.mpFdWjOVHn+5.l1iOnNGkwsSMpPWPj17Dnp alLp212Xd6
QIHxnJBIwSmftFifh3Hwd7hVBqDoNPg+CD2aE8lj3Nz4+YIK5p JT5uru55eb
04dWzuzTT7Mwhw7IYK7UZP5quMjsH1X2Kc1DkGgw5x1iq8ZtD3 gXLlkiJrSs
SBcbNyKxptB+oxlaungm+ocuvS5dUqBTjSd6yrTHK6+0VfZZCK 8vws8kM1uf
cFtlmSP7bJo6bf5I0qQdx.Am.RR03OLRG1jwQxD.ELEfbL.RdN S.oXC.T7Dv
w2Dlt4hPxCKbFhEBloXN4aONcBarl0eLWj+bkF4NW.MESWz6.R WiEUU8.lU2
NaEFB8j6oLYy3kpl4DcS0U..L7C4GluRpDfXB0.tPJngoeW59P sdFnjJd5.o
Ius9tfcBHUZUDwsYpqZetuRRawyK9KPahLG3
-----------end_max5_patcher-----------
</code></pre>
*/


thanks!

cobtob
06-06-2020, 10:47 PM
ok, everything is working fine.
the issue was introduced by using CNMAT“s odot-lib in Max, where float type is double by default. pushing everything through o.downcast did the trick.