New _pixelbuf based Neopixel object does not allow updating .buf
sta-c0000 opened this issue · 13 comments
ref: pull request #59
Before we could update pixels.buf
(Neopixel obj) directly, but it does not work with new _pixelbuf
based Neopixel
.
Now it returns an error:
>>> type(pixels.buf)
<class 'bytearray'>
>>> pixels.buf = b'\x01\x04\x00\x01\x04\x00\x01\x04\x00\x01\x04\x00\x01\x04\x00\x01\x04\x00\x01\x04\x00\x01\x04\x00\x01\x04\x00\x01\x04\x00'
AttributeError: 'NeoPixel' object has no attribute 'buf'
Simple example for circuitplayground that works with current releases using old Neopixel
object not using _pixelbuf
:
from random import randint
import board
import neopixel
pixels = neopixel.NeoPixel(board.NEOPIXEL, 10)
pixels.buf = bytearray(randint(0,255) for i in range(30)) # <=- now fails
pixels.show()
Thank you.
Sigh. This is the kind of thing that I wanted to find with testing before merging to master. I feel like we rushed merging the pixelbuf changes. This is fixable but might have slight performance penalties until I make changes to _pixelbuf to allow changing the underlying bytearray.
there's no way to really find these sorta bugs without a lot of eyeballs lookin at em :)
Ya, no worries dude. All things considered IMHO it's better to keep up the momentum and get it out and tested more widely than sitting on it making sure it's ISO certified
@sta-c0000 Do you ever directly manipulate buf
with subscripts or slices?
@rhooper while it's perhaps a decent use case, it's maybe worth considering if accessing buf
directly is/was an intended part of the API or not.
@siddacious I'd say that providing your own buffer is the right approach. As this breaks backward compatibility, a (deprecated) buf
property along with new kwargs to pass in buffer(s) would be the best approach.
I'll post examples and a PR soon.
@rhooper No. Subscripts work now (pixels.buf[0] = 3
), but I haven't used. I don't think you can modify slices now... just tested:
pixels.buf[:3] = b'\x04\x00\x01'
TypeError: 'bytes' object does not support item assignment
Would need to do (but would have your bytearray already):
b = bytearray(pixels.buf)
b[:3] = b'\x04\x00\x01'
pixels.buf = b
As for siddacious's comment: I imagine direct .buf access is not very common.
I'd rather not support direct .buf
access because it can be done with a raw bytearray
and passing it to neopixel_write
directly.
@sta-c0000 You're right on the bytearray (which _pixelbuf uses).
The reason for the issue with assigning to buf
is that there is no setter on the buf
property of _pixelbuf (yet). I've filed issue adafruit/circuitpython#2502
You might want to work with a _pixelbuf directly if you're already mucking with .buf
, like @tannewt suggested.
Nevertheless, I'm going to submit a PR that adds the ability to pass in your own bytearray buffer(s) to NeoPixel so you can do what you're doing another way:
import board
import time
num_pixels = 32
buffer = bytearray(32 * 3)
pixels = neopixel.NeoPixel(board.D6, num_pixels, brightness=0.1, auto_write=True,
pixel_buffer=buffer)
pixels.fill((128,128,128))
pixels.show()
buffer[:] = bytearray([((i % 5) * 10) for i, _ in enumerate(buffer)])
pixels.redraw()
pixels.show()
Issue was primarily discrepancy with previous NeoPixel obj noticed while testing. I don't know, but perhaps .buf
write can indeed be deprecated?... feel free to close this issue once noted if so.
Direct bytearray
neopixel_write
sounds like a reasonable workaround.
edit: in fact I'd like to close since being pointed in that direction, is faster; e.g. fast cycling (where our buf is filled bytearray):
while True:
neopixel_write(pin, buf)
buf = buf[-3:] + buf[:-3]
...
Thanks again!
@sta-c0000 I think you can close the issue.
You might also find performance of using NeoPixel with _pixelbuf and slices with integers similarly fast and possibly easier to work with. I'd love to chat more about what you're doing sometime - perhaps on discord? https://blog.adafruit.com/2017/07/20/adafruit-is-on-discord-discordapp-adafruit-discord-adafruit/ where you can find me as krayola. Your use case might give me more inspiration for ways to speed up or make _pixelbuf better.
Yes, only starting to play with the new _pixelbuf and NeoPixel functions like .fill are leaps and bounds faster, which is great. Closing, thanks!