Hello from an excited and concerned backer!
We got a WeMos D1 Mini board (ESP8266-12F) driving a 240 LED strand using MicroPython 1.8.7 last night but we are a little concerned. Actually we are really happy that it works at all but we could use some advice.
First of all we got a speed of about 1 fps using the neopixel library. We got up to 2 fps by upping the clock rate to 160MHz. Then we found the low level esp.neopixel_write and thought it was the neopixel library taking time converting internal data structures before writing to LEDs. It was not. Instead, most of the time was taken in the main Python for loop simply accessing the 240*3 bytearray!
We've always done C++ on Teensy/ARM but would love Python's interpreted aspect to realize the Burning Man project idea. We also need wireless access and a cheap board so the $4 WeMos is perfect. In the end we got about 150fps by only changing six byte on the bytearray to move a single LED down the strand. We would like to procedually generate all 240 LEDs so that's not a solution.
Is anyone else using MicroPython on ESP8266 to drive 200+ WS8212 LEDs per strand at a decent rate? Any tricks?
Slow bytearray?
Re: Slow bytearray?
You can always write the relevant function in C or assembly, and have the rest in Python.
Re: Slow bytearray?
What exactly do you mean with 'accessing', can you show some code?simply accessing the 240*3 bytearray
-
- Posts: 3
- Joined: Thu Mar 03, 2016 7:42 am
Re: Slow bytearray?
Thanks for the reply!
This is the cleaned up code. All "mode" setting use the esp.neopixel_write to remove that possibility. The other modes are:
0: noop - just write the zero bytearray to the LEDs
1: set six bytes, aka two LEDs to move a single LED across all pixels
2: set all 240*3 values, fading up all LEDs to pink and then starting over.
noop = 142 fps
6 bytes = 125 fps
720 bytes = 27 fps
Why is accessing all bytearray values so slow? Is there is faster way?
This is the cleaned up code. All "mode" setting use the esp.neopixel_write to remove that possibility. The other modes are:
0: noop - just write the zero bytearray to the LEDs
1: set six bytes, aka two LEDs to move a single LED across all pixels
2: set all 240*3 values, fading up all LEDs to pink and then starting over.
noop = 142 fps
6 bytes = 125 fps
720 bytes = 27 fps
Why is accessing all bytearray values so slow? Is there is faster way?
Code: Select all
import utime
import machine
import esp
if __name__ == '__main__':
i = 0
offset = 0
on = False
led = machine.Pin(2, machine.Pin.OUT)
gpio4 = machine.Pin(4, machine.Pin.OUT)
machine.freq(160000000)
rgb = bytearray(240*3)
oldTime = utime.ticks_ms()
mode = 1
while True:
# mode 0: 142 fps
# mode 1: 125 fps
if mode == 1:
rgb[offset*3 + 0] = 0
rgb[offset*3 + 1] = 0
rgb[offset*3 + 2] = 0
offset = offset + 1
offset = offset % 239
rgb[offset*3 + 0] = 0
rgb[offset*3 + 1] = 255
rgb[offset*3 + 2] = 255
# mode 2: 27 fps
elif mode == 2:
for j in range(0, 240*3, 3):
rgb[j + 0] = 0
rgb[j + 1] = offset
rgb[j + 2] = offset
offset = offset + 1
offset = offset % 239
esp.neopixel_write(gpio4, rgb, True)
if on:
led.low()
on = False
else:
led.high()
on = True
newTime = utime.ticks_ms()
print("FPS:", int(1000.0 / utime.ticks_diff(newTime, oldTime)))
oldTime = newTime