Moderators: adafruit_support_bill, adafruit

// This is how data is pushed to the strip. Unfortunately, the company
// that makes the chip didnt release the protocol document or you need
// to sign an NDA or something stupid like that, but we reverse engineered
// this from a strip controller and it seems to work very nicely!
void LPD8806::show(void) {
uint16_t i, nl3 = numLEDs * 3; // 3 bytes per LED
// write 24 bits per pixel
if (hardwareSPI) {
for (i=0; i<nl3; i++ ) {
SPDR = pixels[i];
while(!(SPSR & (1<<SPIF)));
}
} else if(slowmo) {
for (i=0; i<nl3; i++ ) {
for (uint8_t bit=0x80; bit; bit >>= 1) {
if(pixels[i] & bit) digitalWrite(datapin, HIGH);
else digitalWrite(datapin, LOW);
digitalWrite(clkpin, HIGH);
digitalWrite(clkpin, LOW);
}
}
} else {
for (i=0; i<nl3; i++ ) {
for (uint8_t bit=0x80; bit; bit >>= 1) {
if(pixels[i] & bit) *dataport |= datapinmask;
else *dataport &= ~datapinmask;
*clkport |= clkpinmask;
*clkport &= ~clkpinmask;
}
}
}
// DELAY IS HERE
delay(2000);
writeLatch(numLEDs); // Write latch at end of data
// We need to have a delay here, a few ms seems to do the job
// shorter may be OK as well - need to experiment :(
delay(pause);
}
Safarir wrote:At first, I tought it was my code the problem, because I wrote it from scratch, but I also try with a arduino nano, and I get the same behavior.
#include "LPD8806.h"
#include "SPI.h"
// Example to control LPD8806-based RGB LED Modules in a strip
/*****************************************************************************/
// Choose which 2 pins you will use for output.
// Can be any valid output pins.
int dataPin = 2;
int clockPin = 3;
// Set the first variable to the NUMBER of pixels. 32 = 32 pixels in a row
// The LED strips are 32 LEDs per meter but you can extend/cut the strip
LPD8806 strip = LPD8806(4, dataPin, clockPin);
// you can also use hardware SPI, for ultra fast writes by leaving out the
// data and clock pin arguments. This will 'fix' the pins to the following:
// on Arduino 168/328 thats data = 11, and clock = pin 13
// on Megas thats data = 51, and clock = 52
//LPD8806 strip = LPD8806(4);
void setup() {
// Start up the LED strip
strip.begin();
// Update the strip, to start they are all 'off'
strip.show();
}
void loop() {
strip.setPixelColor(0, strip.Color(127,127,0));
strip.setPixelColor(1, strip.Color(127,0,127));
strip.setPixelColor(2, strip.Color(0,127,127));
strip.setPixelColor(3, strip.Color(127,127,127));
delay(2000);
strip.setPixelColor(0, strip.Color(0,0,0));
strip.setPixelColor(1, strip.Color(0,0,0));
strip.setPixelColor(2, strip.Color(0,0,0));
strip.setPixelColor(3, strip.Color(0,0,0));
delay(2000);
}driverblock wrote:How did you declare your LPD8806 object? Number of pixels, data and clock pins, etc?
I can't diagnose the issue without any details.
Safarir wrote:line #15 of the code i just post ?
driverblock wrote:Safarir wrote:line #15 of the code i just post ?
Ah - from your video, I thought you were using hundreds of pixels.
OK, so you see the issue with 4 pixels and software SPI. I'll investigate
pburgess wrote:Okay, I've had a moment to mess around with this...
Keep in mind that we don't have a datasheet for the LPD8806; the library was developed through reverse engineering and there are some huge gaps in what we know about this chip.
But yes, near as I can tell now, this is not a bug but a "feature" (ironic quotes) of the LPD8806...if the serial clock is interrupted for too long a period (I don't know the exact length, have gone as low as 100 milliseconds and still observed the phenomenon), then as a failsafe of sorts the LEDs will interpret the last byte received as the latch (which is why the last LED in the strand isn't displaying the right color...the latch byte is eaten, not displayed).
So, moral of the story: don't put a delay before the latch...always issue it immediately following the data, and handle any needed delays elsewhere.
If you're worried about keeping your LED timing consistent (e.g. using a timer interrupt so they always refresh at something like 50 Hz), it's not a problem. The number of cycles spent issuing data is deterministic, and the latch will always occur at the desired interval, just slightly offset from when the interrupt actually fires.
pburgess wrote:Part of the problem is that the LED driver isn't really a shift register, but we've been relying on shift register terminology because it's the closest thing we have. And that's kind of thrown off my impression on how these things work. But you're right, there isn't really a latch (it's more like a counter reset operation).
Also interesting to note that the LEDs display color data as it arrives, NOT actually at the so-called "latch" signal...but each color byte isn't shown until the NEXT byte of data arrives. I'm not sure why it works that way, but it does, and I think this is the phenomenon you're seeing.
Return to Glowy things (LCD, LED, TFT, EL) purchased at Adafruit
Users browsing this forum: mibignistinly and 4 guests