-
-
Notifications
You must be signed in to change notification settings - Fork 121
How to build a new LED system or to upgrade it. Needed components.
1) Full version of this tutorial can be found on my blog
2) Required hardware components
a) Device for hosting HyperHDR
b) Video components
c) Choosing LED strip
d) LED driver
e) 3.3V to 5V level shifter
f) Case for Raspberry Pi, ESP32 and two power supplies
g) HyperSPI vs HyperSerialESP32
h) How to solder the edges of LED segments 🆕
3) Challenges in designing a new sk6812/ws2812b system
4) Proposed solution: parallel multi-segment
5) Things to consider for single or multi-segment
6) Single-segment scheme for new LED system
7) Multi-segment scheme for new or upgraded LED system
8) Multi-segment HyperSerialESP32/HyperSPI firmware and HyperHDR configuration
9) Important! Optimization of HyperSerialESP32/HyperSPI settings in HyperHDR
The tutorial was originally posted on my blog and it can be found here: https://www.hyperhdr.eu/2023/02/ultimate-guide-on-how-to-build-led.html
No matter if you use LEDs multi-segment or classic single-segment solution, you will need these main components: USB grabber (+ HDMI splitter for MS2109/MS2130), sk6812 LED strip, SN74AHCT125N level shifter with a socket, good LED power supply (e.g. Mean Well) with appropriate power, ESP32 or ESP32-S2 device. I recommend using a wooden frame to mount the LED instead of the TV, a prototype board to mount the ESP and level shifter on it. Of course, the multi-meter is also recommended for detecting short circuits and possible cold solder joints. If you use a frame, you can direct the LEDs at a certain angle: if the frame is close to the wall (~3-5cm) it can be even 45 degrees.
Unfortunately, the situation with the availability of Raspberry Pi 4 has not improved yet. An increasingly important aspect when using HyperHDR is the presence of a USB3.0 port on the device. Let me just remind you that you can easily use HyperHDR even on a PC with Windows or Linux, on macOS or on various still cheap ARM-based TV boxes: I recommend especially those with Amlogic S905x3, more information can be found in my older posts on this blog. HyperHDR has very good compatibility with most of the newer builds of Armbian and Debian for various devices, especially the AARCH64 version.
For some time, HyperHDR has an automatic calibration of the HDR signal. This allowed for a fairly objective assessment of USB grabbers video quality using our HDR tone
mapping. As you can read in this test, MS2109 presented itself best. However, this required modifications to the brightness, contrast and saturation, which the manufacturer set well beyond the neutral settings. Which could be a problem e.g. if you are using HyperHDR on macOS as it is not possible to set them on this system.
Just before publishing this post, I received an improved version of this grabber: MS2130. It is a true USB3.0 cheap video grabber with factory neutral processing settings and no adjustments required. Still only HyperHDR allows you to use its capabilities optimally in terms of quality for SDR and HDR processing (yes, SDR is also affected because of YUV full range and FCC coefs). The results are sensational, although the grabber itself requires further testing and a full review will be published later. I recommend following this topic for more details: MS2130 link
No matter if you choose the proven MS2109 grabber or decide to experiment with the latest MS2130, you still need an HDMI splitter. I have two of them for a long time: FeinTech VSP01201 and Ezcoo EZ-SP12H2. Both work well, although there are some differences between them and as some users reported, the firmware update in the case of EZ-SP12H2 can be troublesome or even dangerous. Nevertheless, the manufacturer's efforts to support the product should be appreciated.
Currently, the best quality for our purposes is offered by the sk6812 RGBW cold white. If you are worried that the "Cold White" version of the SK6812 RGBW is bluish, this is completely false. You may experience such effect from RGB LED strips like ws2812b or APA102, but not from this RGBW LEDs version. We do not use LED strips for room lighting where warm color characteristic is preferred, but for precise Ambient Lighting. I know a lot of users choose the "Neutral White" version, but you also need to know that the our LED drivers do a lot of things underneath to try to fix the "Neutral White" unbalanced color profile and it is definitely not a good or "neutral" thing. I've both SK6812 version and can compare them side by side. Still whichever version you choose, the quality will be much better than with RGB LED strips such as ws2812b or clones of APA102.
You should read these market ads as:
- SK6812 Warm White → "Orange" (avoid!)
- SK6812 Neutral White → "Warm"
- SK6812 Cold White → "Neutral" (preffered)
The recommended LED driver is ESP32 or ESP32-S2 Lolin mini device. Unless new models are released, the Arduino as an LED driver is a thing of the past, and the Esp8266 is slowly following the same path. Below are examples of boards that I work with on a daily basis and have the best support from my side: ESP32 MH-ET Live (CH9102x) and ESP32-S2 Lolin mini. This does not mean, however, that we limit ourselves to them: almost every board with similar parameters will be supported. The exception is bad designed or manufactured boards like the model described by our users: link and link. Such "optimization" of costs can happen even between successive revisions of the same model. Always check product reviews before buying from a particular retailer.
Since the cost of transport is quite a large part of the total and takes a long time, I always order at least 2 ESP boards from Aliexpress, which gives me a spare in case one of them fails: damage in transit, bad flash memory or damage during soldering of pins can always happen. It's not a big deal as they usually cost around $2 to $4 only.
Update: support for Raspberry Pi Pico (Rp2040) boards has been added using my new project HyperSerialPico. More details can be found here: link. You can use it as a solid and cheap alternative to HyperSerialESP32 solution. Some of rp2040 boards (e.g. selected Adafruit and Pimoroni boards) have already built-in 3.3V to 5V level shifter, which greatly simplifies the whole setup when HyperSerialPico is used!
As it has been explained many times, the logic of the ESP32/ESP8266/ESP32-S2/Raspberry pi uses a voltage of up to 3.3V, while the driver in the LEDs works with a voltage of up to 5V. If we don't use 3.3V to 5V level shifter our solution will be out of technical specification and you can expect all sorts of problems: from LEDs not working at all, to occasional flashes or a complete "disco" effect. Similar symptoms can occur if you do not provide "common ground" between the driver/level-shifter and the LEDs. We recommend using a multi-channel level shifter: SN74AHCT125N/74AHCT125 with a socket which allows you to replace the chip if needed. You can find more here: link
Example: you can use the cut off legs of the resistors (thin wires) to make the paths on the PCB easier. Because I had a 2x8 IC socket and the level shifter is only 2x7, the first column of the socket is empty. For this particular multi/single-segment capable board and ESP32-S2 mini, the LED output is on GPIO16 and GPIO33 (requires a firmware compilation to set these GPIOs, which is explained later). The yellow pinout is optional and it's used for HyperSPI connection: if you don't use, you don't need to solder it:
If you use a modular power supply, you must take special precautions and ensure that all high-voltage cables are securely fastened and insulated. The whole thing should be enclosed in a case while ensuring at least passive ventilation (ventilation holes). Never open it when the power cord is connected. I'm absolutely not encouraging anyone to follow this scheme as there is potential hazard related to the high voltage from the modular power supply. You can use a sealed laptop 5v power supply as an alternative. I never leave the system without attention and power it off with Power Cube Remote when not used. The Rpi with Raspberry Pi OS is using the read-only system on SD card so it can withstand sudden powering off (read more here )
In my project I used a Kradex Z17W case, screw-in copper sockets to attach the ESP32 and Raspberry Pi, screws to attach Mean-Well LRS-150F-5 power supply, IEC 320 3-pin 10A 250V sockets C14 input male plug with 1A fuse and a molex for the LED strip output (for higher currents you will need, for example, an XT60 connector or its equivalent). Raspberry Pi is using dedicated 2A USB power supply, not Mean-Well.
HyperSPI is by far the optimal solution: the SPI protocol is hardware accelerated and is much faster, so consumes much less system resources and provides lower latency than HyperSerialESP32, which involves the use of USB serial port drivers to communicate (but works over long distance even few meters). Contrary to appearances, it is also very easy to build because it requires the use of only 3-4 short 15-20cm dupont wires to connect the SPI interfaces and the grounds.
But HyperSPI can only be used if the device offers an SPI interface and is supported by the operating system. In practice, this limits its use to the Raspberry Pi (and OrangePi as reported by users). An additional limitation for HyperSPI is the distance: it can only be used on very short distances of 15-20 cm from Raspberry Pi. Of course, if you have a supported device and the distance between it and the ESP will be short, you can use it as you want with either HyperSPI or HyperSerialESP32.
Update: support for Raspberry Pi Pico (Rp2040) boards has been recently added using my new project HyperSerialPico More details can be found here: link. You can consider it as an alternative to HyperSerialESP32 solution. Also Pico thanks to the PIO I/O coprocessor is able to produce a very high quality and precise signal, which is especially required for the Neopixel sk6812/ws8212b LED strips. Some of rp2040 boards (e.g. selected Adafruit and Pimoroni boards) have already built-in 3.3V to 5V level shifter, which greatly simplifies the whole setup when HyperSerialPico is used!
The cables for +5V and the ground should be thicker, e.g. typically 0.75-1.5mm2 (depending on the predictable load), the signal cable can be very thin. Everyone can use their technique here, one that suits them. Start by applying tin to soldering points on LED strip.
For the data line I use thin copper solid wire aprox. 4-5cm length. I start by soldering one end of the wire to the first LED segment, I bend it and remove excess insulation and soldered it to the second LED segment. Then I cut the excess part of the wire with my wire cutting plier.Be careful because the wire can heat up to high temperatures when soldering so use some insulation and do not hold it with your bare fingers.Then I solder the cables connecting +5V and the grounds of LED segments as in the attached photo.
As you can see I also use 45° wooden strip attached to the wooden frame.
Unfortunately, a certain disadvantage of Neopixel type LEDs like sk6812 is a rather slow data bus ~800KHz. This is especially true for RGBW LEDs because we need to send as much as 4 bytes of data for each LED and only 3 bytes in case of RGB ws2812b. This limits the maximum refresh rate. However, the latest versions of HyperSerialESP32 and HyperSPI offer HyperHDR a solution to this problem without compromising quality.
Since we can't increase the speed of the data bus, we have to work around this problem in a different way: split a long single LED strip into two smaller ones. In this way, each of them will have a separate data bus and will be able to be refreshed at twice as often as the original single and long LED strip. So far, the problem remained how to easily offer the configuration of such a solution and ensure perfect synchronization between both smaller segments? After all, we don't want both segments to render even slightly out of sync scenes or make the construction or configuration of such a system so complicated, that it will surpass the abilities of an average mortal.
This is where the latest HyperSerialESP32 v9 and HyperSPI v9 come to the rescue with the true parallel multi-segment output. Just choose the solution that suits you better. Parallel multi-segment mode is currently supported only by ESP32 and ESP32-S2 (mini lolin). Unfortunately, today the Esp8266 is too limited to offer similar solution. Parallel multi-segment output means that the signal for both segments is sent at exactly the same time using ESP parallel I2S interface, so both segments are perfectly synchronized.
Parallel multi-segment not to be confused with WLED segments: it's a completely different solution that can't provide the same experience at all in terms of quality (DMA pre-fill mode to ensure smooth rendering) and synchronization of segments.
Is it worth building or upgrading your system to parallel multi-segment mode? You have to answer this question yourself, taking into account the parameters of your setup. It complicates a bit building and configuration of new setup compared to the single LED segment, but this is certainly the most optimal way to use sk6812 or ws2812b with HyperHDR. The benefits depend on whether you are using RGB or RGBW and how many LEDs you intend to use and start from 300 RGBW LEDs, for RGB this number is higher. Example results of maximum refresh rate:
Parallel multi-segment mode / Device | ESP32 MH-ET LIVE mini @4Mb speed |
ESP32-S2 Lolin mini @5Mb speed |
---|---|---|
300LEDs RGBW Refresh rate/continues output=100Hz SECOND_SEGMENT_START_INDEX=150 |
100Hz | 100Hz |
600LEDs RGBW Refresh rate/continues output=83Hz SECOND_SEGMENT_START_INDEX=300 |
83Hz | 83Hz |
900LEDs RGBW Refresh rate/continues output=55Hz SECOND_SEGMENT_START_INDEX=450 |
55Hz | 55Hz |
And if you dont use parallel multi-segment setup:
Single RGBW LED strip / Device | ESP32/ESP32-S2 HyperSerialESP32 v9 |
---|---|
300LEDs RGBW Refresh rate/continues output=83Hz |
83Hz |
600LEDs RGBW Refresh rate/continues output=42Hz |
42Hz |
900LEDs RGBW Refresh rate/continues output=28Hz |
28Hz |
And few words about Neopixel data line latency.
Let's calculate how long it takes to send LED color information over the Neopixel data line (800kHz).
Single segment, sk6812 RGBW LEDs:
300 RGBW ⇒ 300 * 4 bytes ⇒ 300 * 4 * 8 bits ⇒ 9600 bits ⇒ 9600 / 800000 ⇒ 12 ms
600 RGBW ⇒ 24 ms
900 RGBW ⇒ 36 ms
Multi-segment, sk6812 RGBW LEDs divided into two smaller segments:
300 (2x150) RGBW ⇒ 150 * 4 bytes ⇒ 150 * 4 * 8 bits ⇒ 4800 bits ⇒ 4800 / 800000 ⇒ 6 ms
600 (2x300) RGBW ⇒ 12 ms
900 (2x450) RGBW ⇒ 18 ms
So the latency is two times smaller for the multi-segment setup. Neopixel LEDs render immediately upon receiving a reset pulse, which is a nice feature compared to SPI LEDs.
Many thanks for @pavel-ponomarev for help with the diagrams. Connections between Rpi pinout and ESP pinout are needed only if you use HyperSPI. For HyperSerialESP32 only full USB connection between ESP and Rpi is neccesery.
The above Fritzing sketch is available here for download.
You only need the already built firmware from the HyperSerialESP32/HyperSPI Releases section. Upload it to the ESP device and configure it according to the instructions you will find on the project homepages. For general HyperHDR setup instructions, see the HyperHDR wiki. Then skip to "Optimizing HyperSerialESP32/HyperSPI chapter".
Upgrading your current setup to parallel multi-segment: depending on how it's built, you'll need to carefully physically separate the data lines in the middle of the LED strip to get two equal smaller segments. You don't need to break the existing +5V and ground lines, although it may give you more room to firmly attach the new data line. Connect a new data line cable at the beginning of the segment that no longer has a data input. After soldering, secure it mechanically permanently using e.g. hot glue. Make sure it is not touching/shorting adjacent ground or +5V lines. You don't use the SECOND_SEGMENT_REVERSED option described later when compiling your firmware for ESP driver. Remember that both data lines from the ESP/level-shifter to the LED strip should be fairly even and short.
The above Fritzing sketch is available here for download.
The construction of the new system is much simpler: from the LED strips you build two segments facing in opposite directions. The data lines cannot connect between them. One picture will replace many words (thank you @pavel-ponomarev).
For multi-segment we need to compile our own HyperSerialESP32/hyperSPI firmware to take into account where the second segment starts and whether it is reversed (new setup) or not (upgrade of the old single to multi-segment). But don't worry: you don't need to install any application on your computer or have any programming skills to do it. The whole process takes only a few minutes and is completely online. All you need is a free Github account.
Follow the manual available here or here and stop at step 5.
For HyperSerialESP32 now we can increase in platformio.ini configuration file the default serial port speed: for ESP32 MH-ET Live (CH9102x) set 4000000
and for ESP32-S2 Lolin mini set 5000000
. Remember than you need to use this new speed also in the HyperHDR Adalight driver instead of the default 2000000
speed. You don't need to change the serial port speed for HyperSPI.
There are 3 options (append -D
prefix) when defining the second segment in HyperSerialESP32 and HyperSPI :
-
SECOND_SEGMENT_START_INDEX
start of the second segment, total number of LEDs in the first segment -
SECOND_SEGMENT_DATA_PIN
this is the GPIO data pin for your second stripe. Recommend to use GPIO4. -
SECOND_SEGMENT_REVERSED
if present, the second segment is reversed relative to the first one (new setup). We do not use this option if both segments have the same direction (upgrade of the old single-segment setup)
We find in the edited file sections suitable for our ESP (ESP32 and ESP32-S2 have separate sections) and the type of LEDs and define the second segment there.
For example, I have an SK6812 RGBW Cold White segment of 340 LEDs split into two 170 segments in opposite directions (new setup). I'm using ESP32 and HyperSerialESP32 and the LED output for the second segment is GPIO4.My setup would look like this: locate
[env:SK6812_RGBW_COLD]
section for ESP32 and SK6812 RGBW Cold white. Append to build_flags my configuration:build_flags = ... ${env.build_flags} -DSECOND_SEGMENT_START_INDEX=170 -DSECOND_SEGMENT_DATA_PIN=4 -DSECOND_SEGMENT_REVERSED
Another example, I have an WS2812B RGB segment of 500 LEDs split into two 250 segments in same direction (upgraded setup). I'm using ESP32-S2 mini and HyperSerialESP32 and the LED output for the second segment is GPIO4. My setup would look like this: locate [env:s2_mini_WS281x_RGB]
section for ESP32-S2 and WS2812B. Append to build_flags my configuration:
build_flags = ... ${env.build_flags} -DSECOND_SEGMENT_START_INDEX=250 -DSECOND_SEGMENT_DATA_PIN=4
Now you can commit changes to platformio.ini with the button at the bottom and wait a moment for Github Action to compile them, which is described in the next steps on the wiki. Download from Github Action the zip firmware package, unpack it and find the version you configured. Then follow the instructions on HyperSerialESP32 and HyperSPI to flash this firmware.
Multi-segment in HyperHDR should be configured as one continuous segment. Everything is done in the HyperSerialESP32/HyperSPI software transparently and does not affect the configuration of the LED strip in HyperHDR which treats it in the same way as a single-segment. For example, if you have a multi-segment divided into two 250 LEDs segments you should configure it in HyperHDR as standard single LED strip of 500 LEDs. Check the HyperHDR wiki for more details.
We cannot force the Neopixel sk6812/ws2812b LED strip to render more frames than its internal data line can handle. Therefore, to avoid dropped frames or their buffering, which can sometimes introduce a slight lag, you should set the maximum refresh in smoothing so that the LED strip is able to render.
To do so, follow the instructions at HyperSerialESP32 or at HyperSPI. Remember that you need to set color as an effect, not an animation like "Rainbow swirl" because they have predefined settings that you cannot change. For HyperSerialESP32 you also need to have an 'Esp8266/ESP32 handshake' option enabled in HyperHDR Adalight driver.
I will show on the example of HyperSerialESP32 how to do it. I have defined a single segment of 400 RGBW LEDs in HyperHDR. I enabled the 'Continues output' option in Smoothing configuration and run the color as an active effect according to the manual mentioned earlier. From the benchmarks in the table that can be found in this section, I know that the expected maximum refresh rate is between 83Hz and 42Hz. So I set it now to the highest value for testing: 83Hz.
After a few seconds, I stop the LED device in the Remote section and find the actual refresh rate in the logs. The test should be carried out several times (enable and disable the LED strip again) to eliminate possible interference.
So I know that my LEDs can be refreshed with a maximum of 62Hz. If the value is greater than 100 for smaller configurations, it usually doesn't make sense to set it so high. I go back to the Smoothing settings and set the refresh according to the result. Then I disable the 'Continues output' option. That's it. The same procedure applies to a multi-segment setup, although of course you can expect a higher refresh rate.