Testing level shifters for running Adafruit NeoPixel strips from a 3.3 Volt Teensy

If you’re running NeoPixel LED strips off a Teensy 3, maybe because you want to put 180 LEDs on a hat, then you need a level shifter. But which one? The NeoPixel data protocol is high speed and pretty harsh on timing requirements and I’ve had a bugger of a time getting reliable data from the Teensy to these strips. Hence I’ve tested a bunch of shifters. I tried a TXS-0102, TXB-0108, 74HCT245, PCA9306, and a MOSFET based shifter.

The Teensy outputs data at 3.3 Volt, the strips expect 5 Volts. Or rather, the strips might see 3.3 Volts as a digital 1 or they might not. If you want some reliability, then you’re better off shifting the Voltage level up to 5.

Each LED reads the data it needs and passes on the rest, regenerating the signal to nice square pulses, so there is no decline in signal quality along the strip. Well, that’s the theory. In reality, all sorts of weird failure modes can happen.

Anyway, short conclusion from this testing is: use a TXS-0102 shifter if you’re tight on space and running one or two strips, use a 74HCT245 if you’re not or you are running three to eight strips. The 74HCT245 was the only shifter to give perfect performance, everything else had some kind of problem.


Test set-up is as simple as I can manage; DC wall power, Teensy 3.0, shifter, and short wires to a 36 LED length of 60 per metre black NeoPixel strip. These use the WS2812B LEDs and seem more sensitive than the other NeoPixel strips. I’ve been referring to this particular test strip as the grumpy strip, coz it seems very touchy, throwing its toys if there are poor connections, poor Voltages, bad data timing, or the phase of the moon is wrong.

DSS Circuits have a dinky TXS-0102 based shifter. Small, autodetects direction and only US$ 3. Good square pulses and simple to wire up.

This gave some flickering on the first LED, but the rest of the test pattern displayed fine. It didn’t flicker when I tried it with several different white test strip.

The TXB0108 based shifter from Adafruit handles eight lines and auto-detects direction, so that’s one less pin to worry about. Scope pic looks good, but the first LED didn’t light at all. The rest were fine, which is odd, as good data is clearly coming out of the first LED, even if it isn’t responding to the data going in.

The 74HCT245 is recommended by people who know what they’re talking about. It was the only shifter I tested that didn’t have a problem with the grumpy strip, reproducing the test pattern perfectly. Good sharp edges and flat tops. There’s some ringing after the pulse edges, but that’s because this is the only shifter that I didn’t test on the breadboard. This was soldered into the Hat driver and pushing signals down a metre-long cable, hence the ringing.

It handles eight channels, if that’s what you need. Also, it’s DIP and has pins for setting the direction, hence it’s fairly large.

Sparkfun provide the PCA9306. I’ve used this successfully to run the 5 Volt I2C components in the Mitochondrion Mark 4. It’s great for I2C as it has pull-up resistors on the breakout board. However, it really can’t handle the 800 kHz signal here. Those leading edges are horrible. The strip didn’t like it either, just occasional flickers and nothing more.

Sparkfun also produce a MOSFET-based logic level converter. I’m sure it’s good for slower signals but it can’t cope with the NeoPixel data. The scope trace is crap and the LED strip produced nothing at all, not even a flicker.

So I hope that helps with your level shifting adventures.

11 Replies to “Testing level shifters for running Adafruit NeoPixel strips from a 3.3 Volt Teensy”

  1. When we have fast signals where we need good tracking, we use an LT1715, which is not the most pleasant package to solder down, and has some slightly funny layout requirements, but it’s really fast.
    I’ve been playing a lot with a teensy 3.1 lately, mostly with its d2a output.

    1. That is indeed very fast, although I don’t know enough about comparators to know one would be more effective than the TXS-xxxx chips. I mean, they’ve got “output one-shot edge-rate accelerators”. That sounds pretty cool, although I’m only guessing at what they do and whether they need to do that or not.

  2. The CMOS level shifter uses a BSS138 with 10k pullups. The reason it won’t work isn’t the CMOS. It’s the RC time constant of the pullups and the trace capacitance. Most uC’s can sink or source ~20mA, so re-sizing the pullups to 820 ohms or so is still safe and gets the time constnt to <0.1us or so where the NeoPixel needs it. I have a NeoPixel ring working flawlessly with this solution and no flicker or first pixel issue.

    1. Hmm… I don’t doubt that’s a strong factor, especially as the on/off time on those MOSFETs is in the tens of nanoseconds. I’m a little confused why I got the shape of the traces that I did, it’s not the classic RC time constant curve.

      But hey, if it works, then it works.

  3. With the 10k pullups in place, it was taking my circuit ~1.2uS to reach 5V. My scope trace looked like yours, but when I put a 100kHz square wave, I could see what was going on. The voltage rise to 3.3V was very sharp and then it would have the characteristic RC curve to 5V. I used the measured curve to re-size the pullups and then went back to the NeoPixel code with good results.

  4. Also, add a 330 pF capacitor to the low Voltage side of the level shifter.

    I’ve been getting some flickering with one of the 144 per metre WS2812B strips from Adafruit, running off a Teensy via a 74LVC245 level shifter. The flickering stopped when poking the data line on the low Voltage side of the shifter. Instead of just swearing, like I usually do, I thought – well, the scope probe probably has some capacitance so how about I just chuck a cap between the data line and ground and see what happens?

    A quick test revealed no flickering at 330 pF, some at 680 pF, more at 1 nF, and pretty awful at 3.3 nF. Looking at the pulses on the scope and there’s not much difference between a 330 pF and no cap. With no cap there’s a little bit of ringing at the pulse corners, but nothing that looks bad. So I’m at a slight loss to say why this might work, but it works.

  5. The DIN needs to be 90% of VCC. I am going to try running VCC through the same BSS138 MOSFET as the DIN line.

    Has anyone tried that? The theory is that the max level, not the slope is also important if not more important.

    1. Clarification: Not the exact same MOSFET. 1 on the VCC line, one on the DIN line. That way DIN high will be 100% of VIN as seen at the WS2812B

  6. A simple trick to achieve this is to reduce the power supply to the first NeoPixel.
    The data signal HIGH should be 70% of the input voltage, if you reduce the supply to 4.3V by adding a diode to the first NeoPixel power supply, 3.3V will be see as a HIGH signal.
    And each Neopixel “rectifying” the data signal before sending it to the next, this first pixel will increase the data signal to 4.3V allowing the next pixel to work at 5V šŸ™‚

    Original source of this trick is to be found here:
    http://www.electrobob.com/ws2812-level-translator/

Leave a Reply

Your email address will not be published. Required fields are marked *