Cheating At 5V WS2812 Control To Use 3.3V Data

Schematic of Diode Level Shifter for WS2812

If you’re looking to control WS2812 (or Neopixel) LEDs using a microcontroller running at 3.3 volts, you might run into some issues. The datasheet tells us that a logic high input will be detected at a minimum voltage of 0.7 * Vcc. If you’re running the LED at 5V, this means 5 V * 0.7 = 3.5 V will be needed for the WS2812 to detect a ‘1’ on the data line. While you might get away with using 3.3 V, after all the specification in the data sheet is meant to be a worst case, it’s possible that you’ll run into reliability issues.

So usually we’d say “add a level shifter to convert 3.3V to 5V” and this post would be over. We even have a whole post on building level shifters which would work fine for this application. However [todbot] at CrashSpace came up with a nifty hack that requires fewer components yet ensures reliability.

bigbutton-front-backFor the Big Button project at CrashSpace, [todbot] used an ESP8266 running at 3.3 volts and WS2812 LEDs running at 5 V. To perform the level shift, a signal diode is placed in series with the power supply of the first LED. This drops the first LED to 4.3 V, which means a 4.3 V * 0.7 = 3.01 V signal can be used to control it. The logic out of this LED will be at 4.3 V, which is enough to power the rest of the LEDs running at 5 V.

This little hack means a single diode is all that’s needed to control 5 V LEDs with a 3.3 V microcontroller. The first LED might be a little less bright, since it’s operating at a lower voltage, but that’s a trade off [todbot] made to simplify this design. It’s a small part of a well-executed project so be sure to click-through and enjoy all the thought [todbot] put into a great build.

