Serial control of Arduino pins (not reading them, writing them) from Max
Hi all,
I'm having a bit of a brain teaser here, trying to sort out how to send PWM controls to multiple Arduino pins. As a start I thought I'd make a Max patcher to send the 3 pin control info and the ASCII n symbol to interface with this Arduino tutorial sketch using an RGB LED: http://arduino.cc/en/Tutorial/ReadASCIIString
I'm having trouble figuring out how to follow the 3 data values with the ASCII n (line feed/newline) code. Any suggestions?
Thanks in advance!
Steven
Can you post your patch and arduino code ?
Hi Nat,
Thanks for the reply. The Arduino code is in the link in the original post. I'll attach it below, for convenience.
I'm wanting to send the 3 control data bytes from Max rather than from the Arduino IDE serial monitor, as the sketch is set up for (3 binary bytes (0-255) comma or space separated, followed by ASCII 10). My (unsuccessful) Max patch is pasted below. I have no trouble sending the binary bytes successfuly by themselves, but getting them to be followed by the ASCII new line is where I'm getting hung up. Also, I'm not too worried about sending/receiving the data back from Arduino to Max - that part will be discarded as soon as I get the patch working.
Thanks,
Steven
Max patch:
Arduino sketch:
/*
Reading a serial ASCII-encoded string.
This sketch demonstrates the Serial parseInt() function.
It looks for an ASCII string of comma-separated values.
It parses them into ints, and uses those to fade an RGB LED.
Circuit: Common-anode RGB LED wired like so:
* Red cathode: digital pin 3
* Green cathode: digital pin 5
* blue cathode: digital pin 6
* anode: +5V
created 13 Apr 2012
by Tom Igoe
This example code is in the public domain.
*/
// pins for the LEDs:
const int redPin = 3;
const int greenPin = 5;
const int bluePin = 6;
void setup() {
// initialize serial:
Serial.begin(9600);
// make the pins outputs:
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
}
void loop() {
// if there's any serial available, read it:
while (Serial.available() > 0) {
// look for the next valid integer in the incoming serial stream:
int red = Serial.parseInt();
// do it again:
int green = Serial.parseInt();
// do it again:
int blue = Serial.parseInt();
// look for the newline. That's the end of your
// sentence:
if (Serial.read() == 'n') {
// constrain the values to 0 - 255 and invert
// if you're using a common-cathode LED, just use "constrain(color, 0, 255);"
red = 255 - constrain(red, 0, 255);
green = 255 - constrain(green, 0, 255);
blue = 255 - constrain(blue, 0, 255);
// fade the red, green, and blue legs of the LED:
analogWrite(redPin, red);
analogWrite(greenPin, green);
analogWrite(bluePin, blue);
// print the three numbers in one string as hexadecimal:
Serial.print(red, HEX);
Serial.print(green, HEX);
Serial.println(blue, HEX);
}
}
}
Clearly posting the Arduino code made a mess...it's probably easier just to copy & paste from the link in the original post...
I just realized I posted the wrong version of my Max patch...and In doing so, I think I've sorted out the issue - but I don't have my Arduino here, so can't test it until tomorrow. So, I'll wait to resend the correct version of the patch until I've had a chance to try it out tomorrow.
Thanks!
OK, just for completeness' sake, here's the correct and working version of the Max patch that interfaces with the Arduino sketch in the linked URL.
DId you try with ascii character 13 (CR) ?
Sometimes it expects CRLF so 13 10
This particular sketch only looks for 10, though you're right, they often come together.
Hmmm, did you try sending messages individually (by using the iter object ?
Hi Nat, actually, as I mentioned in the post where I attached the last version of the Max patch, everything is correct and working now. Sorry for the confusion - it's all sorted out now. Thanks!
Thank you for posting your research!
Hi Steven, Nat,
I'm actually trying to get this going with a pixel strip and seem to be running into the same trouble. I'm using a modified version of Steven's patch and the GraphASCII code from Tom Igoe. I can pass variables to control pixel #, r, g, and b fine in the serial monitor and additionally, can control single variables from Max, but I'm having trouble passing the whole string. If anyone had any suggestions I'd be grateful.
Arduino#include
#define PIN 9
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
Serial.begin(9600); // initialize serial communication
//Serial.setTimeout(100); // set serial timeout
strip.begin(); // initialize pixel strip
strip.show(); // Initialize all pixels to 'off'
}
void loop() {
// if there’s any serial available, read it:
while (Serial.available() > 0) {
// look for the next valid integer in the incoming serial stream:
int pixel = Serial.parseInt();
//do it again:
int red = Serial.parseInt();
// do it again:
int green = Serial.parseInt();
// do it again:
int blue = Serial.parseInt();
// look for the newline. That’s the end of your
// sentence:
if (Serial.read() == 'n') {
// constrain the values to 0 – 255 and invert
// if you’re using a common-cathode LED, just use “constrain(color, 0, 255);”
//pixel = constrain(pixel, 0, 59);
//red = constrain(red, 0, 255);
//green = constrain(green, 0, 255);
//blue = constrain(blue, 0, 255);
// print the three numbers in one string as hexadecimal:
Serial.print(pixel, HEX);
Serial.print(red, HEX);
Serial.print(green, HEX);
Serial.println(blue, HEX);
}
}
int pixel;
int red;
int green;
int blue;
strip.setPixelColor(pixel, red, green, blue);// set the color for this pixel
strip.show();
}