Open
Description
A pair of classes to allow I2C communication between two CircuitPython devices via a ring buffer.
I2CRingPeripheral runs on the peripheral device. It provides a ring buffer to which the controller can write.
I2CRemoteRing runs on the controller device.
Asyncio:
The controller can await
while the peripheral is busy.
The peripheral can await
enough bytes to fill a bytearray buffer.
Use Case: Remote NeoPixel Strand
Peripheral: Read five bytes from ring as available, update NeoPixel strand
buffer = bytearray(5)
ring = I2CRingPeripheral(3*5*BYTES, addr=0x29) # allocates enough room for 3 messages of 5 bytes
strand = NeoPixel(pin, 8, brightness=0.2)
while True:
ring.fill(buffer) # read 5 bytes into buffer
if buffer[0] < len(strand):
# write one pixel
strand[buffer[0]]=(ring[1],ring[2],ring[3],ring[4]) #RGBW
else:
# fill the strand
strand.fill(ring[1],ring[2],ring[3],ring[4]) #RGBW
Controller: Send colors to remote NeoPixel strand
def send_pixels(ring: I2CRemoteRing, pixel:int, colors:bytearray) -> None:
while ring.busy:
pass
ring.write(pixel)
ring.write(colors[0])
ring.write(colors[1])
ring.write(colors[2])
ring.write(colors[3])
ring = I2CRemoteRing(addr=0x29)
while True:
# flash first two pixels: RED/BLUE, BLUE/RED
send_pixels(ring, 0, RED)
send_pixels(ring, 1, BLUE)
time.sleep(2)
send_pixels(ring, 0, BLUE)
send_pixels(ring, 1, RED)
time.sleep(2)