@brossingo I simplified the neopixel demo code using RMT a little bit. Also, I made a similar short function using SPI. It works to some extend (better than the other SPI driver), but the problem is the unpredictable timing of SPI. It had gaps between the words it sends, which the disturbs the communication.
Here is the RMT variant
from machine import RMT
from time import sleep
def send_rmt(data, rmt):
from time import sleep_us
no_pixel = len(data)
bits = bytearray(no_pixel * 24 * 2)
duration = bytearray(no_pixel * 24 * 2)
index = 0
for pixel in data:
for byte in pixel:
mask = 0x80
while mask:
bits[index] = 1
bits[index+1] = 0
if byte & mask:
duration[index] = 8
duration[index+1] = 4
else:
duration[index] = 4
duration[index+1] = 8
index += 2
mask >>= 1
sleep_us(60) # wait for the reset time
rmt.pulses_send(tuple(duration), tuple(bits))
sleep_us(60) # wait for the reset time
data = 6 * [
(127, 0, 0), # green
(0, 127, 0), # red
(0, 0, 127), # blue
]
blank = 24 * [(0,0,0)]
rmt = RMT(channel=3, gpio="P11", tx_idle_level=0)
while True:
send_rmt(data, rmt)
sleep(1)
send_rmt(blank, rmt)
sleep(1)
And here is the SPI variant:
from machine import SPI, disable_irq, enable_irq
from time import sleep, sleep_us
def send_spi(data, spi):
no_pixel = len(data)
buffer = bytearray(no_pixel * 3 * 4)
index = 0
for pixel in data:
for byte in pixel:
bits = 0
mask = 0x80
while mask:
bits <<= 4
if byte & mask:
bits |= 0x0e
else:
bits |= 0x08
mask >>= 1
buffer[index] = (bits >> 24) & 0xff
buffer[index + 1] = (bits >> 16) & 0xff
buffer[index + 2] = (bits >> 8) & 0xff
buffer[index + 3] = bits & 0xff
index += 4
sleep_us(60) # ensure initial reset
state = disable_irq()
spi.write(buffer)
enable_irq(state)
data = 6 * [
(85, 0, 0), # green
(0, 85, 0), # red
(0, 0, 85), # blue
(85, 85, 85), # white
]
blank = 24 * [(0,0,0)]
spi = SPI(SPI.MASTER, baudrate=3200000, polarity = 0, firstbit = SPI.MSB, bits=32)
while True:
send_spi(data, spi)
sleep(1)
send_spi(blank, spi)
sleep(1)