Using WS2812 with LoPy
I'm trying to drive a 10 leds ws2812 strip with my lopy and I'm kinda stuck. I was looking for a library which was taking the programming work of me. I came across this github project https://github.com/aureleq/wipy-lopy-WS2812 which sounds quiet promising. However I did not succed in getting the leds to show anything. My code looks like the following:
import pycom import time from ws2812 import WS2812 print("Disabling heartbeat") pycom.heartbeat(False) chain = WS2812( ledNumber=10, dataPin='P22' ) # connected to G9 on extension board data = [ (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), (255, 0, 0), ] while True: chain.show(data) time.sleep(4)
Does one already have some experience with this library? Is there a better alternative? Thanks for your help!
I'm not one to grave-dig old topics, but this one isn't that old and seems to turn up in Google for searches about using WS2812 pixels with WiPy/LoPy etc.
Upon looking into getting our WS2812-based products up and running with WiPy I came across the libraries listed here, but upon further testing I found some pretty severe problems with how they work.
Both of the linked "wipy-WS2812" codebases suffer the same issue; they claim to pack 2bits per byte, when they actually pack 1 bit every 2 bytes and discard half the bits. Running tests that sweep the full range of intensity for any colour channel pretty quickly showed this up.
Another example I found for generic MicroPython boards (uses
pyb.SPIwhich I believe is either an old paradigm, or one the Pycom does not follow) managed to get the bit packing correct, but failed to disable interrupts. It would update ~8 pixels before an interrupt fired and caused a delay in the SPI output long enough to count as a WS2812 reset.
I took the best of both of these examples and merged them into this: https://github.com/Gadgetoid/wipy-WS2812/commit/4288b4b782040053fcfec86fa7644dbec3ceab76#diff-62a17d14021710b4dc4370f193749d1f
Much kudos to whoever came up with the 2bits per byte packing optimisation- it's elegant, even if it makes the code ugly.
I have tested my code up to 32 pixels on a WiPy 2.0 board, using the SPI MOSI pin (labelled G22 on the breakout) and verified with an oscilloscope that the signal is consistent and uninterrupted.
Hopefully someone will find this useful.
@binux I had the same thought a while back. The code that drives the single status LED should be fairly easy to expand to support a string of LEDs. And doing it that way would save the SPI port for "real" SPI stuff. I think it would be a nice feature.
@jmarcelino I ask myself why the pycom led library does not offer the option to control a WS2812 strip. I mean they have one mounted on the PCB a change to support a led strip seems minor to me. Looking forward to know your results on Wednesday
Yes something changed, I couldn't get that library to work for me yesterday. Seems that now when ports are set as SPI you can't do PULL_DOWN as the code is doing.
I'm away from any WS2812s or test equipment until Wednesday so can't really help with this until then.
@jmarcelino, that library is not working for me. The LoPy SPI 0 port is on P11 I believe, not P22. Even with the change of pins, I have not been able to get an 8-led unit going.
I tried. Nothing happened. I used the test.py from the github project.