Open SeppeBudenaers opened 9 months ago
Great source to learn more about ws28x ledstrips.
For programming the WS2813 ledstrip on the pico we used the standard neopixel.py library. A ZIP-folder containing the files to be installed here. (If you don't now how to transfer this library to the pico here is a link on how to transfer files using thonny).
1) Upload the code below to the pico:
import time
from neopixel import Neopixel
numpix = 14
pixels = Neopixel(numpix, 0, 28, "RGB")
green = (0, 255, 0)
blue = (0, 0, 255)
red = (255, 0, 0)
color0 = green
color1 = blue
pixels.brightness(50)
pixels.fill(blue)
while True:
if color0 == green:
color0 = blue
color1 = green
else:
color0 = green
color1 = blue
pixels.set_pixel(3, color0)
pixels.set_pixel(4, color1)
pixels.show()
time.sleep(1)
2) When this code is uploaded to the pico and the ledstrip is connected. All the leds should turn blue and the third and fourth led should switch colors between blue and green. We can see that the pixel.fill() function is used to turn all the leds to the same color. This can come in handy for the game code. This code is verified and works.
Seppe and Kobe will take over this ticket.
because we could not get machine to work inside of a docker we used a SPI kernelmodule and made a custom ws2812 library to convert R
G
B
Brightness
values into a ws2812 data stream
from dataclasses import dataclass
@dataclass
class RGBdata:
RED: int
GREEN: int
BLUE: int
BRIGHTNESS: int
def __init__(self, red: int = 0, green: int = 0, blue: int = 0, brightness: int =0):
def limit_to_8bits(value):
return value & 0xFF
self.RED = limit_to_8bits(red)
self.BLUE = limit_to_8bits(blue)
self.GREEN = limit_to_8bits(green)
self.BRIGHTNESS = limit_to_8bits(brightness)
def output_bytes(self) -> bytes:
# Calculate RGB values with brightness adjustment
red_value = int(self.RED * self.BRIGHTNESS/255 )
green_value = int(self.GREEN * self.BRIGHTNESS/255)
blue_value = int(self.BLUE * self.BRIGHTNESS/255)
# Pack RGB values into a 3-byte representation (bytes)
output = bytes([blue_value, red_value, green_value])
return output
def colors(self):
output: str = " "+str(self.RED) +" "+ str(self.GREEN) +" "+ str(self.BLUE) +" "+ str(self.BRIGHTNESS)
return output
@dataclass
class Neopixel:
def __init__(self, count: int =0):
self.pixels = [RGBdata()] * count
pixels = []
def colors(self):
output_list = []
index = 0
for pixel in self.pixels:
output_list.append("LED" + str(index) + self.pixels[index].colors())
index += 1
return ' '.join(output_list)
def set_pixel(self,pixel: int , input: RGBdata):
self.pixels[pixel] = input
return 0
def fill(self, input: RGBdata):
self.pixels = [input] * len(self.pixels)
return 0
def ws2812_Data(self):
outputArray = [0] * (len(self.pixels) * 24)
index = 0
for pixel in self.pixels:
color = pixel.output_bytes()
for i in range(23, -1, -1):
byte_index = i // 8
bit_index = 7 - (i % 8)
if ((color[byte_index] >> bit_index) & 0x01) == 1:
outputArray[index] = 0b11111000 # store 1
else:
outputArray[index] = 0b11100000 # store 0
index += 1
return bytes(outputArray)
The important part is the last function called
ws2812_Data(self)
SPI
this WS2812 data pact than gets send over SPI with the help of the
SPIDEV
kernel module at around6.25 Mhz
to6.75 Mhz
#SPI spi = spidev.SpiDev() spi.open(0,0) # open /dev/spidev0.0 spi.mode = 0b00 spi.max_speed_hz = 6000000*2
leds = Neopixel(1) leds.fill(RGBdata(255, 200, 0, 100)) print(leds.colors()) oldData = RGBdata(0,0,0,0) newData = RGBdata(0,0,0,0)
leds.fill(RGBdata(0,0,0,0)) spi.writebytes2(leds.ws2812_Data())
> please make sure when you use give the docker container access to `spidev0.0`
Epic : #8