Serial communication between MAX MSP and Arduino
Hello!
I'm working on a project where I need to send integers through serial from MAX to Arduino. I am receiving write -1 in the MAX console, am I right in thinking that this should be write 1 instead and that this indicates an issue receiving the data?
Could you post your patch and your Arduino code?
I'm not sure if there is a more efficient way to send the code

#include <Servo.h>
Servo servoLeft;
Servo servoMiddle;
Servo servoRight;
#define CMD_OPEN_LEFT 101
#define CMD_OPEN_MIDDLE 102
#define CMD_OPEN_RIGHT 103
#define CMD_CLOSE_LEFT 121
#define CMD_CLOSE_MIDDLE 122
#define CMD_CLOSE_RIGHT 123
#define DIRECTION_OPENING 0
#define DIRECTION_CLOSING 1
typedef struct flower_struct {
const char *name;
Servo servo;
byte direction;
long lastStepTime;
int currentAngle;
int timeBetweenSteps;
int stepAngle;
int minAngle;
int maxAngle;
} Flower;
Flower flowerLeft;
Flower flowerMiddle;
Flower flowerRight;
void setup() {
Serial.begin(9600);
flowerLeft.name = "Left flower";
flowerLeft.servo = servoLeft;
flowerLeft.servo.attach(9);
flowerLeft.currentAngle = 0;
flowerLeft.servo.write(flowerLeft.currentAngle);
flowerLeft.direction = DIRECTION_CLOSING;
flowerLeft.lastStepTime = millis();
flowerLeft.timeBetweenSteps = 500;
flowerLeft.stepAngle = 1;
flowerLeft.minAngle = 0;
flowerLeft.maxAngle = 45;
flowerMiddle.name = "Middle flower";
flowerMiddle.servo = servoMiddle;
flowerMiddle.servo.attach(10);
flowerMiddle.currentAngle = 0;
flowerMiddle.servo.write(flowerMiddle.currentAngle);
flowerMiddle.direction = DIRECTION_CLOSING;
flowerMiddle.lastStepTime = millis();
flowerMiddle.timeBetweenSteps = 500;
flowerMiddle.stepAngle = 1;
flowerMiddle.minAngle = 0;
flowerMiddle.maxAngle = 45;
flowerRight.name = "Right flower";
flowerRight.servo = servoRight;
flowerRight.servo.attach(11);
flowerRight.currentAngle = 0;
flowerRight.servo.write(flowerRight.currentAngle);
flowerRight.direction = DIRECTION_CLOSING;
flowerRight.lastStepTime = millis();
flowerRight.timeBetweenSteps = 500;
flowerRight.stepAngle = 1;
flowerRight.minAngle = 0;
flowerRight.maxAngle = 45;
}
void loop() {
if (Serial.available()) {
long command = Serial.parseInt();
switch (command) {
case CMD_OPEN_LEFT:
flowerLeft.direction = DIRECTION_OPENING;
break;
case CMD_OPEN_MIDDLE:
flowerMiddle.direction = DIRECTION_OPENING;
break;
case CMD_OPEN_RIGHT:
flowerRight.direction = DIRECTION_OPENING;
break;
case CMD_CLOSE_LEFT:
flowerLeft.direction = DIRECTION_CLOSING;
break;
case CMD_CLOSE_MIDDLE:
flowerMiddle.direction = DIRECTION_CLOSING;
break;
case CMD_CLOSE_RIGHT:
flowerRight.direction = DIRECTION_CLOSING;
break;
default:
break;
}
}
update(flowerLeft);
update(flowerMiddle);
update(flowerRight);
}
void update(Flower &flower) {
if (millis() - flower.lastStepTime >= flower.timeBetweenSteps) {
switch (flower.direction) {
case DIRECTION_OPENING: {
int newAngle = flower.currentAngle + flower.stepAngle;
if (newAngle <= flower.maxAngle) {
flower.servo.write(newAngle);
flower.currentAngle = newAngle;
printFlower(flower);
}
}
break;
case DIRECTION_CLOSING: {
int newAngle = flower.currentAngle - flower.stepAngle;
if (newAngle >= flower.minAngle) {
flower.servo.write(newAngle);
flower.currentAngle = newAngle;
printFlower(flower);
}
}
break;
default:
break;
}
flower.lastStepTime = millis();
}
}
void printFlower(Flower flower) {
Serial.print(millis());
Serial.print(" ");
Serial.print(flower.name);
Serial.print(": ");
Serial.print(flower.currentAngle);
Serial.print(" (");
Serial.print(flower.servo.read());
Serial.println(")");
}
For your patch the best way to share is using Copy Compressed in the Edit menu and paste it here into the thread.
I am on the road right now. Later I’ll take a look
as first delet all that patchcords comming from if objects.
then restart max and load the patch.
Make sure arduino is recognised and correct port selected.
send single integers 0 - 255.

Ok I've had a go at that and the MAX console isn't receiving anything now
there is nothing that max console should receive.
only available serial devices when you click on print message.
I see! In that case

look into max console
it will tell you which port your usbmodem1401 is.
It says serial C. Do you know if there is anything else I need to do to connect to it?
if it is C, than your init port should match.
is it atmega32u4 based arduino.
one can't help you without more infos.
and you connected print status at wrong outlet.
left one is for receiving data from arduino in case you send any.
and you can't send floats like that.
only 8bit integers.
that trigger objects helps you in this case,
but sending floats directly to serial object will fail.
I see! It's an R4 Minima so I don't think so.
I did wonder if sending floats would be an issue! Do you know a good way to send integers?
Thankyou for your help by the way
all you need to send integers is visible in the shot I posted.
You must first verify that you can talk to that board,
use simple test patch like light LED when sending 1 and 0
or anything else.
Close arduino IDE before trying to use board in Max,
and opposite when uploading code to the board.
I would don't work like this for sending a flow to a serial.
Actually, and working on some projects requiring very fast arduino triggering , and not saturing or at least controlling the serial flow, I'd advice asynchronous things.
data are coming, buffer them, and bang/send them to serial with another part.
You can also code an external for this (this is what we did for a specific project) which buffer & release using an internal timer with Max Scheduler.
v8 for buffering is also perfect, even if I'd prefer not to put a timer inside but bang from outside to release data (when it is required)
Also, send only fresh data that has to be sent. If no change, don't send.
I cannot post more about the current project on which we have been involved but that way increased the speed & triggering flow x100 doing this. That's even too fast for .. the pneumatic physical system 🥴
Also, for fast triggering on the arduino side, there are some libraries like digitalWriteFast or like that are like ... 50x faster than the core one.
I would not assume that someone not having much idea about how serial object works would
code max external.
that is in fact a trivial task, to control few servo motors.
in any case when update interval between steps is 500ms ....
it is no way too fast for serial object, not even at 9600 baud.
but taming controller inputs before sending unneeded multiple same values too fast is of course
helpfull.