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
NeoPixel: Add invertedDIN option to use single transistor driver. #8037
Conversation
Here is an example code (taken from https://github.com/micropython/micropython/blob/53145c4c5f10c3e44ffe174b1e6968792f17ea3a/drivers/neopixel/neopixel.py) that was used to create this patch on ESP32 with generic MicroPython
|
* Patch allows using single transistor (i.e. IRLML6344) to drive WS2812B. * Transistor is required for MCU 3.3V signals to drive 5V WS2812B. * Inverted DIN and bistream hi-to-lo only is compensated by timings. * No underlying driver code is touched. * Please verify on your hardware. How compensation timings were calculated: ``` STREAM: 11001010 BUS: 110 110 100 100 110 100 110 100 LET: A B A B CD CD A B CD A B CD INV STREAM: 00110101 INV BUS: 001 001 011 011 001 011 001 011 INV LET: D C D C BA BA D C BA D C BA ``` Signed-off-by: Tomasz 'CeDeROM' CEDRO <tomek@cedro.info>
12ec6b1
to
477f217
Compare
Thanks @cederom Generally I always prefer to use buffer (e.g. 74AHCT125 or similar) but I agree supporting simpler level shifting would be good. My inclination is to either push this into the driver (i.e. add FWIW, we've tried to push the code and bytecode size of neopixel.py down as much as possible, hence why there are some weird stylistic things. Here's a sketch of what neopixel_inverted.py could look like... import neopixel
class NeoPixelInverted(neopixel.NeoPixel):
def __init__(self, pin, n, bpp=3, timing=1):
super().__init__(pin, n, bpp, ((850, 400, 450, 800) if timing else (1700, 800, 900, 1600)) if isinstance(timing, int) else timing))
def write(self):
self.pin.value(1)
super().write()
self.pin.value(1) We could provide that next to the existing (frozen) neopixel.py and then add a note to the docs to copy over neopixel_inverted.py to the filesystem if necessary. |
Awsome :-) Thanks for your hints @jimmo :-) I also considered Thus comes my experiment with observing the signals after inversion, and it turns out that when these inverted signals are generated by MCU with existing I am working on a board at the moment with complementary N+P MOSFET in TSOT-23 package to see if output of the voltage level translator works correctly between 3.3V->5V without logic inversion. Then I would verify if both software implementations work exactly the same in N+P and single N configuration. I am somehow afraid that one bit may be missing.. but colors and intensity seems to be generated correctly "by naked eye". Another test I can think of is to put one oscilloscope channel before first LED and second channel after first LED then compare. If you have other ideas on how we can verify this please share :-) Even if there is one bit missing (hopefully LSb), it is enough for most applications and benefit of having only single cheap tiny N-MOSFET transistor seems to outweights the potential resolution loss. But we should clearly state that something like this takes place if it is :-) As you are far more familiar with the MicroPython architecture and if you have time you can freely put necessary changes on top of my commits (then squash everything if necessary) so they have perfectly small footprint and matches internal coding standards :-) Thank you for MicroPython! I am really impressed how well it works and how much time it can save for rapid prototyping.. where time is most precious. I am working on ESP32 and ESP32-C3 (RISC-V) so they are cheaper and more resourceful than ARM anyway :-) |
I'd definitely recommend taking a look at a dedicated level shifter part rather than DIY with mosfets. They will typically have schmitt trigger inputs, and are still fairly cheap. Also like you say, WS2818 are far more sensitive to timing than voltage and in many cases the level shifter is not necessary (3.3V io is just on the borderline. 3V is more likely to lead to issues). The other trick is to have a "sacrificial" first WS2818 which is powered one diode-drop below 5V (i.e. 4.3V), and essentially serves as a level shifter to the rest of the strip. See https://hackaday.com/2017/01/20/cheating-at-5v-ws2812-control-to-use-a-3-3v-data-line/
I did all the testing for the current driver with a logic analyser. You could use your scope for the same purpose. |
My preference for this hardware problem is a hardware solution: using a proper level shifter, like a TXB0101 (https://www.ti.com/product/TXB0101). You can of course use a 2 transistor logic as well, if that meets the timing requirements. |
I prefer generic parts. In times where supply chains are noticeably disturbed this is important :-) In my design I was using new component that got marked EOL around May 2021 because factory in Texas and Taiwan was closed.
No need to "sacrifice" any components. I saw that page thanks :-) Also saw the HCT ICs examples. My solution works using cheap tiny generic transistor that fully opens around 1V (starting at 0.5V) thus it also works well in battery powered applications when voltage shifts down from stable 3.3V :-) |
Thank you for TXB0101 hint @robert-hh! This is also SOT tiny device.. but its 10x more expensive than N-MOSFET and 5x more expensve than N+P MOSFET.. also this is not a generic-trivial-to-replace-part what is important because availability may be impacted as explained in my previous reply :-) |
Closing due to inactivity. @cederom If you want to go ahead with this, I think adding a separate That said, I can't convince myself that just transposing the high/low times actually does the right thing here. I think it works because the neopixels are quite forgiving and mostly it's just the high time that matters, but I don't think if you looked at the signal on the output side of your level shifter n-mos it would not match the expected timing. Would be curious to see if this works for neopixel-like devices with different timing (e.g. SK6812). |
Thanks @jimmo for your time! :-) Actually WS2812-MINI accepts DIN voltage levels from 2.7V so no inverter and/or level shifter is really necessary and I am using native implementation from 1.19 on ESP32 :-) In a free moment I will dump signals both from DIN and DOUT and put here just out of curiosity. I do not have SK6812 at hand but when I get one I will also try out that one :-) This is not a priority anymore and in some cases even not necessary - some WS2812 can be driver straight out of the 3.3V MCU so swap in BOM seems most sensible solution.. world would have been much easier if all of them could work that way out of the box :-) |
fix to make buttons and leds compatible with pca10056
How compensation timings were calculated:
Signed-off-by: Tomasz 'CeDeROM' CEDRO tomek@cedro.info