Closed jmb closed 7 years ago
This might be a bit out of scope or implemented clumsily, but I've started this request in case it is useful.
Hmm, I assumed that the buffer is still usable after calling spi.xfer, and could be reused. That's why there is a clearStrip method, so that one can start with a fresh buffer if desired. Why do you think a copy is required?
Hmm, when I tried it seemed to clear the buffer. Let me try again...
Ok, thanks! As I say: I assumed, but never tested my assumption ;)
Here is what I'm trying - using the python console for ease of testing...
>>> import apa102
>>> strip = apa102.APA102(numLEDs=60, globalBrightness=5, order='rgb')
>>> strip.leds
[229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0, 229, 0, 0, 0]
>>> strip.setPixel(30, 255, 0, 0)
>>> strip.show()
>>> strip.leds
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
>>> strip.setPixel(30, 0, 255, 0)
>>> strip.leds
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
>>> strip.show()
>>> strip.leds
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
After I try and re-set pixel 30 from red to green and then call strip.show()
the second time, the first LED lights up green and the 30th stays red. It's quite likely that I've missed a step and this pull request isn't necessary!
Your observation matches the buffer content 100%: One can sent as many zeroes as one likes to the strip, and nothing happens. As soon as the first "pixel start" command is sent (the start frame), the first pixel sets its color. So, the first pixel is green (after many zeroes, a start frame and the color green arrive), and pixel 30 remains red, because no command reaches LED 30 to change anything. So apparently the buffer gets cleared, I just wonder why...
I guess it's something to do with the self.spi.xfer2(self.leds)
call - hence my idea to copy the buffer to it rather than pass a reference. I guess both ways of working are valid, depending on what you want to achieve! :)
I just spent an entire afternoon debugging a problem with the rotate() method and finally found that spi.xfer kills the buffer. Then I came back to review the open requests and found our discussion. Now I feel a bit stupid... Anyway: I have to reject your pull request, because I already fixed the same problem...
Oops! Your solution looks better though - no need to create a copy of the buffer! 👍
By sending a copy of the pixel buffer to the SPI device, we can update individual pixels rather than having to set the entire buffer from scratch each time show() is called.