Forums > MaxMSP

[sharing is caring] Arduino + max

March 31, 2009 | 4:05 pm

This semester I’ve had a number of students ask me about getting sensor data from the Arduino into Max. Seeing as how a component of the class involves actually writing code for the Ardy, I don’t even mention Firmata, Simple Message System, etc.

Luke’s example in the Max tutorials is good for showing that the Arduino and Max can communicate, but has confused some of the people in my class, particularly those who are not well accustomed to patching.

This simple example illustrates multiple analog inputs on the Arduino going into max as bytes. There’s a simple handshake protocol involved so the Ardy only reads the Analog Pins 0 & 1 when Max requests the information.

The Arduino code isn’t commented, but is very straightforward.

Suggestions for improvement are quite welcome.

~s

max5 serial comm with arduino

– Pasted Max Patch, click to expand. –

Arduino serial comm with Max

int Sensor1 = 0;
int Sensor2 = 1;

int Val1 = 0;
int Val2 = 0;

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

void loop(){
if(Serial.available()>0){
int inByte = Serial.read();

Val1 = analogRead(Sensor1);
Val2 = analogRead(Sensor2);

Serial.print(Val1/4,BYTE);
Serial.println(Val2/4,BYTE);
}
}


March 31, 2009 | 11:25 pm

hi, thanks for sharing this.. as a new arduino user myself, im glad to see more stuff to learn from.

i get all the program except the last two lines.. could you comment on the Serial.print(Val1/4,BYTE); line?

i understand you’re sending the values of the ADCs serially as a byte, but why val1/4? is this because arduino sensors encode the ADC signal to 10 byte values (1024), and 256 (1024/4) is 8 bit (as is a byte)?

also, to me it looks like you have an unused variable, int inByte… can you comment what it does?
thanks :)


April 1, 2009 | 3:31 am

Quote:i get all the program except the last two lines.. could you comment on the Serial.print(Val1/4,BYTE); line?

The Arduino is sending a Byte, 0-254. If you try and send the full 10-bits (0-1023), you’ll just roll over.

To get a full sensor reading into max, you can use Modulo, like this :

– Pasted Max Patch, click to expand. –

int Sensor1 = 0;
int Sensor2 = 1;

int Val1 = 0;
int Val2 = 0;

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

void loop(){
if(Serial.available()>0){
int inByte = Serial.read();

Val1 = analogRead(Sensor1);
Serial.print(Val1/4,BYTE);
Serial.println(Val1%255,BYTE);

}
}

As for the inByte, it’s local and just thrown out after each loop. In the max patch, after a valid packet is sent (Val1, Val2, 10, 13), max sends a byte to the Ardy, letting it know it is ready for more data. The inByte just reads this out of the serial buffer before sending the values from the pots.


April 1, 2009 | 12:52 pm

ah ok, thanks for clearing that up!


April 2, 2009 | 2:41 pm

hi,

first, an other way to have 1024 steps by replacing :

Val1 = analogRead(Sensor1);
Serial.print(Val1/4,BYTE);
Serial.println(Val1%255,BYTE);

by :

Val1 = analogRead(Sensor1);
Serial.print(Val1,BYTE);
Serial.print(Val1/255,BYTE);

is it better (only one operation) ?

second, i try to put some text from Max5 to a 16×2 LCD display, via an arduino board.
All is right with hardware but i’m not fluent in C and C++. So i need help to find a way to tell arduino to understand ASCII data string like "hello world!".
I suppose i need to declare this string, read it from serial, and then load it to LCD via lcd.print…

thanks a lot for your help !

fxw


April 2, 2009 | 3:14 pm

Quote:is it better (only one operation) ?

As an academic and practical matter, I find it’s best to be as explicit with things like that as possible. Plus, one % is not going to hog up massive amounts of resources.

As for the ASCII to Ardy, I think the nuts and bolts of it is best left to the Arduino forums. On the Max side, you would simply need to send the message "Hello World!" out the serial port (very bare bones example below):

– Pasted Max Patch, click to expand. –

April 2, 2009 | 4:05 pm

Thanks for your comments.

I go to Arduino forums…

fxw


April 2, 2009 | 4:45 pm

IMO, it is inevitable when working with Arduino or any microcontroller that you’ll have to eventually do some bitshifting and bitmasking. You will be much happier in the long run to spend a little time getting used to it. This will give you the most efficient and lightweight compiled machine code. For this example, I would do the following:

Serial.print(Val1&0xFF,BYTE);//explicitly mask the LSB using bitwise AND
Serial.println(Val1>>8,BYTE);//right-shift Val1 for MSB

Depending on the chip’s instruction set, a modulo (%) operation can actually be really expensive when compiled down (in terms of code size and clock cycles), when compared with bit-shifting/masking operations, which can usually be done in a single clock-cycle. On the Max side you can do a left-shift(< <8) on the MSB and add it to the LSB.
I believe there is a pretty good tutorial on bitwise operations on the Arduino site.
Best,
Andrew B.


April 2, 2009 | 4:53 pm

Thanks Andrew. You have a valid point, though I’m trying to do lowest common denominator-type programming for the class with these examples. I haven’t addressed bit-shifting, perhaps next week :)

I will be doing some Max+Arduino example work with Tom Igoe in a week or two. I’ll post what we come up with after.


May 14, 2009 | 8:13 am

Scott, I really love this stripped down method of Arduino communication, up until now I have been using SMS to communicate. But this is so good.

One question…. Using your method and current maxpatch, how would I write to a digital pin (for example to turn an LED on)

Many thanks


May 21, 2009 | 4:07 pm

Sorry for the tardy reply.

You should check out the next batch of Arduino examples (to be released in v.16).

Here’s the Physical Pixel example from the next release (i.e. turn on & off an LED).


Viewing 11 posts - 1 through 11 (of 11 total)