Max and CNMAT OSC help please

brendan mccloskey's icon

Hi
I've successfully installed all the required libraries and packages to get Arduino to talk OSC to Max:

I have tried two different examples sketches (SerialSendMessage, and SerialOscuinoWithMessages). All the required objects (such as slipOSC, OpenSoundControl and OSC-route) are installed correctly. And I'm getting nothing. Correct COM port, baudrate etc. Tested Arduino and Max with a dummy sketch and everything is working as expected. Not getting anything via USB-serial or any of the CNMAT examples.

Been at this all day and starting to get a little jaded. The CNMAT site says that the OSCuino bundle comes with example Max patches, which it doesn't.

:(

brendan mccloskey's icon

Arduino Mega 2560 (I have an old NG somewhere I can use also), Win 7, Arduino IDE 1.6.2, Max 6.1.10 32-bit. If that helps.

I'll try grabbing the latest latest version of CNMAT-Everything, but it appears to be MacOS only

brendan mccloskey's icon

Maybe it's been a long day, but. My own customised sketch works fine: 16 FSRs at 115200 bps. Admittedly, it's reading and sending chronologically, so I'm learning how to power digital pins in parallel, and I've had a suggestion to only send all the sensor values, once they've all been read. Might tighten things up a bit. Can't be bothered with troubleshooting a new encoding/protocol, because of perceived enhancements. Preemptive optimisation indeed.

But I really would like to learn OSC all the same.

Tired little bunny

brendan mccloskey's icon

OPEN Sound Control? Really? More like Secret Arcane Unsupported Language Implementation Mystery. Three days of research and I'm still friggin none the wiser.

F*ck it, serial-USB serves me well, anyone wanna buy some ethernet chips?

vichug's icon

(did you try contacting people at CNMAT directly ?...)

Wetterberg's icon

it's off topic, but you've got 16 fsrs hooked up to an arduino? Sounds like a great project! I've been meaning to convert my Trigger Finger into something a bit more... hacky :D

Which fsrs are you using? The sparkfun ones?

pdelges's icon

Keep your ethernet chips! There is no need for OSC to communicate with an arduino over ethernet (there are udp examples in the arduino's IDE). Instead of [udpreceive], use [mxj net.udp.recv ] or sadam's library to receive the UDP packets in Max.

Wetterberg's icon

urgh, mxj net.udp.recv is pretty ugly though, it binds to the port, so you basically have to reserve special ports for special destinations... that's pretty limiting, don't you think? IIRC the s adam lib does the same thing?

brendan mccloskey's icon

Hi guys, thanks for responding to my ugly little rant there.

@vichug, I've signed up to CNMAT, but 3 days later and still no response. There's a paper by Dave Wessel from 2004 that's really relevant, and might help clarify things, but I can't access it yet. I've heard that Adrian Freed is quite apporachable, so once my subscription to CNMAT goes live, I'll consult him.

@Wetterberg, at the moment the interface consists of 16 x DIY FSR (copper fabric and Velostat sandwich) embedded below a small DIY silicone disc/pad, each with an embedded LED. It's being reworked at the moment though, in light of a better solution I have devised. Top secret hush hush.

@Patrick/everyone. I need to get a handle on the whole UDP protocol/system first I think, but the udpsend/receive helpfiles will make a good start.

I just find it very frustrating that for a beginner, the whole CNMAT-Everything package is a bit daunting, and not very clearly laid out. Might just put it to one side for the moment. As I keep saying though, I'd still like to become OSC_fluent, as it seems to be growing in popularity.

Brendan

hz37's icon

Hi Brendan,

I'm sort of in the same boat with OSC, so here's some of the things I've encountered that might be of help for you.

- I've been wrestling with the SlipEncodedSerial OSC message building from Arduino to Max as well, and thought it wasn't worth the trouble. I don't see an advantage in encoding to slip OSC and decoding slip OSC again at the Max side of things. So whatever an Arduino sends to Max is a plain old serial string or number. If I want to turn that into OSC, Max will take care of it.

Here's how to make life so much easier:

If you want a sensor value to enter Max from the Arduino, turn it into an 8 bit number. For most purposes, that's more than adequate. For instance, if I want analog sensor 0 to become an OSC message, this is my Arduino code:

void setup()
{
Serial.begin(9600);
}

void loop()
{
// read the input on analog pin 0:
int sensorValue = analogRead(A0);
char c = map(sensorValue, 0, 1023, 0, 255);
Serial.write(c);
delay(1); // delay in between reads for stability
}

Max Patch
Copy patch and select New From Clipboard in Max.

The advantage is that you can have a really simple serial receiver in Max. No need to flush out line ends etc. Not a gazillion numbers that represent a slip OSC message. So [0..255] travels to Max, and there you will scale it further to a floating point message in the range [0.0 .. 1.0], which is the default for just about every OSC parameter.

Again, I see little reason to use the CNMat packages, when you can create your OSC addresses simply with a Max message box as in the above example. In this example I [udpsend] to two devices, one being Reaktor running on the same machine and listening to port 8000 and the other being my iPad running TouchOSC listening to port 9000.

The cool thing about UDP/OSC is that you can have everything happening simultaneously. So you can have an Arduino parameter entering Max via serial and going out to several devices on whatever networked machine they happen to be running. And another process can even transmit the same OSC message and it'll still work.

Which brings me to another point: it's more fun experimenting with OSC if you have at least a few things that work great. I happen to be on OSX, but here's a few things I really enjoy using with OSC:

- Reaktor. It's super easy to map a parameter to OSC. Right click on any control and choose OSC learn.

- TouchOSC on my iPad is also gold. You can create your own layouts with custom addresses. It can also transmit accelerometer data via OSC.

- Python. I'm using python-osc (pip3 install python-osc). It's super reliable, e.g.:

import time

from pythonosc import osc_message_builder
from pythonosc import udp_client

client = udp_client.UDPClient('192.168.178.26', 1234)

for idx in range(0, 100):
msg = osc_message_builder.OscMessageBuilder(address = '/hey')
msg.add_arg(idx)
msg = msg.build()
client.send(msg)
print(idx)
time.sleep(1)

Max Patch
Copy patch and select New From Clipboard in Max.

Then have Max listen to port 1234:

Have fun!

brendan mccloskey's icon

Hi HZ37
many thanks for this advice; my failure to grasp OSC/UDP via ethernet derives from trying to learn a 'new' transport layer and protocol at the same time. I should have stated at the outset that my INITIAL interest in OSC over ethernet was simply for Arduino to PC, for enhanced resolution and speed. On the Arduino forum I've learned that, while one may push the baudrate beyond 115200, other contributors say that ethernet doesn't exactly give "blazing" speeds either. Adrian Freed and Matt Wright talk about sub-millisecond accuracy and sampling rates in the kHz, though I'm not yet clear if they were explicitly talking about ethernet TCP UDP or whatever. I'm struggling now. Damn it all to hell guys, I'm not a telecoms engineer - actually that reminds me, I know two people who are, must bend their ears soon.

So, anyhoo. You make a good point about how I might use OSC for networked instrument/performance control, in some future experiments. In the meantime, perhaps Andreas or Patrick might be kind enough to offer a simple Max and/or Arduino example of sending from Arduino. Again, at the risk of illustrating my ignorance, send UDP from Arduino to Max udpreceive? Am I close?

Brendan

(and thanks for the continued support)

hz37's icon

Sending from the Arduino is quite easy and successful. I have an ethernet shield connected to my Arduino Uno. It's connected to the main router of our home network and runs the following code to send the reading of analog 0 as an OSC message:

#include
#include // UDP library from: bjoern@cs.stanford.edu 12/30/2008
#include
#include // needed for Arduino versions later than 0018

// MAC address from the bottom of the Ethernet shield.
byte mac[] = {0x90, 0xA2, 0xDA, 0x0D, 0x22, 0xB0};

// An EthernetUDP instance to let us send packets over UDP.

EthernetUDP Udp;

void setup()
{
// DHCP assigns an IP address.
Ethernet.begin(mac);

// We will only send here, so use an arbitrary listen port.
Udp.begin(1234);
}

void loop()
{
// Create an OSC message.
OSCMessage Msg("/analog/0");

// As a value, add the current value of analog 0 input.
Msg.add(analogRead(0));

// Send to Max, [udpreceive 5678] listening to port 5678.
Udp.beginPacket("192.168.178.26", 5678);
Msg.send(Udp);

// Clean up.
Udp.endPacket();
Msg.empty();

// Time to settle down the ADC.
delay(20);
}

You'll have to change the MAC address to the one on the bottom of your ethernet shield, of course. And figure out the IP address that Max is using on your machine. I did install the CNMAT OSC Arduino library, but that part is very transparent and easy to use.

Max Patch
Copy patch and select New From Clipboard in Max.

Then Max will simply listen to port 5678 via [udpreceive], No need to use any CNMAT objects. To parse OSC messages, I simply use a [regexp] object in Max as below:

Lemme know if it works! Good luck and have fun.

Screen-Shot-2015-05-01-at-09.40.44.png
png
brendan mccloskey's icon

Hi
many thanks, again HZ37. Will test this once my ethernet breakout boards arrive (i'm using Chinese Hanrun breakout boards, not official Ethernet shields - £50 versus £3 !), so some tweaking is involved, but once I'm up and running I'll report back, with success hopefully, thanks to your input

Brendan

Wetterberg's icon

watching this thread closely. I have a lot of experience with OSC, and a fair amount of arduino experience too, but no experience with using OSC from an arduino at all. I'd just use arduivis or whatever for arduino projects normally, but our OSC stuff is scaling to a size where plugging into a switch and distriuting OSC is attractive.

brendan mccloskey's icon

Hi Andreas

that's good to hear, many hands make light work. Amongst yourself, HZ37, and Jan who has also offered support, we should be able to crack this. For clarity, this is what I'm intending to do:

- hack the existing Arduino-UDP sketches to see if I can successfully send multiple sensor data to Max via [edit] CAT5/e cable
- I have some ethernet boards from Hong Kong (not China as previously stated), I need to research how to assign them a MAC address, as they don't inherently have one
- buy or make a CAT 5/e crossover cable, as I don't yet need network capability, I simply want to see if Ethernet transport layer is indeed 'better' than the serial bus
- receive sensor data in Max (question: if I'm not using a network router or hub, does that negate using udp? Is UDP 'like' serial, will it simply be ArduinoUDP(send) -->Ethernet cable--> MaxUDP(receive)?
- in the near future, if all this is successful, then I can easily exploit and broadcast OSC - thanks to the contributors here - using UDP*send* in Max to access a local network.

Phew

My ATmega chips and FTDI boards arrived today, so as soon as I get some caps and a crystal I'm building my own Arduino clones. Yay.

brendan mccloskey's icon

Stress test figures, non-bump update, perhaps of interest to Andreas, and others.

115200 bps and 35 fake sensors (discrete random number ranges) works fine

Just reporting figures FYI

Brendan

Wetterberg's icon

That's regular serial transmission over usb? I'm wondering what the updates-per-second for each fake sensor is like? (headmath=hardmath)

brendan mccloskey's icon

Well, back of the postcard numbers would be 115200 bps = 11520 bytes/s, call it 10kHz for ALL 35 sensors = 330 Hz for each individual value (as they're in a serial queue). Not great. And in my code there's a delay(1) just as a safety precaution, and a [qmetro 1] in Max. So the actual sampling rate is 1kHz overall (the serial object is using the default bufsize 2048; not sure what impact this has in practice). Ultimately, the ATmega368 clock speed and code iteration cycles could impact on these numbers, and that's a bit too low level for me.

Incidentally, it looks like I might have to pull this back down to 57600 bps, Max will hang if I send the serial object a 'close' message at 115200. In any final analysis, it's important to note how it 'feels', to play it. I'll post results of that analysis when I have the new prototype built.

HTH

brendan mccloskey's icon

I'll probably have to take this off-forum as my research has taken me into unfamiliar technical territory:

If you want to join the nerd-fest@http://forum.arduino.cc/, you'll know where to find me

Basvlk's icon

Hi Brendan, did you get it to work in the end? I'm trying to do something similar, but different: send OSC packages to the Arduino over wifi.
I have used touchOSC for years on Ipad and Iphone - so it's my fastest way of building a 'remote control'.

I'm hoping I won't need a computer or Raspberry Pi to do any interpretation - I'd just want to send OSC messages straight from touchOSC to the Arduino. I realise Max has fallen out of the equation here, but it will end up as a part of the setup, inevitably...

btw - what the hell is going on with CNMAT? site down, no response, no info anywhere on why it's gone

brendan mccloskey's icon

Hi Basvlk
I ended up using Processing and Supercollider to learn about the OSC 'format'; but on Windows there is no Arduino comms extension to SC. So, it's very slow - runs at the Processing frame rate - I use the Serial library in Processing and send OSC from there to SC. I'm happy now that I can implement OSC should the need arise, but as far as Max goes, I've yet to find a better solution than the serial object for communication with Arduino. And the boards are getting smaller and smaller, and cheaper and cheaper.

Sorry not to be of more help.

Brendan

brendan mccloskey's icon

. . . and I have yet to implement HZ37's advice, or investigate udp send/receive. They seem like much more transparent options.

B

Jan M's icon

... maybe a bit out of topic, but i'd like to share some recent "discoveries":

Since the (useless, unnecessary, vanity-driven, what a f*** up ) split of the Arduino project into the US (arduino.cc) and European (arduino.org) branch there are also two IDEs and two different Ethernet Shield/Board Types available. For the US boards you'll need to use the US IDE and the Ethernet.h/ EthernetUdp.h libraries for the (newer) European boards/shields (e.g Leonardo Ethernet/Ethernet Shields v 2) the European IDE and the Ethernet2.h/EthernetUdp2.h libraries. The latest version of the Arduino CNMAT OSC library (https://github.com/CNMAT/OSC) seems to support both, an older version that I had installed only worked with the (now) US version.... Also note that the example code in the CNMAT library solely uses the older Ethernet libraries version. Depending on your board you'd might have to adapt the examples to make them work.

To complete confusion both projects keep on using the same logo and App name for the IDE but use different not really conclusive version numbers (grrrrr). Current Arduino.org (Europe) IDE version is 1.7.8, Arduino.cc (US) 1.6.6