I am trying to control some SMD LEDs WS2812B with the ESP8266-Nodemcu. I am using Arduino environment for coding. Actually I am trying to accomplish a PWM that is precisely able to:

  • Go High for 850ns and then
  • Go Low for 400ns

According to the Spec this, this High Low change is considered as a bit with value 1.

I have tried to delay between the lows and highs, without an effort (delays only work for microseconds and above i suggest).

Do you have any idea how to accomplish that?

  • 3
    I believe you're using WS2812? Then you can use the NeoPixel library. You probably should not bother to try it yourself. – Paul Dec 8 '16 at 6:32
  • 2
    You could have better picked up an SPI based led strip. Since the ESP8266 has to do stuff in the background, it could affect the timing afaik. And the SPI ledstrips are easier to drive. – Paul Dec 8 '16 at 6:33
  • @Paul yes the libary could indeed be useful. I will try it later. Could you propose me a special model of SPI led stripes? – Thomas Richter Dec 8 '16 at 8:31
  • This could be relevant also: github.com/cnlohr/esp8266ws2812i2s, it 'hacks' the I2S bus for accurate timing. – bluemind Dec 8 '16 at 9:45
  • 2
    For Arduino, the same I2S bus trick is used here: github.com/Makuna/NeoPixelBus/wiki/… – bluemind Dec 8 '16 at 9:46

According to §1.7 (Pulse-Width Modulation) of espressif.com's ESP8266 technical reference document, “PWM frequency range is adjustable from 1000 μs to 10000 μs, i.e., between 100Hz and 1 kHz.” That range is shown in other sections of that reference, and in other ESP8266 documents as well. I don't know whether that range reflects any hardware limitations, or whether the PWM APIs enforce such limits or can be operated outside them.

Depending on what your intent is, you might instead consider use of UART capabilities. For example, if you set the UART data rate to 2.5 MHz and transmit a 110110110... binary pattern synchronously, you will have 800 ns high alternating with 400 ns low. [I've seen references to use of USARTs on ESP8266's but don't know with certainty whether synchronous protocol actually is supported.]

The I2S subsystem mentioned in §1.5 and described in §10 of the technical reference document also may be able to generate a bit stream as desired. As noted in § one six-bit field selects an input clock prescale factor, and another six-bit field is used as the frequency divider of the communication clock signal.

Edit 1: As noted in cranphin's comments, cnlohr's esp8266ws2812i2s github page provides code that uses the I²S subsystem and DMA to drive WS2812 LED units. Using DMA (direct memory access, ie transfer of memory data under control of a subsystem other than the CPU) means that once the CPU has set up a data buffer for a new display, it can turn actual transmission of the buffered data over to I²S / DMA and then go on with unrelated tasks while transmission occurs. Note, cnlohr's page links to a youtube video that illustrates and briefly explains the process.

  • 1
    Thanks for the broad information, this was very useful for me. The UART and I²C thing could be an interesting solution, i will try it at the weekend :) – Thomas Richter Dec 8 '16 at 8:35
  • 1
    I ahve tried the I2S thing and it worked! thx – Thomas Richter Dec 12 '16 at 8:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.