71 thoughts on “Cheating At 5V WS2812 Control To Use 3.3V Data

    1. I have. Funny (really, really funny) thing is the issue went away when the logic probe was connected. Since the original issue was primarily incorrect bit values, I would guess that it was rise time related with a near limit threshold. Why the problem went away with the logic probe connected really mystified me, as I would figure that to slow down the edge, but there are mysteries….. Bumped my supply to 3.6 and no more problem.

      1. I had exactly the same problem – when I connected oscilloscope probe, everything worked. Without the probe, data got lost and random colours appeared on the LEDs. To solve this problem, I cheated a little bit – I stuck a little piece of the ESD protective black foam (ICs are sometimes sold in it) between data and ground and the problem disappeared.

        1. We got the same problem with random LEDs lighting up in random colors on two diffrent projects. We did not use a level shifter and can’t get one in because there is just a tiny whole to the inside. Could you maybe explain how laying the foam between data and ground fixed the problem for you?

          This might still be possible for us and could rescue the projects.

    2. I just make a small experiment with two power supplies: lowering the supply of an Arduino Uno until the WS2812 start to make errors. When the WS2812 is powered by precisely 5.0V, it make error when the Arduino is powered below 4.1V. At 4.1V it work as expected and the oscilloscope show a signal with just 3.0V for the high level. Heating the WS2812 with a oven require an additional 0.1V on the Arduino power supply, but the change is very small on the oscilloscope. I would say that 3.1V high level signal seem to be safe for this particular WS2812. But is the WS2812 power supply is increased, the 3.0V high level signal is not enough anymore.

      So for simple systems where the 5.0V supply is precisely 5.0V or a bit less, 3.3V signal should be ok with about 0.2V margin. The is more complicated if the WS2812 supply is for example 5.25V, only 5% higher than 5.0V. For systems where power supplies are not precise enough, a level translator is a good idea.

  1. Nice one.
    I use a WS2812B stripe with 5V vcc and 3.3 data directly from an esp8266. The pattern updates approx. 10 times a second, and every few minutes or so there’s a visible glitch.

    1. Has anyone tested the dropout of the CCS on the WS2812? Nominally, if that circuit is working properly, the brightness should be roughly the same at 4.3V and 5V, actually, which makes this circuit even slicker than you’d normally think.

      The highest voltage LED is probably going to be 3.3-3.5V dropout worst case, so I’d imagine brightness on the WS2812, best case, will be constant for all supply voltages above 3.6V.

    1. I’ve tried a number of “simple” solutions, and other than slapping a single-gate 74HCT buffer, none of them were reliable enough. Single-transistor level converters are fine for slow I/O and even some slow serial comms, but are too slow for the 800KHz comms here.

      I have used a voltage-dropped pixel here, and it works well in this specific application. Can you provide examples of other level conversion methods you’ve used successfully with WS2812 pixels?

      1. A transistor will run at many MHz, faster than you will get data through WS2812, Just put an extra resistor between base and emitter as well as the resistor in series with the base.

        But still, for lower data rates I like the WS2812 as voltage translator idea and it saves a uC pin if used as a status indicator. I will have to buy some now.

        Nice trick, I do it differently –

        Most 3.3v chips are rated to run from 3.0v to 3.6v so I run then at 3.6v when they have to send data to 5.0v chips. This also improves the noise margin for LVTTL to TTL and makes LVTTL or CMOS (only just) work.

        I will goto ebay and get some of these. Any tips on what to buy?

      2. Unfortunately, a lot of people offering single-transistor solutions are either repeating a design they don’t understand, or don’t explain how to vary the parameters of the design. Typically you have to adjust the base resistor and collector resistor values to accommodate higher speeds – this is fairly basic analog design, but the gist of it is if your edges are not fast enough on the oscilloscope, reduce your collector resistor value. Power consumption is worse for your run-of-the-mill BJT single-transistor level shifter, but it’s not significant in lighting designs where your total LED power consumption is going to be on the order of 100s of mA.

        I was originally thinking the same as Capmo (lots of stupid solutions are often offered on the internet, and a single transistor design works in almost all cases except in the higher MHz range, or when power is important), but if you wanted to use the extra pixel anyway for indicator LED, this is actually a very elegant design – the original indicator LED would have been a resistor + LED, and now for the same component count you get a level shifter (with better edges and lower power than just a transistor driver), and a better constant current source for your LED than a resistor (I think most of these guys have a built-in moderate-quality CCS for the LED drive).

        1. What is missing here is the knowledge that a bipolar transistor has a parasitic capacitance between the base and emitter connections, so when you bias a bipolar transistor ‘ON’ you are also charging this capacitor and the end result is that then the voltage to the base is removed the energy in the capacitor takes time to dissipate so the transistor will switch ‘OFF’ very slowly as it slowly drops through it’s linear region.

          To solve this problem you need to place a resistor between base and emitter to bleed off this charge. You should also ensure that if you have series resistor from the drive or uC the the resulting divider will still allow at least 1 volt at the base.

          The collector resistor can also be reduced to about 1k Ohms.

          It seems that many are shy of bipolars and prefer FETs now and that is fine with the more specific FETs that have internal compensation for specific tasks. The reality is that generic FETs also have many parasitic qualities and because there are so many types of FETs there is consequently a lot of different combinations of parasitic qualities.

          On the other hand there are only two types of bipolar transistors NPN and PNP and both have exactly the same parasitic qualities even if the polarities are different.

          TLDR; FETs are not going to save you from picking up a calculator and doing some basic math so learn what needs to be calculated or get used to the sound of popping FETs.

          You “go to”s for bipolars are

          Vce: Voltage from collector to emitter. This should be higher than your Vcc or higher again for driving inductive loads or put a reverse diode from collector to emitter to shunt back EMF from inductive loads.

          Vbe: Voltage from base to emitter. Always around 0.6v for bipolar silicon transistors. Germanium transistors are about 0.2v

          Hfe: The AC current gain – need to drive 1Amp with a Hfe of 100 then you need 10mA of base current.

          Cbe: the capacitance between base and emitter. Even if it is not specified it still exists. Use it to calculate time delays and filtering properties or bleed resistors.

          Cob: The effective capacitance (after Hfe) at the output – collector.

    2. Fully Agree. However… the premise here is hacking, not engineering, hence “Hackaday”. The kids come up with some interesting stuff once in a while, albeit generally not for production grade work. This one is a useful hack as it solves a problem one can reasonably expect hackers to encounter with this device, but would get an engineer fired.

      1. That’s because you’re slamming it into saturation – from which it takes time to recover. Correctly biased with a gain of 5/3 you should theoretically be able to get a 180MHz 3dB BW.

        1. My gut analysis is that the limit in the design here is not the transistor. In this case it’s at least the 6.8kohm resistor, which is essentially a pull-up resistor forming an RC circuit with your WS2812 load capacitance, and cable capacitance. The WS2812 has a rated input capacitance of at least 15pF. This gives a corner frequency of 1.5MHz with 6.8kohm. It is probably lower becuase of the long cabling typically used for these LEDs. To get good square wave digital signals through, you will probably need a corner at least 10 times higher than the base square wave frequency – 800kHz in this case.

          You should also notice that the drive is asymmetric – that is, it should take substantially longer for the positive rise time than the negative rise time. That is because your BJT only actively pulls the line low, but passively lets the line float up. You might have noticed that I2C works in a similar way, with only active low and pull-ups. This is also why the standard tries to limit the maximum frequency to 400kHz – in most common setups, it becomes increasingly annoying to go higher than that.

          There’s also the effect that was described by RÖB earlier, which in this particular design may also be more substantial, depending on the exact transistor part number and how bad the line capacitance is. It should result in a similarly asymmetric output waveform. Now that I think of it, it may be more a large-signal manifestation of the Miller effect. Either way, needs to be considered.

          The real way around this is to make a totem pole output – two transistors, one PNP and one NPN (or p- and n-channel). This way, one transistor is actively driving/speeding up the positive-going edge, and the other is driving the negative-going edge. At this point, you’ve pretty much made what’s inside an older-series 7400 inverter, and you may as well buy an inverter IC…

  2. What about some simple pullup logic: Decouple the 3.3V data output with a diode (cathode pointing to signal emitter) and add a single pullup resistor to 5V? Disable the microcontrollers’ GPIO pullup, of course.
    I know an esp8266 doesn’t tolerate 5V (it would just see 4.3V), but after all it’s heat through power that destroys it, not voltage. If the current stayed low enough it should survive. The current needed to safely trigger the WS2812 should be less than the max. “low” output current of the 8266. The pullup R is dimensioned to safely fit into that gap.
    Would this work?

    Oh, just a thought on the sending microcontroller:
    The GPIO output might go low with its internal pullup enabled for some reason, thus increasing the L current (two pullup Rs in parallel). Without careful design software could fry the GPIO. Hmm, datasheets and calculations, maybe sacrificing one or two 8266s.

    Or just desolder a schmitt trigger bus buffer from some scrap pcb… ;-)

    1. I think that would work as well. It’s still one extra component compared to using a single WS2812 LED + diode. Keep in mind the pullup resistor value needs to be modified appropriately for the higher required speeds, probably to ~1k instead of the 10k you usually see. It’s a little tricky on the 3.3V end in terms of safety and tolerance; I sort of avoid this sort of situation if possible, but my understanding is some current will go through the ESD protection diode on the I/O, and if the leakage current is limited there will be no actual damage to the chip.

    2. i have done something simillar using a diode and pullup resistor but there is one big caveeat, during reset, startup, sleep, ect any current flowing INTO the input MUST be SMALLER then the total current consumed on that powersupply rail, including power LED ect, otherwise powersupply may “float up”. possibly causing a lockup or damage to something.

      my setup was using a diode to “pull down” the pullup resistor (using data). was connecting 5v CMOS logic output to 7.5v CMOS logic input and the sillicon diode-drop makes it work (at low speed) and yes i understand that the speed could have been increased with decreased pullup resistor value.

      logic went like this:
      7.45vCMOS low=4.5v
      logic LOW: 0 + 0.7 = 0.7
      logic HIGH: 5 + 0.7 = 5.7

      original problem was (other) resistive loads on data pins pulled microcontroller outputs down to less then 4.5, or at least pulled down the edges of the signals enough to corrupt.

  3. Maybe also qualify that this is if you only have 5v available. About a bazillion projects out there are running quite happily on lower voltages. A 3.3v controller and a lipo being a common choice for portability.

    1. This is exactly right. If you’re running WS2812s off a LiPo at 3.7V you don’t need this. If you have a 3.3V power source capable of driving all the pixels, you don’t need this. (Even though WS2812Bs are only spec’d down to 3.5V, many work okay if powered at 3.3V) This is for the case where: a) you only have 5V available, but b) your micro is 3.3V.

      1. You mean, those resistor values are too slow for the WS2812. The RC will set a corner frequency in the hundreds of kHz range (15pF max input on the WS2812, plus PCB parasitics, wiring, etc), and that’s not including gate capacitance, maybe some miller capacitance I’m missing, etc. If that circuit doesn’t work, try a 1kohm resistor first.

        The other thing is this looks like a bidrectional shifter. It’s a unidirectional line for the WS2812, so you can move things around and turn it into a fast open-drain driver with one R and one Q. Either way, I would say that in this particular design, if you were going to use an extra indicator LED anyway, the posted design is actually more elegant than using an additional level shifter.

  4. Actually, by accident, I found that WS2812B works from 3.3V supply and 3.3V data directly.
    A) Parallax Propeller + 5V PSU for LEDs. F**k the standards for data.
    B) Arduino Uno @5V data + 3.3V PSU for LED. Accidentally had 3.3V DC-DC step down converter instead of 5V. Can’t get full brightness.

    Without any level translation! It’s not good practice, but for standard nerds it will work.

  5. Glad the first line says “you may have an issue” since I have only used 3.3v data with WS2812s and have yet to experience any issues.

    However, to be a bit more accurate regarding the specs, you forgot to accommodate hysteresis. The WS2812 data sheet calls this out at 0.35v, so technically (by spec, your results may vary) a low-high transition will be seen at 3.85v. One could say that this hack actually proves that actual parts are “out of spec” since the hack presents a 4.3v VDD which means you have a 3.36v point for the low to high transition ((4.3v *0.7) +0.35) and that is still above the 3.3V data line.

    In any case, I would also suspect that the 3.3v data line concern is really only a problem when you are pushing the data rate near limits as well.

  6. I have long used a “sacrificial” WS2812 as a line driver when I need to have the LED string far from the controller. Without this driver, I found that I couldn’t have more than a few feet of separation (with ordinary crappy wiring, anyway), but with it I could get at least the ten feet or so that I need for some of my lighting projects. Actually, just the chip itself will work if you want to be minimalist, and you can buy those on little PCBs that don’t have an RGB LED installed.

  7. Hmm I haven’t had an issue using 3.3V logic to drive them. But this is a neat hack for sure. It’s probably working for me since my WS2812 is a couple cm away from the micro.

  8. I’ve figuerd out an easier solution that does work for me:
    When you power your wemos over the 5 volt pin (propably not recommended, yes) simply put a fordward based diode between the ground pin and the ground of your power supply. Due to the diode the low gpio state will now output 0.7 volts while the high state will output 4 volts. This is more than 3.5V (5V*0.7) for ‘high’ and still less then 1.5V (5V*0.3) for ‘low’.

  9. I have bookmarked this page in case I need it in the future. To be honest I’ve not had any issue until now and have made many D1 mini’s with 12 WS2812 leds directly connected to the 5v out of the D1 and one of the (3.3v) signal pins. The D1 gets its juice from the USB connector (5volt).

  10. I was wondering if anybody would mind helping me out; I have only a basic knowledge of electronics and almost no knowledge of programming (but am hoping to learn what I need for this project.)
    I am wanting to make a “smart hoop”, I already own one which cost me £190 and I would ideally like a set of 4, I don’t really want to spend that kind of money and like a challenge so have decided to see if I can make one.
    From what I can gather the hoop contains a ws2812b strip (I’ve had it snap in the past and saw the led strip before I sent it for repairs), there are 60 pixels in this hoop and I’ll be looking to make on the same size. As far as the circuitry goes, I can’t really see a lot and don’t want to take it to pieces as it’ll be a pain to put back together but I know that this hoop has a microprocessor to control the led patterns and create graphics (the tubing is 19mm OD so its a small micoprocessor) and I can see an IR receiver (uses a remote to cycle through modes and colours). The hoop is powered by a single TR14500 3.7v 2300mAh battery.
    I have an addressable LED strip on order and an adafruit trinket 3v to play with, does anybody think this will be possible? I also have a 5v trinket on order but as the battery I will be using is 3.7 I don’t think it will be suitable?
    I’d like to try and save myself some frustration by at least knowing if my project is feesable… Any guidance would be greatly appreciated!

  11. i have 300 leds hanging off a wimos mini pro – no need to do anything. The string is connected to 5v (at multiple points) and the pro just drives it straight off the pin….

  12. Some clone controllers are known to have suspicious 3.3v data outputs so this is where people would get mixed results running the led’s direct from the pinout. Since this hack effectively pushes the data line to 4.3v there is no reason not to do it especially if you are using long data line links. On some of my lighting projects I have 5m data lines with no issues after completing this hack.

    Great work with minimal components.

  13. This fixed my issue with an ESP8266 and SK6812 by putting the first pixel 3 inches from the esp, then the rest of the strip 10 feet away, wiring it as noted above, but WITHOUT the diode (or resistor) anywhere on the data line. Does that make sense? Thank you, I’m new to all this.

  14. Same Problem here: Generic ESP + WS2811 stripe gets wrong / random colors at higher brightness.
    As long as the brightness (=the current) is low, everything works as expected.

    Setup: 96 Pixels of WS2811 at 12V, controlled by a 3.3V ESP8285 M3 Module which gets its power through a adjustable mini step-down converter module. 1000µF at 12V and 530Ohm on the data pin, located at the esp which is 30cm (1ft) away from the first pixel. My code is using the basic Adafruit Neopixel lib.

    I can confirm, that minimal changes to the 3.3V does affect the behaviour of my stripe:
    Adjusted to 3.35V idle voltage, the system shows the errors at higher brightness.
    Adjusted to 3.25V idle voltage, the stripe is not controllable at all.
    Adjusted to 3.4V idle voltage, the stripe is working perfect!

    But this brings up another problem: The 3.4V from my step-down converter is rising up to 3.7V when the system draws about 2 amps. I’ve seen this behaviour, when the 12V input voltage is not stable, but it is in my case (CV lab power supply).
    Will have to test other step-downs…

    Increasing the 3.3V of the controller to 3.4V did it for me.

  15. Actually, no sacrifices required here, if one just adds a couple resistors to the schematic :) Power the WS2812 from a 5V rail, then connect the said rail and ground to the data line through resistors of the same value, effectively making a voltage divider and setting our logical ‘zero’ to 2.5V. Then all you need to do is connect the data line from the MCU to the LED via a diode – this way, setting the data line to high will add (3.3-0.7)=2.6V to the voltage on the data line, thus bringing it to 5.1V, voila!

  16. I just fell into this trap, with a set of 144 LED’s/M ws212B’s. I was sure I had screwed up, but take a single led and hook it up likethis and the whole strip is working. thanks HackaDay.

  17. I REALLY think people should note that if you’re driving the LEDs directly from a lithium battery, 3.3v logic will always work perfectly fine. 4.2v(max lithium voltage) *.07 (minimum signal constant) gives less than 3.3v, so you’re fine. Ive done it and it works great.

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.