Need help with OSC?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

538 Stars 115 Forks Other 237 Commits 57 Opened issues


OSC: Arduino and Teensy implementation of OSC encoding

Services available


Need anything else?

Contributors list

OSC for Arduino

This is an Arduino and Teensy library implementation of the OSC (Open Sound Control) encoding.It was developed primarily by Yotam Mann and Adrian Freed at CNMAT where OSC was invented. It benefits from contributions from John MacCallum, Matt Wright, Jeff Lubow and Andy Schmeder and many beta testers.


  • Supports the four basic OSC data types (32-bit integers, 32-bit floats, strings, and blobs - arbitrary length byte sequences)
  • Supports the optional 64-bit timetag data type and Booleans
  • Address pattern matching
  • Dynamic memory allocation
  • Sends and receives OSC packets over transport layers that implements the Arduino Stream Class such as Serial and Ethernet UDP


We recommend Arduino 1.8.5 and a compatible Teensyduino overlay if you use the Teensy. Install using the library manager.

Additional information about installing libraries on Arduino's website.



folder contains examples for Max/MSP and PD and Processing that work with the example sketches. This will be expanded to include other applications like TouchOSC and Processing. For the Max/MSP examples you will need to download the CNMAT max externals package that includes the "o." objects available here.


OSC for Arduino supports creating, sending and receiving OSCMessages individually and wrapped into OSCBundles.

The full API is available here.

Sending Data

Create a new

with an address in the constructor:
OSCMessage msg("/address");

add some data to it:


will infer the type of the data and encode it correctly. The API also supports chaining, so multiple calls to
can be strung together:

Then send it over any transport layer that extends Arduino's Print class like the


Receiving Data

In a typical Serial stream, there is no way to know where one message ends and another begins. That's why we recommend using

(which also comes in the OSC for Arduino Package). Read more about the lightweight SLIP encoding.

To receive an OSCMessage, wait for the end of SLIP Stream, and fill an empty OSCMessage with the available bytes:

//make an empty message to fill with the incoming data
OSCMessage msg;
//wait for the end of the packet to be received
    int size = SLIPSerial.available();
    if (size > 0){
        //fill the msg with all of the available bytes

Now you can query and use the data you received:

//returns true if the data in the first position is an integer
if (msg.isInt(0)){
    //get that integer
    int data = msg.getInt(0);

Routing / Dispatching

OSCMessages can be routed to a specific function by matching their address exactly or with an OSC pattern.

will do a full match on the OSCMessage's address or patterned address.
OSCMessage msg("/a/1");
msg.dispatch("/a/1", dispatchAddress);

And the function definition of

could be as follows:
//called whenever an OSCMessage's address matches "/a/1"
void dispatchAddress(OSCMessage &msg){
    //do something with the OSCMessage...
    if (msg.isFloat(0)){
        float val = msg.getFloat(0);

does the same thing as
but allows for partial address matching as long as they are aligned to a
OSCMessage msg("/b/2");
msg.route("/b", routeAddress);
//called whenever an OSCMessage's address matches "/b"
void routeAddress(OSCMessage &msg, int addressOffset){
    //do something with the OSCMessage...
    if (msg.isBoolean(0)){
        bool val = msg.getBoolean(0);


An OSCBundle is a group of OSCMessage that can be sent and received together.

OSCBundle bundle;
//add a new OSCMessage to the bundle with the address "/a"
OSCMessage msgA = bundle.add("/a");
//add some data to that message
msgA.add("some data");
//append another OSCMessage, this time chaining 'add' calls
bundle.add("/b").add("some more data").add("even more data");

Now send the OSCBundle over SLIPSerial

//start a new SLIP Packet
//send the data
//end the packet

SLIP Serial

The OSC for Arduino library includes extensions of the USB serial and Hardware serial functions of the Arduino core that sends and receives data using the SLIP encoding. This makes Max/MSP and PD integration very simple using CNMAT's The SLIPSerial library implements the same methods as the Serial object with additional

methods to mark the boundaries of each packet in a serial stream.

When sending data, begin each packet with

, then write any data to the SLIPSerial and signify the end of the packet using

On the receiving side, in addition to the normal

methods of the Serial object, SLIPSerial includes
which returns true when the EOT (End Of Transmission) character is received, marking the end of the data packet.


As well as many small examples illustrating the API, there is a larger application called "oscuino" that illustrates how to use OSC to simplify situations Firmata and Maxuino are typically used in.



Arduino 1.8.5

Best Supported Board: ARM boards such M0, Zero, Teensy 3.0 and 3.1 and LC have the performance and memory that afford rich OSC implementations. Our primary test platform for new development is the Teensy 3.x series which currently offers the best performance of any of the Arduinos and variants. We greatly appreciate Paul Stoffregen's ongoing work with "best practice" engineering of high performance micro-controllers.

Unsupported boards

Arduino Yun and related openwrt/arduino hybrids (e.g. Draguino):

Marco Brianza is exploring these interesting approaches to running this OSC library on the Atmel 32u4 in the Yun:

The Yun still lacks the Linux-side support to reliably move data between the 32u4 and the router's cpu. We recommend that you add a Teensy to the USB port of an OpenWrt router to get good performance and reliability with our library.


OSC for Arduino comes with a small suite of tests to validate its functionality and test compatibility when new platforms come out. The tests are broken into a number of individual

files located in the

The tests require ArduinoUnit to be installed in the

folder. The results of the test are printed to the Serial console.

Tested on:

  • Esplora
  • Leonardo
  • Teensy 3.x
  • Mega 2560


Currently best performance is achieved with Arduinos with built-in USB Serial, i.e. Teensy 3.0, Teensy 2.0 and 2.0++ and Leanardo variants (12Mbps max).

This is because the Wiznet 5100 used in the Ethernet Arduino and shields uses really slow SPI (0.3Mbps). This will change as people retool to use the much faster Wiznet 5200 which has been measured with the Due at 6Mbps.

References: * *

The serial examples use a 9600 baud rate which is reliable on most of the FTDI based Arduinos. The slow rate is required for Arduino's without clock chips such as the TinyLili. Once you have established that things work at 9600 baud you will find it very beneficial to increase the rate. e.g.

Serial.begin(345600);   // !! 115200, 230400, 345600,   460800 X

Future development ideas

  • WIFI examples
  • STM32 support
  • Intel Galileo support
  • HiFive Support
  • Photon Support
  • support for special OSC types in CNMAT's "o." especially subbundles
  • examples for recent OSC support in node.js and Node Red
  • nested bundles
  • performance tuning
  • Photon spark core examples
  • Better Time Tags that avoid the overflow limitation of Arduino timer code
  • Time Tag synchronization
  • Bluetooth LE
  • TCP/IP Examples
  • examples for more applications (i.e. TouchOSC, Processing with SLIP)
  • deadline scheduling of OSC 64-bit timetags
  • ADK support

We welcome and appreciate your contributions and feedback.

New in this release

ESPxx, M0, PIC32

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.