Using the Imp for an RGB "Pixel Chase"

Hello! I have a hardware question. After some research, I found an LED strip that suits my needs that I would like to connect to the Imp. Vin is 5V so that’s not a problem. However, I’m not too certain what to do on the software end.

I’ve ordered the strip and it will arrive in a few days. The example code they provide is arduino based:
http://learn.adafruit.com/12mm-led-pixels/code

I’m familiar with the Imp process and have two up and running that make use of RGB LEDs & PWM, but I’m unfamiliar with how the to properly clock the data, as described in the code above code.

ANY help would be greatly appreciated. And any example code that you think/know would make me your new best friend. Thanks!!

If you’re curious, what I’d ultimately like to do is be able to take an HTTP IN and interpret 2 colors/intensities and send color1/intensity1 down to fill the first half of the strand and color2/intensity2 throughout the rest.

I know how to interpret HTTP IN arrays and have them execute to variables, but it’s the rest that makes me o_O

Thanks!

That strip is driven by a series of WS2801 controllers. Those are quite common, and, fortuitously, feature in the first example on http://devwiki.electricimp.com/doku.php?id=writingefficientsquirrel – which should be enough to get you started.

You’ll need to connect clock to the SCLK and data to the MOSI of one of the imp’s SPI peripherals. However, the imp is 3.3V, not 5V – are you sure the voltage will work out? The WS2801 datasheet says min VIH is 0.8*VDD, so for 3.3V signalling that would imply that you shouldn’t run the power supply at more than 4V.

Peter

Peter,

Thank you so much!! I just took a good look and none of it makes me want to run, just yet. Off to tinker around in the code a bit…

All parts are in and the code works well. Thank you, again, Peter.

Looks like I got it figured out. I had some issues with flickering after about a minute passed. Thought it had something to do with the buffer or clock until I realized it was a power issue. I had connected the wrong wall wart to the unit and instead of 2000mA, I was only sending 300, leaving the imp and the LED strip fighting each other for power, I assume.

I’m now looking for a way to cleanly iterate a color between each pixel with a 100ms delay, or so. The way I’m doing it is with a for-loop, writing the SPI out to an additional pixel with each pass.

Any better ideas out there?

I’m hitting an issue when I try and display the pixels at a linear, non-max, RGB (i.e. R:100 G:100 B:100). They become “white”, but have a faint flicker. Other, non-linear, combinations work great, and max 255 on RGB returns a nice white.

Does anyone have any ideas what is causing this? My goal is to have the ability to produce faint “white” on each pixel, sans flicker.

This flicker happens when you’re not talking to the LEDs? If so it may just be the LED’s internal PWM frequency is too low - not seen that myself though - or that your power supply is oscillating a bit?

Correct, they flicker when I’m not sending anything. Also, I tried three different power supplies, two with sufficient current and one that doesn’t. The flicker (again, only when displaying all “white”, non-255, values) was reproduced with all three.

However, I found that if I put the LEDs at low enough RGB values (<15) the flicker either disappears or is too faint for me to notice.

Is there a way to adjust the PWM via the Imp? I’ve done it with standard LEDs, but not via SPI.

No, the PWMs on those LED controllers is within the controller; you just send the requested output value - but generally it should be too fast to notice.

Maybe the controller has some undesirable behavior when RGB are all set at the same level (though I’ve never seen this myself). If you do, eg, 100, 101, 100 does it still flicker? How long are the wires from the PSU to the LED strip?

Ah, good idea. Was away this weekend, but I can confirm that it still flickers with the values 100, 101, 100 (or similarly close, yet high values). The wire from PSU to strip is around 4 feet. Ordered another quality power supply to use as a control. We’ll see if that does it. Until then, I’ll keep using low values.

And pardon my unfamiliarity with the code, but could someone show me how to execute the sample code (from Peter’s link above) that would send values to the strip (i.e. const setup_params = “\x55\x23\x11\xff”;). More specifically, when I send the values through the blob (about half white, half green) the instance I get in the log is 0x0x20010208. I assume this is the value I would need to send to achieve the same result as the for loop I’m using.

It refers to using a table in the example. So would this be the means by which one would send these values? And would it just be something like hardware.spi257.write(ioexpander1) or am I way off? Thanks!

Could you post your code? The example Peter linked to was for animated LEDs and so does some gymnastics with the rgb values to make them cycle.

If you have static values you can encode them as a string and send that. eg:

hardware.spi257.write("\xff\x00\x00\x00\xff\x00\x00\x00\xff");

…in place of the blob creation code should give you one red, one green and one blue pixel.

That’s exactly what I needed. I was complicating the matter far too much in my head.

Substituting your code in place of the blob allowed me to submit the direct values I needed without having to iterate through every time. Thank you!!

I got to play with my new LED strip (this one) this weekend and here is some code I’m working on right now. Feel free to comment/clone/work on the gist!

Next goal is to add http in capabilities for my fancy LED strip.

https://gist.github.com/ejeklint/4714653

Cheers,

Per

You are my hero, Per. That code is really fun to play with. I have the same strip, but with 25 pixels. Going to toy with it a little later and try and see if I can get it to do some more effects. Particularly, have it repeat a “rainbow cycle” of just red/orange colors down the strip, for example. Any input on how to achieve this? Will report back.

Thanks again!!

Glad you like it! I’m working on a better version and a reasonably easy way to control it over the net. The code is here on Github if you want to keep an eye on how’s it progressing. I will continue to work with it tomorrow.

Cheers!

One thing I can’t figure out is how to break out of a for loop on an InputPort request.

If I have the strip cycling through colors for a set amount of time (from HTTP in), I can’t get it to break from another HTTP in.

Trying various methods, I see that the HTTP in doesn’t even log as received until after the prior loop completes.

The only way I can think of getting around this is a “fake” loop within that keeps iterating with until n=desired loops.

Basically:

`function something(){
if(inhibit){
return;
}

else{
…do something…
if (n<5){
imp.wakeup(0.001, something);
}
n++;
}
}`

I haven’t actually tried this, but I’ll get some sleep and try it first thing. Just wanted to know if anyone knew of a clean way to break out of a loop with HTTP IN.

Thanks!

The “fake loop”, made using imp.wakeup, is the right way to do this – for exactly the reason you point out. InputPort events only happen when Squirrel is otherwise idle, so each time you’ve updated the strip you should set an imp.wakeup and drop out of Squirrel altogether so that event handlers run. The same would be true for input-pin events. There’s no point in updating the strip faster than the human eye can follow it, which is going to be at most 100Hz.

Peter