Hey guys. I know this is a pretty new release, but I’m wondering if there is any more entry-level or plain language documentation with examples for how to use the library. I’m doing a project with some WS2801s and I haven’t worked with LEDs a ton and I’m having trouble getting started. Thanks a lot for all the great work, I’m excited to dig in
The best place to start right now is probably the example code that comes with the library. Have you taken a look at that, and have you gotten your LEDs to light up yet?
The wiki here https://code.google.com/p/fastspi/w/list has some further notes which may be helpful.
If you’re having specific problems, please feel free to post code or questions here and folks will help out.
Finally, bigger and better documentation is coming. It’s one of the “release criteria” for the full 2.0 version of the library as far as we’re concerned. Dan and I both have pretty full summer plans, but we’ll do what we can to get some good docs in place over the next weeks.
Thanks for the quick reply, Mark. I do have a question I would love some help with. Hopefully it is a pretty quick solve.
Background: I’m making a gesture-based music tool using a Kinect + Ableton live, and I would like to use some LEDs to give the user some visual feedback about what he/she is controlling. So for example, if the user turns the drum channel on, I would like a small bank of LEDs to light up.
I’m using a string of 50 WS2801s and currently an arduino uno, though I do have a teensy 3.0 I could use instead. I can get the pixels to light up and cycle through green and blue using the Fast2Dev.ino example. My question is, what would be the best way to set up banks of pixels within my string that I could then address as a group? So, for example, pixels 0 - 9 = Bank1, 10-19 = Bank2, etc. Do I just need to declare an array and assign the pixel numbers I want in that array? If so, could anyone help me out with what that would look like in code?
Thanks so much!
If you have your main led array declaration as
CRGB leds[50];
then you can define your ‘banks’ as pointers into that one main array, thus:
CRGB* Bank1 = &(leds[ 0]);
CRGB* Bank2 = &(leds[10]);
CRGB* Bank3 = &(leds[20]);
etc.
You can then just refer to Bank1, Bank2, Bank3, etc as if they were distinct pixel arrays. E.g.,
Bank2[ 3 ] = CRGB::Red; // set pixel 3 in Bank 2 to Red.
For further example, this function would set all ten pixels in a given Bank to a given color:
void setBankColor( CRGB* bank, CRGB& color) {
for( byte i = 0; i < 10; i++) { bank[i] = color; }
}
You’d call it like this:
setBankColor( Bank2, 0xFF0000 ); //set Bank2 to red
Hope this helps. If I understand what you’re asking, it’s largely a “C”-language question about pointers and arrays – which is often a point of complexity and confusion.
You are THE coolest.
I was literally just this minute reading up on how to pass arrays into functions in C. And there you go, being all awesome and totally nailing my question on the head.
Thank you soooo much. Do you guys have a tip jar for Fast SPI? Looking forward to seeing more of the awesome to come!
Hey Mark. With this code:
#define NUM_LEDS 25
CRGB leds[NUM_LEDS];
CRGB* Bank1 = &(leds[ 0]);
CRGB* Bank2 = &(leds[5]);
CRGB* Bank3 = &(leds[10]);
CRGB* Bank4 = &(leds[15]);
CRGB* Bank5 = &(leds[20]);
void setBankColor( CRGB* bank, CRGB& color) {
for( byte i = 0; i < 5; i++) { bank[i] = color; }
}
char val; // Data received from the serial port
void setup() {
LEDS.addLeds<WS2801>(leds, NUM_LEDS);
Serial.begin(115200); // Start serial communication at 115200 bps
}
void loop() {
if (Serial.available()) { // If data is available to read,
val = Serial.read(); // read it and store it in val
}
if (val == ‘H’) { // If H was received
setBankColor( Bank1, 0xFF0000 ); // turn bank one red
} else {
leds[].setRGB( 0, 0, 0 ); // Otherwise turn it OFF
}
LEDS.show();
delay(10); // Wait 10 milliseconds for next
}
I’m getting this error: “Invalid initialization of non-const reference of type ‘CRGB&’ from a temporary of type ‘long int’”
then:
LEDJ_FastSpi_0_1.ino: In function ‘void loop()’:
LEDJ_FastSpi_0_1:43: error: invalid initialization of non-const reference of type ‘CRGB&’ from a temporary of type ‘long int’
LEDJ_FastSpi_0_1:24: error: in passing argument 2 of ‘void setBankColor(CRGB*, CRGB&)’
LEDJ_FastSpi_0_1:45: error: expected primary-expression before ‘]’ token
Any thoughts? Sorry for the long troubleshoot in a comment. I’m happy to post in another forum if there’s a better place. Thanks again for all the help.
Whooops. Jumped the gun on crying for help there.
I just added a ‘const’ in front of the ‘CRGB&’ and it compiled and works great. Just to be sure I’m not setting myself up for future failure, is that indeed the best fix?
Yep. My bad for not putting it in. Nice find.
leds[].setRGB(0,0,0) isn’t going to do what you want, I think. That won’t set all the leds to black, just the first I believe.
There’s a convenience function called fill_solid that you can use:
fill_solid( leds, 50 /number of leds/, CRGB( 0,0,0) );
yeah I had written that quickly to test out the function you sent and pulled a whoops on that the leds.set. Thanks for the catch and the heads up on the helper function. I like the scaling feature alot, too. Are there any other cool effects functions you’d recommend? Chases or anything like that?
static byte hue = 0;
hue = hue + 1;
fill_rainbow( leds, NUM_LEDS, hue);
Cool! Thanks man. I really appreciate all the help. I’ll be sure to send some links when my project is up and running
Hey Mark. One more question. Should I be able to set other attributes with my setBank call? For example, setBankBrightness
The library’s built-in setBrightness function is global. If you wanted to have your setBankColor function take a separate brightness parameter (and have it default to full brightness), you could do this:
void setBankColor( CRGB* bank, const CRGB& baseColor, byte brightness = 255) {
CRGB adjustedColor = baseColor;
if( brightness != 255) {
adjustedColor.nscale8_video( brightness);
}
for( byte i = 0; i < 5; i++) { bank[i] = adjustedColor; }
}
The CRGB::nscale8_video function take a CRGB color and adjusts the brightness (down) based on the 0-255 argument you supply.
We’ve actually provided this as an overridden member function, too, so if you prefer, you can just do this:
adjustedColor %= brightness;
The rationale for using the “%” operator is that you’re sort of scaling the brightness down by a ‘percentage’ (even though it’s a per255thage).
Me, I tend to think that simpler code can be more legible and more maintainable. I think I’d omit the if, and just do this:
void setBankColor( CRGB* bank, const CRGB& baseColor, byte brightness = 255) {
CRGB adjustedColor = baseColor % brightness;
for( byte i = 0; i < 5; i++) { bank[i] = adjustedColor; }
}
Awesommme. And to call that I would just include that in my setBankColor, right?
So, setBankColor( bank2, 0xFF0000, adjustedColor %= 128);
would set bank 2 to red at 50% brightness?
Sorry, I left out the example use:
// half-brightness red
setBankColor( bank2, 0xFF0000, 128);
oh wow, even easier. Nice. Thanks again, Mark. You do a kick-ass job.
Sorry, Mark. One more.
What is memset all about? Should I be using that? The processing sketch I’m using to feed the arduino sketch just tapped out on a memory problem which made me remember seeing memset referenced in the fast2dev example
from what i believe, memset is a quick easy way to set all address’s at once