ESP32 + WS2812B wiring

Hi,
this is probably dumb question, but after checking a lot of projects I'm still confused. I wanna make LED strip project controlled by ESP32. I wanna use:

  • ESP32
  • 5m WS2812B leds (30leds / m, 150 leds in total, 45W)
  • external power suply (5W, 10A)
  • 330k ohm resistor
  • 4700uF - 1000uF wasn't on stock when I placed order, but I think this one should be ok (neopixel recommends it)

I wanna use only external power suply. My concern is how to connect it. LED strip has soldered 5 wires, three in conector + two lose power wires. In projects I checked, I see two methods. I sketched two diagrams to show what I have on mind. Please note that this LM35 is only for representation of LED strip, I couldn't find proper graphic in fritzing.

  • TOP - connect ESP32 and LEDs directly from power suply, two extra LED power wires will be not used
  • BOTTOM - use extra LED power wires, connect them to power suply, use LED connector to power up ESP and get data from it

Which way is correct, are some up/downsides of those methods?
Cheers
Mark

Please note that this LM35 is only for representation of LED strip, I couldn't find proper graphic in fritzing.

Thanks for telling us. This is one of the reasons we hate Fritzing here. Basically is is useless for doing anything except mindlessly building something. It has no place in proper electronics.

There is no difference between those two diagrams they are both topological the same.

What can cause you problems is that there in insufficient voltage from this processor to grantee the data is read. Some times it will work but on paper it is not enough.

Ok, thanks for answer! I will try, if there will be some issues with voltage I will search for other solution.
And next time I will use something else then fritzing :wink:

:frowning:
Fritzing does not come with every electronic component ever made built-in. No schematic/pcb editor does. As with all such tools, for anything even slightly exotic, you need to download a library to add the component to Fritzing's database. That includes ws2812 leds and esp32 dev boards. Google will provide.

They say a poor workman blames his tools. Do great workmen blame the poor workman's tools or do they blame the poor workman?

OK, now to answer your original question, your second diagram is correct! You use the separate "loose" power wires to connect your supply (but there is a trick!) and the connector with three wires takes power to your ESP32 along with the data. It is important that all power or signal wires travel bundled with the ground return to avoid open loops in the wiring as your first diagram implies. This is in order to avoid interference of various sorts coupling by induction (or capacitance) from one area to another.

The capacitor should be as close to the LED strip at the "data in" point as possible, as should be the series resistor.

What's the "trick"? If you are going to operate the LEDs at any substantial brightness, you need to feed power (5 V and of course, ground) in parallel every 60 or so LEDs (3 Amps) including the distant end as the foils on the strip will drop significant voltage at these current levels.

But also note - the ESP32 drives 3.3 V logic levels which are generally inadequate to drive the 5 V logic level WS2812s and this depends on the actual 5 V supply voltage. You will need a logic level converter such as two cascaded gates of a 74HCT14 (while 74HCT04 would be OK or even a 74HC04) powered by the 5 V.

Thanks Paul__B!
Yes, I'm aware of voltage drop. This project will be used as an bed light (I will also add PIR and photoresistor, not included on diagrams, but it was irrelevant for my question), so it will be rather low brightness. If there will be any issues, I think also connecting end to power supply will do the trick.

About 3.3V logic. This one confuses me. Of course I know about this, but I saw a lot of projects that works fine (on ESP32 or 8266) without it. Of course on some projects people uses them. It's logic to use logic level converter/shifter, but I wonder what (besides data sheets which clearly says "you need it") determines usage of it. Strip length?

