I've been struggling for a few months now trying to get Vuo to control addressable LEDs (neopixels / ws2812bs) over serial.
The part that I am failing to understand is how to package up a list of RGB pixel values in vuo and send them to a serial device (such as Arduino or Teensy). I've been experimenting with some Arduino sketches specifically for this such as: https://gist.github.com/Yona-Appletree/6490993
However I can't seem to generate the right data to control the LEDs such as, all LEDs to Red (255, 0, 0) or all off (0, 0, 0). Can anyone shed light on how Vuo sends serial data packets and maybe how one might form a composition that interfaces with the following code: ?
// include the neo pixel library
#include <Adafruit_NeoPixel.h>
// The number of LEDs being driven. This dictates how much data is expected in each frame read from the serial port.
static const int NUM_LEDS = 256;
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_RGB Pixels are wired for RGB bitstream
// NEO_GRB Pixels are wired for GRB bitstream
// NEO_KHZ400 400 KHz bitstream (e.g. FLORA pixels)
// NEO_KHZ800 800 KHz bitstream (e.g. High Density LED strip)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(
NUM_LEDS, // Number of pixels in strip
12, // Pin number (most are valid)
NEO_GRB + NEO_KHZ800 // pixel type flags, add together as needed:
// NEO_RGB Pixels are wired for RGB bitstream
// NEO_GRB Pixels are wired for GRB bitstream
// NEO_KHZ400 400 KHz bitstream (e.g. Old FLORA pixels)
// NEO_KHZ800 800 KHz bitstream (e.g. New FLORA pixels and most WS2811 strips)
);
// Buffer used to read LED data from Serial.
// TODO: Direct access to the Adafruit_NeoPixel buffer would cut memory usage in half
char colorValues[NUM_LEDS*3];
void setup() {
// Init the NeoPixel library and turn off all the LEDs
strip.begin();
strip.show();
// Do a quick test/demo to show that things are working
for (int i=0; i<60; i++) { flashAll(strip.Color((i%20)*2,i%30,i%60)); delay(10); }
// Initialize the buffer to all black
memset(colorValues, 0, sizeof(colorValues));
// Initialize serial and wait for port to open:
Serial.begin(115200);
while (!Serial) {
; // wait for port to be ready
}
// Tell the computer that we're ready for data
Serial.println("READY");
}
void loop() {
while (true) {
int bufferPos = 0;
// Read the data for each pixel
while (bufferPos < NUM_LEDS*3) {
int color = Serial.read();
if (color >= 0) {
colorValues[bufferPos++] = color;
}
}
// Feed the data to the NeoPixel library
for(int i=0; i<NUM_LEDS; i++) {
int d = i*3;
uint32_t c = strip.Color(colorValues[d], colorValues[d+1], colorValues[d+2]);
strip.setPixelColor(i, c);
}
// update the strip
strip.show();
// Clear up the serial buffer
while (Serial.available() > 0) Serial.read();
// Let the sender know we're ready for more data
Serial.println("READY");
}
}
void flashAll(uint32_t color) {
// Do a quick test/demo to show that things are working
for (int i=0; i < NUM_LEDS; i++) {
strip.setPixelColor(i, color);
}
strip.show();
}
Comments
In Vuo, Convert Data to Text
In Vuo,
Convert Data to Text -> Send Serial Data
is going to send the data as a UTF8-encoded string.For example, if you were to feed the integer 255 into
Summarize Value -> Convert Data to Text -> Send Serial Data
, this would send not one but three bytes of data to the serial device — one for the character '2', one for the first character '5', and one for the second character '5'. So yourint color = Serial.read()
is going to get not one but three numbers — 50, 53, 53.One solution would be to modify your serial device code to expect the data as a string rather than an integer, like in this example: https://www.arduino.cc/en/Tutorial/StringToIntExample
Or another solution would be to write a custom Vuo node that converts an unsigned 8-bit number (0-255) from Integer to 1 byte of Data so it can be read directly by
Serial.read()
. Or, for your purpose, a list of n Integers to n bytes of Data.