adafruit / Adafruit_NeoPixel

Arduino library for controlling single-wire LED pixels (NeoPixel, WS2812, etc.)
GNU Lesser General Public License v3.0
3.08k stars 1.27k forks source link

esp8266 timing accuracy and problems #112

Open dpgeorge opened 8 years ago

dpgeorge commented 8 years ago

There seems to be a timing problem controlling neopixels on esp8266 based boards. Reports on the forum are here: https://forums.adafruit.com/viewtopic.php?f=57&t=103097 https://forums.adafruit.com/viewtopic.php?f=57&t=103844 , and on the MicroPython github: https://github.com/micropython/micropython/issues/2465

There are 2 parts to this issue. First, what is the exact theoretical timing that the WS2812 expects? (The WS2811 probably has similar problems, but let's just concentrate on the WS2812 for now.) I found a datasheet that says:

T0H   = 0.35us +/- 0.15us
T1H   = 0.7us  +/- 0.15us
TH+TL = 1.25us +/- 0.6us

In the code in this repo following values seem to be used (respectively to the values above, all in microseconds):

Atmel 8MHz:  0.25,   0.875,  1.25
Atmel 12MHz: 0.333,  0.833,  1.25
Atmel 16MHz: 0.3125, 0.8125, 1.25
ESP8266:     0.4,    0.8,    1.25

There seems to be a bit of a discrepancy here.

Second part: the actual timing of the esp8266 output (as captured on a scope) is slightly larger than the values listed above, because the loop does timing based on a CPU tick counter but does not take into account overhead from the loop and setting the GPIO registers. The actual values measured are, with esp8266 running at 80MHz:

T0H   between 0.417us and 0.5us
T1H   between 0.833us and 0.875us
TH+TL between 1.250us and 1.33us

Questions and issues are:

  1. What theoretical values for the timing should a neopixel driver aim for to be compatible with the majority of WS2812 devices?
  2. The esp8266 driver needs to be fixed to include the overhead of the loop, likely this is as simple as subtracting a fixed value from time0, time1 and period.
torwag commented 8 years ago

I found this article to be rather informative. IIRC, the datasheet is not exactly telling the complete story . https://cpldcpu.wordpress.com/2014/01/14/light_ws2812-library-v2-0-part-i-understanding-the-ws2812/ Maybe this helps to narrow it down

dpgeorge commented 7 years ago

The MicroPython driver fixes this issue by using 350ns for T0H on the esp8266 (calculation is time0 = fcpu / 2857143).