Electronic – Arduino serial communication protocol design

arduinomaxmspmidiprocessingserial

I make a drum sequencer interface for electronic music.

enter image description here

It uses an arduino mega as it's microprocessor, and currently it interfaces to a Processing program that I wrote for serial communication. From there, OSC messages are sent out to a Max/MSP program that my collaborating partner wrote to create a midi data stream.

So:

enter image description here

My physical interface -> Arduino Mega -> serial I/O -> Processing -> OSC -> Max/MSP -> Midi ( -> music app)

I chose this path partly out of not being clever enough to remove any of the steps yet, but also to accommodate being able to update the physical interface the way we want, being able to make the physical interface multi-purpose (multiple modes for the faders, knobs, and voice select buttons), and be able to ensure mission critical timing and rhythm modification (aka "swing").

My serial messages are set up like this:


PL,1;        // transport control: play
PL,0;        // transport control: stop
SW,30;       // swing value 30
TM,130;      // tempo value 130
SD,1,8,04,0; // Step sequencer data, pattern 1, voice 8 (of 8), step 04 (of 16), off
MU,8,1;      // Mute, voice 8 (of 8), on
SO,4,0;      // Solo, voice 4 (of 8), off
VL,3,127;    // Velocity, voice 3 (of 8), value 127
CC,1,127;    // Midi CC, controller 1, value 127
NN,1,36;     // Note number, voice 1 (of 8), value 36 (usually a kick drum)

So, you can see that based on the number of commas per semicolon, I can determine how to parse the serial data from the arduino in the processing program. From Processing, these kinds of messages are transformed into OSC like this:


/beatseqr/play 1
/beatseqr/play 0
/beatseqr/swing 30
/beatseqr/tempo 130
/beatseqr/matrix/1/8/04 0
/beatseqr/mute/8 1
/beatseqr/solo/4 0
/beatseqr/velocity/3 127
/beatseqr/midicc/1 127
/beatseqr/midinn/1 36

And it all works ok, but it feels inefficient. Do I really need the processing app in the middle?

enter image description here

Now, I had tried to chop Processing and the OSC parts out of the equation, but I'm missing some knowledge in regard to serial data protocol design.

I'm aware that there is a udpreceive object in Max. And that works ok I guess? Maybe I'm using it wrong.

At one point I had switched all of my arduino code to not send newlines at the end of every serial message since that didn't mean anything special to Max's udpreceive object. In fact, if I recall correctly, it would only accept the first message up to the first newline and then it would stop processing data. So to get around that, I took out all the newline characters and then it would spew into max/msp continuously.

Then the next problem with this method is that the udpreceive object only accepts one character at a time. So I was trying to use a js javascript object to concatenate the incoming characters, and then parse them on the semicolons and commas. The problem I ran into there was that it was unpredictable and unstable. Characters would drop out and the message would be unprocessable. So it's really making me wonder if I should change my serial data protocol to something more robust? Or if I'm just doing it wrong entirely?

Should I just scrap it all and start over from scratch using a firmata firmware? I've seen some tutorials for using the firmata with Max/MSP, and I guess I could take a fresh look at what the code on the box is doing and if it needs to do it at all. Can the firmata accept string data on a pin to send to the on-board serial LCD? if I can control the LCD from max/msp, that might work out ok.

Got any advice?

Best Answer

Is it possible that your problem is caused by Arduino? I know that sounds strange, because Arduino strongly relies on serial communication and it doesn't usually fail. But I would suggest you to try your Arduino with different speeds, dumping human readable data and monitoring with a terminal program. I've had the same problem and that was caused by ground problem of my arduino. Also, another solution might be using a custom arduino design with serial-friendly clock speeds like 14.7456MHz or any value multiples of 3.6864MHz. Hope it helps...