My first post in the Arduino Forums, but long time lurker.
I have a project of 15 x 3m LED RGB Light strips that I will be controlling through tension sensors via Max/MSP. I have the tension sensors working more or less. But thats beside the point I think.
My problem is with the serial data coming out of Max/MSP and into the Arduino Mega being VERY slow, and I think it is the way I am packaging and passing the data out to the board. I have 3 Megas, each attached to 5 LED strips (3 colours x 5 strips = 15 PWM pins on each Mega). So for each Mega (the other two will have the same code), there are 15 numbers between 0 and 255 converted to ASCII ('atoi') and 'append'ed with '10' on the end to restart a line, being sent out of Max (see attached image). I have also attached the current Arduino code, which has been expanded from the original 1 LED RGB code...
Does the data need to be ASCII? I feel like there should be quite an easy and efficient way to do this but I'm not incredibly clear on it all... Whatever advice you have would be helpful. Cheers!
P.S. I am aware of other and possibly more efficient ways of setting the lights up hardware-wise (e.g. TLC5940...), but I spent so long trying and failing to make them work that I ended up just going down this route haha.
but I think there is a bigger problem is related to the way i'm packing the data...
I think there is something wrong with my transmission because my car won't go over 20 miles per hour in 6th gear, when I don't press the gas pedal. I was planning to press the gas pedal later, after I got my transmission fixed.
Well it is not just a speed thing, thats why I haven't just put it in full throttle; the lights that do change after the 5 second latency are glitchy and not smooth like I get when I have only 1 strip connected and code for only that light
// if there’s any serial available, read it:
while (Serial.available() > 0) {
// look for the next valid integer in the incoming serial stream:
int red1 = Serial.parseInt();
// do it again:
int green1 = Serial.parseInt();
// do it again:
int blue1 = Serial.parseInt();
You must check for available() before every call to parseInt().
Why not write a blocking helper function:
int readInt ()
{
while (Serial.available () == 0)
{}
return Serial.parseInt () ;
}
since you're intending to block anyway?
The other approach is to use a state machine to record progress through your packet parsing,
or to move to a fixed length binary packet and then one call to available () can test for the
entire packet as its length is known.
so i don't need to have serial.available() everytime? cool.
i'm still not quite sure if the data coming out of max and into arduino MUST be ASCII or not?
if it does, and my original LED values are between 0 and 255, then technically the ASCII values for each RGB colour can be anything from 1-3 integers...; how does the arduino code know when to finish that colour parse and move to the next one?
sorry if its a bit vague, but perhaps an example will help:
controlling 1 RGB light by sending values of 255, 5 and 24 for R, G and B respectively from Max, converted to ASCII this would be 050 053 053, 053, and 050 052 respectively.
How do i write the code so that the arduino will know to stop parsing data to R after 050 053 053, then to stop G after 053, and B after 050 052?
Should I append a 013 010 after Each colour in Max, and write something to end the parse and move on after it receives a printLn after each colour line in Arduino? Is there a simpler way to do all of this?
How do i write the code so that the arduino will know to stop parsing data to R after 050 053 053, then to stop G after 053, and B after 050 052?
How would you parse that question if it was:
HowdoiwritethecodesothatthearduinowillknowtostopparsingdatatoRafter050053053,thentostopGafter053,andBafter050052?
Much harder, isn't it. Perhaps a clue has presented itself...
Your Max/MSP program appears to be taking a bunch of values, packing them in an array, and then converting each element in the array to a 3 character string. If you change that to not pad the string to 3 characters, then you need to add a delimiter of some kind between the strings. Doing that won't save many characters being sent. Currently you send 3 characters per value. Sending as a non-padded string with a delimiter will change that to 2 to 4 characters per value. So, you might end up sending more data.
You could have MaxMSP not convert the values to strings, sending the binary data directly. That would reduce the 46 characters sent now to 15 bytes. A definite savings, BUT the problem then is how do you tell if a byte is lost? With what you have now, every 46th character is supposed to be a new line. If it isn't, you know that the current packet is corrupt, and can discard it. Sending binary data, instead, removes the use of 10 (new line) as the packet delimiter, because 10 is a valid value for the red component of the first LED's color.