In this article we connect a WS2812 module to a Raspberry Pi Pico and we will use micropython to display various colours on the module. The WS2812 can also be known as neopixels, this is Adafruits naming of the module
I used the following WS2812 board, there are several different variations with different amount of leds fitted
The WS2812 is rated at 5v and I have seen it recommended that the power should be at minimum 70% of this. I have tried various 3.3v microcontrollers and have not seen an issue driving them but you should be aware that you may not get so lucky in that case you may need a level shifter
The following is from the datasheet
WS2812 is a intelligent control LED light source that the control circuit and RGB chip are integrated in a package of 5050 components. It internal include intelligent digital port data latch and signal reshaping amplification drive circuit. Also include a precision internal oscillator and a 12V voltage programmable constant current control part, effectively ensuring the pixel point light color height consistent.
The data transfer protocol use single NZR communication mode. After the pixel power-on reset, the DIN port receive data from controller, the first pixel collect initial 24bit data then sent to the internal data latch, the other data which reshaping by the internal signal reshaping amplification circuit sent to the next cascade pixel through the DO port. After transmission for each pixel，the signal to reduce 24bit. pixel adopt auto reshaping transmit technology, making the pixel cascade number is not limited the signal transmission, only depend on the speed of signal transmission.
LED with low driving voltage, environmental protection and energy saving, high brightness, scattering angle is large, good consistency, low power, long life and other advantages. The control chip integrated in LED above becoming more simple circuit, small volume, convenient installation
I used an expander with the raspberry pi pico fitted to it but you can quite easily connect the neopixel module directly to the board with cables
|Raspberry Pi Pico||pimoroni|
|Neopixel||AliExpress.com Product – 7 Bits LEDs WS2812 5050 RGB LED Ring Lamp Light with Integrated Drivers For Arduino|
|Connecting cables||Free shipping Dupont line 120pcs 20cm male to male + male to female and female to female jumper wire|
An easy nodule to connect, you simply need to supply 3.3v and gnd for power and pick a GPIO pin for the output. I picked 16 but you can pick a different one but you will have to change the code
I used the thonny IDE that supports Micropython on the Raspberry Pi Pico
There is already a ws2812 example, this is an adapted version which goes through various colours
import array, time from machine import Pin import rp2 # Configure the number of WS2812 LEDs, pins and brightness. NUM_LEDS = 7 PIN_NUM = 16 brightness = 0.1 @rp2.asm_pio(sideset_init=rp2.PIO.OUT_LOW, out_shiftdir=rp2.PIO.SHIFT_LEFT, autopull=True, pull_thresh=24) def ws2812(): T1 = 2 T2 = 5 T3 = 3 wrap_target() label("bitloop") out(x, 1) .side(0) [T3 - 1] jmp(not_x, "do_zero") .side(1) [T1 - 1] jmp("bitloop") .side(1) [T2 - 1] label("do_zero") nop() .side(0) [T2 - 1] wrap() # Create the StateMachine with the ws2812 program, outputting on Pin(16). sm = rp2.StateMachine(0, ws2812, freq=8_000_000, sideset_base=Pin(PIN_NUM)) # Start the StateMachine, it will wait for data on its FIFO. sm.active(1) # Display a pattern on the LEDs via an array of LED RGB values. ar = array.array("I", [0 for _ in range(NUM_LEDS)]) def pixels_show(): dimmer_ar = array.array("I", [0 for _ in range(NUM_LEDS)]) for i,c in enumerate(ar): r = int(((c >> 8) & 0xFF) * brightness) g = int(((c >> 16) & 0xFF) * brightness) b = int((c & 0xFF) * brightness) dimmer_ar[i] = (g<<16) + (r<<8) + b sm.put(dimmer_ar, 8) time.sleep_ms(10) def pixels_set(i, color): ar[i] = (color<<16) + (color<<8) + color def pixels_fill(color): for i in range(len(ar)): pixels_set(i, color) BLACK = (0, 0, 0) RED = (255, 0, 0) YELLOW = (255, 150, 0) GREEN = (0, 255, 0) CYAN = (0, 255, 255) BLUE = (0, 0, 255) PURPLE = (180, 0, 255) WHITE = (255, 255, 255) COLORS = (BLACK, RED, YELLOW, GREEN, CYAN, BLUE, PURPLE, WHITE) for color in COLORS: pixels_fill(color) pixels_show() time.sleep(0.5)
Save this and upload it to your Pico and if you are using the Thonny IDE run it