nickovs/ws2812-SPI

Disabling IRQs required.

Closed this issue · 6 comments

cefn commented

Great library! However I found that for my case (ESP8266 NodeMCUv2) my LED strip flickered if interrupts weren't suspended. The following example code worked for me on Micropython 1.9.3, continually setting the first half of my 12 pixel chain red, and the second half blue without flicker. Perhaps IRQ suspending could be a default, overridden by a boolean keyword argument to write()

from neoSPI import NeoPixel
from machine import SPI,disable_irq,enable_irq
import time
spi = SPI(1, baudrate=3200000)
pixels = NeoPixel(spi, 12)

while True:
    sec = time.time()
    first = (255,0,0)
    second = (0,255,0)
    while (time.time() - sec) < 5:
        pixels[:6] = first
        pixels[6:] = second
        state = disable_irq()
        pixels.write()
        enable_irq(state)

I'm not sure that the flicker here is caused be interrupts upsetting the transfer since if you're using an ESP8266 and machine.spi(1) then you are using a hardware SPI interface, so interrupts should not be an issue. I think that part of what is going on here is that there is no delay in your loop, which means that you are constantly resetting the values on the pixels. The NeoPixels do not need to be constantly refreshed but they do briefly switch off while they are accepting new data. If you briefly disable the interrupts and then reenable them then you'll probably end up with quite a regular loop time and a very regular flicker will be less noticeable. Can you try taking out the disable_irq() and enable_irq() and add a sleep(0.1) statement instead? If that fixes it then I think the flicker was probably cause by you writing to the pixels too fast.

cefn commented

The experience I had was not regular flickering, as would take place if there was a moment of black on each write. Rather the experience was that it worked nearly all of the time, and there was occasionally a failure to accurately write (e.g. some of the pixels ended up temporarily black or the wrong color). I ambiguously described this as a 'flicker'. The reason for writing so very fast and frequently was to be able to trigger enough writes to be able to see the occasional failure. If you run at routine speeds, it looks like it's working all the time, but then you will get e.g. a 1% failure. When you are writing very regularly, they are more detectable.

OK. I've been trying to reproduce the problem and can not get it to show up. I don't see any flickering with interrupts enabled. What version of MicroPython are you using and what sort of LED strip? I've been using some cheap, no-brand ESP8266 cards that I got on Amazon and I've tried this with both cheap AliExpress LED strips and the curved AdaFruit NeoPixel strips and the only problems that I've had have been down to loose connections.

cefn commented

I am using WS2811-driven 12v 3LED rectangular pixels. For these pixels the signal wires need to be very short and I am having to use a 5V buffer to step up the voltage from 3.3V to 5V for reliability. Not sure how any of these might be having a compounding effect on the signal quality to create this correlation with interrupts. I speculate it might also be dependent on how much local Wi-Fi traffic is being processed by the CPU.

cefn commented

Away from the bench right now, but if I recall, the 5V transceiver is this...
http://www.hobbytronics.co.uk/74hc245-octal-transceiver
...and I was using the latest Micropython image 1.9.3 on a NodeMCU v2

Closing due to inactivity. Reopen if this is still an issue.