No, strip length is irrelevant (assuming your power supply is adequate; if it isn't, that could affect voltages in the circuit which could in turn cause various problems). This is why:

If a level shifter is needed, it is only needed to adapt the 3.3V signal from the MCU to the first led in the strip. You see, the signal from the MCU only goes to the first led. The first led then sends a 5V signal to the second led, the second led sends a 5V signal to the third led and so on. If a level shifter is not needed, the first led as acts as a level shifter, and the remaining LEDs get a 5V signal.

Hmm, so it depends on the LED strip? First led could act as level shifter or not? And level shifter guarantee that everything will work fine. Correct?

First led could act as level shifter or not?

The first LED is a level shifter.

And level shifter guarantee that everything will work fine. Correct?

Well there are many ways to screw things up but a proper level shifter will make things reliable on the drive side. Do not use the level shifter circuits designed for I2C circuits, they don’t work quite fast enough.

Whether the first led can act as a level shifter depends on several things. Probably most important are:

  1. The specification of the chip inside the leds. That spec might say something like "a high signal must be at least 0.7 * Vcc". In that case, with a 5V supply, that's 3.5V. So a 3.3V signal would not register as high, and the data would not be received. If the spec says "0.6 * Vcc" then 3.3V would be high enough. Of course, that 0.6 or 0.7 figure isn't exact. It will vary slightly from chip to chip.

  2. The power supply for the leds might not be exactly 5V. It might be 4.8V or 5.1V or so. The power supply for the esp32 might not be exactly 3.3V. It might be 3.25V or 3.35V etc.

  3. There might be some voltage drops in the wires.

As you can easily see, the combination of these factors can lead to signals which can be very close to the borders of what might work and what might not. That's why some projects work fine without a level converter, but someone trying to re-create the same project finds it does not work for them.

Ok, thanks guys for all explanations, now is clear :slight_smile: For now I will have no other option then connect without level shifter (I already placed orders....), but when LEDs will not work or act strange, I will know what probably cause problems.

So for reliable operation, both for your circuit and for anyone copying your circuit, a level shifter is a good idea.

Good level shifter ideas:

  1. Use a chip like 74hct14 or 74hc14.
  2. Use a "sacrificial" led cut from the strip. Power this led with a voltage somewhere between 3.3V and 5V, for example by putting a power diode in series with its Vcc, so it only gets around 4.3V. You might not get the correct colours from this led because of its low supply voltage, but it should boost the data signal to a good level for the rest of the strip.

Less good level shifter ideas:

  1. Any simple circuit built from a transistor and a few resistors, unless those components are expertly chosen.
  2. Those 4-channel level converters from eBay etc. These are the ones mentioned by Mike that are designed for use with i2c components.

In both of those cases, Ws2812 leds use a data rate 4x higher than standard i2c, and these simple circuits are unlikely to be fast enough to keep up with the data signal, and so will corrupt it.

Hi,
All components arrived, so I put this together. At the begining I didn't use cap and resistor, all worked well. Level shifter also isn't needed in my case. As expected, when connecting to only one end, voltage drop was big (around 3V at the other ends, so I connected it from both sides. All works well :slight_smile: But! After checking power consumption, it's only 50% of expected value, 4.5A. And as far I know, it should be 9A for this pixels count. I don't know if I measured this correctly:

  • (-) probe connected directly to power supply
  • (+) probe connected to BOTH wires from strip, start and end
  • set multimeter to 10A

Maybe dumb question, but should I mulitply this value by 2? Then I will get exact amperage as expected. I think components are ok, not top notch, but decent:

  • Mean Well lrs-50-5 50w 5v 10a
  • BTF-Lightning WS2812B 30/m 5m

Maybe my calculation is wrong? But as I read, one pixel and max brightnes - 60mA. Strip has 150 pixels. So that gives 9A. Also BTF on package says 45W, so all matches.
Brightness is ok, I don't have nothing to compare, but from eye balling, I thing 2x brighter would be impossible.
Am I missing something?

Cheers
Mark

Your description of how you measured the current sounds correct. You do not need to double anything.

What code is running while you measure that current?

Maximum current only when every led is at full brightness white. Other patterns could draw much less. For example a rainbow type effect, even at full brightness, might use only one third of that max.

Also 60mA is a conservative over-estimate. 50~55mA is more often seen in practice.

Yes, I know that max current is on white at full brightness, and thats when I'm getting 4.5A. Here is code, in Blynk I set white color and slider to the max (255).

#define BLYNK_PRINT Serial
#include <BlynkSimpleEsp8266.h>
#define FASTLED_ESP8266_RAW_PIN_ORDER
#include "FastLED.h"
#define NUM_LEDS1 150
#define LED_TYPE    WS2812
#define COLOR_ORDER GRB
CRGB leds1[NUM_LEDS1];
char auth[] = "***";
char ssid[] = "***";
char pass[] = "***";
#define PIN1 5
int data=255;
int r,g,b;
void setup()
{
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  FastLED.addLeds<LED_TYPE, PIN1, COLOR_ORDER>(leds1, NUM_LEDS1).setCorrection( TypicalLEDStrip );
}

BLYNK_WRITE(V3)
{
  r = param[0].asInt();
  g = param[1].asInt();
  b = param[2].asInt();

  static1(r, g, b,data);
}

void loop()
{
  Blynk.run();
}
BLYNK_WRITE(V2)
{
data = param.asInt(); 
static1(r, g, b,data);
}
void static1(int r, int g, int b,int brightness)
{
  FastLED.setBrightness(brightness);
  for (int i = 0; i < NUM_LEDS1; i++ )
  {
    leds1[i] = CRGB(r, g, b);
  }
  FastLED.show();
}

goofy3:
in Blynk I set white color and slider to the max (255).

Hmm... I may be clutching at straws, but in this case what values of param[0..2] are actually sent? Try printing them to serial monitor.

Maybe try a simple non-Blynk sketch which sets brightness=255 and r=g=b=255 for every led.

Hi,
I checked those parameters, 255, 255, 255, 255 is sent from blynk, so all good, white on full brightness. Still 4.5-4.6A.

I also uploaded simple sketch as you sugested, little progress, now I'm getting 5.21A. But still a far away from expected values.

#include "FastLED.h"

#define NUM_LEDS 150
#define DATA_PIN 5

CRGB leds[NUM_LEDS];

void setup() {
  FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);
}

void loop() {
  FastLED.setBrightness(255);
  fill_solid(leds, NUM_LEDS, CRGB::White); // Set all to red.
  FastLED.show();
}

Odd. Try moving the code lines from loop() into setup() so that loop() is empty. I suspect it won't make any difference, but...

Also try removing the setBrightness() line. Again, that should make no difference.

Try setting the strip to CRGB::Red, then CRGB::Green, then CRGB::Blue. Each should draw around 2.5~3A. Make a note of the current for each colour. Then try CRGB::Yellow. That should be the the total of the red + green currents. Similarly, CRGB::Cyan should be the total of green + blue and CRGB::Magenta should be red + blue. Are they?

Also strange is that the Blynk shetch uses 0.5A less than the simple sketch, when they should both be sending the same data to the strip.

I tried moving code to the setup, removing setBrightness, no diffrence. With setting diffrent colors I get those results:

Red 1,86A
Green 1,01A
Blue 1,86A
Yellow 3,5A
Cyan 3,5A
Magenta 3,5A

So single green is way off, but combined colors looks ok. I also measured voltage in the middle of strip, on white, full brightness I have voltage drop to 4.4V. It's not full 5V, but I don't think so it should be responsible for this low amperage. Or maybe it is? I borrowed my solder iron so I can't solder new wires for couple of days for testing. Also measuring in diffrent strip location is kinda hard as this is IP65 strip.

I also tried setting only 30 leds, but I'm getting same results, around 35mA/pixel at white, full brightness.

Other strange thing, I used this code for testing diffrent colors amperage, and I didn't get delay of 5s, but rather 2.5s. So besides half of amperage, I'm getting half of expected time... I know delay is dirty way, but it was for testing purposes, and should work.

#include "FastLED.h"

#define NUM_LEDS 150
#define DATA_PIN 5

CRGB leds[NUM_LEDS];

void setup() {
  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
}

void loop() {
  fill_solid(leds, NUM_LEDS, CRGB::Red); 
  FastLED.show();
  delay(5000);

  fill_solid(leds, NUM_LEDS, CRGB::Green); 
  FastLED.show();
  delay(5000);
  
  fill_solid(leds, NUM_LEDS, CRGB::Blue); 
  FastLED.show();
  delay(5000);

  
  fill_solid(leds, NUM_LEDS, CRGB::Yellow); 
  FastLED.show();
  delay(5000);

  
  fill_solid(leds, NUM_LEDS, CRGB::Cyan); 
  FastLED.show();
  delay(5000);

  
  fill_solid(leds, NUM_LEDS, CRGB::Magenta); 
  FastLED.show();
  delay(5000);

  fill_solid(leds, NUM_LEDS, CRGB::White); 
  FastLED.show();
  delay(5000);
}

Note that a digital meter is not very good at measuring pulsating currents. The further away from full on the less accurate it is in averaging the measurements.