-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rp2040 -- neopixels not working properly #4135
Comments
I ran some test when I set up the PIO writes manually, so not using neopixel,py ot neopixel_write and I can reproduce the same behavior when trying to set individual pixels. It is odd -- some programs using .fill seem to be working and the "color wheel" seems t work OK but when I try manually poking a pixel or manually setting fill, I get these odd responses. |
Can you capture the pulse train with a logic analyzer and verify the 1/3 and 2/3 duty cycle? |
Just to add some support to this case, my Pico just arrived today and I immediately hooked it up to an "official" Adafruit neopixel ring (16 pixels). With the example code supplied and minimal modification, I get a random selection of colours all over the ring and a number of points not illuminated (I had the same issue with a simple strip and a cheap 8 pixel ring from Aliexpress). I also tried using GP1 instead of GP0 just to be sure it wasn't pin weirdness. My code:
Obviously, I would expect to see an all red ring, but instead I get a lot of what feels like random noise. I've put an image on imgur so you can see the behaviour. I'm not super technical (a dirty hacker at best) but please let me know if there is anything I can do to help debug. |
I'll try to do this tomorrow. |
Quick update from me, on a whim, I tried unplugging the Pico from my Mac (2020 16" MBP) and plugging it directly into a power strip on my desk that has USB ports and it started working as intended. I don't know if this is helpful, but perhaps @jerryneedell you could try as well and see if it starts working for you? |
could be the VBUS voltage is too high. try powering the pixels from 3.3V |
I've tried 3V -- same result. |
I did some tests with a logic analyzer. In general, the timing looks ok for the 1/3 2/3 duty cycle BUT there appear to be "gaps" on some of the writes. This may be causing the odd behavior The second screenshot was a capture while running the "color wheel" -- the gap is not present on every write. I see the gaps very often when I am writing single values -- When running something with lots of writes, they are less frequent and the string appears to behave "better" If I run the same tests on a metro_esp32s2, I don't see the gaps and the neopixels behave normally |
I don't have a full answer yet but looked into this a bit further. I used neopixel_write to write raw to the string (skipping the neopixel library). What I noticed is on the RP2040 the first byte of the array being sent to the string wasn't always sent correctly, resulting in the rest of the pixels being incorrect. E.g. If I sent 0xFF, 0x00, 0x00 (GRB order so a green pixel) there are times I would not see the first pixel light up (or just flash quickly on/off). If I sent 0x00, 0xFF, 0x00 (so a red pixel) the first pixel would sometimes light up green. Meaning that first byte of the bytearray had been lost. Using the full library it seems to occur on the first display after a "while" (not sure how long). So I may fill a string with blue pixels and the first couple showed red - meaning the green first byte was lost. The last pixel is showing a mix of Red/Blue (maybe an artifact of being a byte short). Another thing I am unsure on is the CP PIO program uses different timings then the PIO used in the RP2040 example code. May be unrelated and may not matter at all. But it does seem somehow the first byte to the neopixel string is being "lost". I'm just not sure how yet. |
I think I have it solved. I noticed the problem only occurred when the transfer was smaller then the amount to use DMA for in StateMachine.c (32 bytes). In the non-DMA transfer part of the code after each byte is written "RUN_BACKGROUND_TASKS" is ran. It seems that most times after writing the first byte there were background tasks to be ran, delaying filling the TX buffer and throwing off the timing. That would explain the random pauses seen. One solution is to run The other option is to remove running background tasks while small transfers in the state machine are required. Many may run at frequencies higher then the 800kHz of neopixels so I can see that throwing off the timing very easily. I will submit a PR with the first change. Should the tasks be ran in that time period can be a bigger topic. |
Ah -- that makes sense -- so when working with any string > 10 pixels and setting them all, the problem will not occur -- This explains why it was working so well with the 16 pixel ring but I started having issues with the 7 pixel jewel, and when testing writes to single pixels. I would remain concerned if there is a known likelihood of failure during the 40 microsecond window. It will happen at the lest opportune time ;-) |
I tried this on a Pico, unfortunately it is not resolving the problems -- still getting some odd behavior especially for the single writes. |
I am still seeing an issue so there is another timing issue as well. I tried the following to ensure DMA is being used:
While this runs I notice the last blue pixel will dim at times (missing the LSB I'd assume) and the first pixel lights up bright green (getting those missing bits on the high side). If I alter the delay in the sleep it will not happen. I do not have a scope so I'm just about at the end of what I can try without being able to easily see the output on the wire. Something is delaying a write near causing the neopixels to think they are seeing a new set of values. |
@jerryneedell noticed that this problem affected strips short enough to not use the DMA peripheral, thanks for the hot tip! Instead of checking for background tasks after every byte transfer, try up to 32 transfers before attending to background tasks. This fixes the problem I was seeing on my 5-pixel circuit. Closes adafruit#4135.
I am having trouble controlling neopixels on a Pico when using the neopixel.py libray
Here is an example
The text was updated successfully, but these errors were encountered: