Skip to content
Michael Miller edited this page Apr 5, 2023 · 12 revisions

⚠️ IMPORTANT ⚠️
The ESP8266 requires hardware support to be able to reliably send the data stream. While a bit bang method is provided, it is not recommended.
Due to this and the restrictions on which pins are used by each hardware peripheral, only I/O pins GPIO1, GPIO2, and GPIO3 can be used. The Pin argument is ignored and can be omitted.

The DMA methods will use GPIO3.
The UART1 methods will use GPIO2.
The UART0 methods will use GPIO1.

NOTE: Due to the varied board layouts for ESP8266, even though the pin maybe exposed, it may not be usable due to some custom feature on the board you use. If you find it not working, you should review the hardware schematic of your board and confirm the pin is not used for other purposes that interferes with it being used for NeoPixelBus.

All methods for the ESP8266 platform will follow this template for the methods name. The LED names are the same from the simple names and will not be listed in full below as we will focus on the hardware details on this page.

"NeoEsp8266<insert hardware detail><insert LED name>Method"

DMA (I2S)

The I2S hardware is used to send the data. This method uses very little CPU for actually sending the data to NeoPixels but it requires an extra buffer for the I2S DMA to read from. Thus, there is a tradeoff of CPU use versus memory use. The extra buffer needed is four times the size of the primary pixel buffer. Since the ESP8266 only supports I2S on the RXD0/GPIO3 pin. The Pin argument can be omitted when you construct a NeoPixelBus.

  • Dma - An example would be NeoEsp8266DmaWs2812xMethod.

There are several unique methods for supporting specific LEDs that use I2S peripheral. They are:

  • NeoEsp8266Dmx512Method - DMX512, an industry standard 250 Kbps data format used in commercial lighting applications.
  • NeoEsp8266Ws2821Method - WS2821, a DMX512 compatible LED that supports faster speeds. This method runs at 750 Kbps.

NOTE: The DMA uses RDX0/GPIO3 pin and the normal feature of this pin is the "Serial" receive, you will not be able to recieve on Serial the primary serial object. But it will not stop you from sending output like this...

    serial.println("I can still debug using serial println");

Due to the pin overlap, there are a few things to take into consideration.

First, when you are flashing the ESP8266, some LED types will react to the flashing and turn on. This is important if you have longer strips of pixels where the power use of full bright might exceed your design.

Second, the NeoPixelBus::Begin() MUST be called after the Serial.begin(). If they are called out of order, no pixel data will be sent as the Serial.begin() reconfigured the RDX0/GPIO3 pin to its needs.

For more details on Serial and pins, refer to the ESP8266 Arduino Reference

Thanks to g3gg0.de for porting the initial DMA support from the original which led to this work. The original was located at github/cnlohr/esp8266ws2812i2s. The current work is no longer based on that but it gave me the direction I needed to provide a solution.

UART

These methods use the CPU to manage a small hardware managed UART buffer to send the data to the NeoPixels. Thus, it requires more CPU overhead than the DMA method, but it does NOT require an extra buffer.

  • Uart0 - Uses UART 0. An example would be NeoEsp8266Uart0Ws2812xMethod. Supports only TXD0/GPIO1 pin.
  • Uart1 - Uses UART 1. An example would be NeoEsp8266Uart1Ws2812xMethod. Supports only TXD1/GPIO2 pin.

Because the UART FIFO size is limited, data for just a few (typically 10) pixels can be sent completely in the background. If you have more pixels than will fit into the UART FIFO, data sending will block (use the CPU) until only a few pixels are left to send, which can then be completed in the background while the CPU does other things. The exact number of pixels depends on how much bytes each pixel needs. The FIFO buffer is 128 bytes, of which 4 bytes are need for each byte transmitted to the pixel, so for a typical 3-bytes-per-pixel WS2812 you need 12 FIFO bytes per pixel and can drive 10 pixels without blocking).

If CPU cycles or blocking are an issue in your project, see AsyncUart below.

Due to using the hardware UART, the associated Serial or Serial1 objects can not be used. If you use UART1, Serial is still available and if you use UART0 then Serial1 is still available.

Asynchronous UART

These methods use the UART interrupt to read from a secondary buffer to send the data to the NeoPixels. It requires very little CPU overhead but does require an extra buffer similar to the DMA method.

  • AsycUart0 - Uses UART 0. An example would be NeoEsp8266AsycUart0Ws2812xMethod. Supports only TXD0/GPIO1 pin.
  • AsycUart1 - Uses UART 1. An example would be NeoEsp8266AsycUart1Ws2812xMethod. Supports only TXD1/GPIO2 pin.

WARNING: With this method, Serial and Serial1 cannot be used due to the ISR not being shareable.
CAUTION: With this method, the Pixels() method will return alternating pointers after each call to Show(); so the pointer returned should not be cached or retained between calls of Show().

Thanks to unaiur for providing the original implementation.

Bit Bang

This method uses only the CPU to send data to the NeoPixels. But due to Wi-Fi interrupts it is not stable when used with Wi-Fi features of the ESP8266. The bit bang methods only support pins between 0 and 15.

  • BitBang - An example would be NeoEsp8266BitBangWs2812xMethod.

It is not recommended to use this method except for comparing results with the other methods. For very short runs of pixels (no more than about 3) it may be possible to use this method without ill effects. If it fails, the pixels may not be correctly set.

Clone this wiki locally