Raspberry Pi Pico WS2812B Dice

YouTube Video

Introduction

In this project, we are recreating a previous Raspberry Pi Pico Dice build using WS2812B through-hole LEDs. With three push buttons, you can roll either the left die, the right die, or both dice together using the middle button. The PCB design for this project will to mimic the face patterns of a standard die shown below.

Disclaimer - JLCPCB was generous enough to sponsor this project and provide the PCB used in this project.

Components + Tools Breakdown

ComponentsQuantity
Custom PCB (JLCPB)1
Raspberry Pi Pico1
WS2812B 8mm THT14
2.54 20 pin Header2
12x12 PCB mount buttons3
3D printed enclosure1
Tools / Equipment
Soldering Iron + Solder
Computer + Thonny IDE
Screw driver
3D printer

WS2812B 8mm

I purchased the LEDs online from Taobao and discovered that their pinout was different from the commonly available part. To fix this, I edited the footprint in EasyEDA to match the LEDs I received. For easier soldering, I also changed the pads to oval shapes and slightly staggered the pins.

This is the edited part in EasyEDA. The Din and Dout pins was swapped.

PCB ( JLCPCB )

PCB Design

Once the prototype was working, I designed a custom PCB in EasyEDA.
The schematic for the Pico Dice PCB is shown below:

Here is the PCB layout. As shown, the LEDs are arranged to mimic the face patterns of a standard die.

The PCB was manufactured by JLCPCB, who offer high-quality boards at low cost, often with discounts and coupons available throughout the year. You can support me as a creator by signing up using this link:

https://jlcpcb.com/?from=Nerd that will support me as a creator to keep making content that is accessible and open source at no charge to you.

Ordering the PCB is very simple:

Download the Gerber file here.

Click on Add Gerber file

leave all the settings as default given. You might want change the PCB color which you can do here:

Enter you shipping details, save to cart

Then after a few days depending on your location you will receive your great quality PCB.

Final Code

from machine import Pin
import utime
import urandom

urandom.seed(utime.ticks_us())


# Define the LED pins for the two dice
dice1_leds = [Pin(i, Pin.OUT) for i in range(0, 7)]
dice2_leds = [Pin(i, Pin.OUT) for i in range(7, 14)]

# Define the button pins
button1 = Pin(14, Pin.IN, Pin.PULL_DOWN)
button2 = Pin(15, Pin.IN, Pin.PULL_DOWN)
button3 = Pin(16, Pin.IN, Pin.PULL_DOWN)

# Define the LED patterns for each number
numbers = [
    [0, 0, 0, 1, 0, 0, 0],  # 1
    [1, 0, 0, 0, 0, 0, 1],  # 2
    [1, 0, 0, 1, 0, 0, 1],  # 3
    [1, 1, 0, 0, 0, 1, 1],  # 4
    [1, 1, 0, 1, 0, 1, 1],  # 5
    [1, 1, 1, 0, 1, 1, 1],  # 6
]

# Function to turn off LEDs of a specific dice
def turn_off_leds(dice_leds):
    for led in dice_leds:
        led.value(0)

# Function to show a number on the dice
def show_number(dice_leds, number):
    # Get the LED pattern for the number
    pattern = numbers[number - 1]
    
    # Loop over each LED in the dice
    for i in range(len(dice_leds)):
        # Get the corresponding LED and its value from the pattern
        led = dice_leds[i]
        value = pattern[i]
        
        # Set the LED to the value from the pattern
        led.value(value)

# Main loop
while True:
    if button1.value() == 1:
        utime.sleep(0.3)  # Wait for 2 seconds to ensure the button is pressed long enough
        if button1.value() == 1:  # Check again if the button is still pressed
            utime.sleep_ms(urandom.randint(0, 200))  # Random delay before generating the number
            show_number(dice1_leds, urandom.randint(1, 6))
            utime.sleep(2)  # Keep the LEDs on for 5 seconds
            turn_off_leds(dice1_leds)  # Then turn them off
    elif button2.value() == 1:
        utime.sleep(0.3)
        if button2.value() == 1:
            utime.sleep_ms(urandom.randint(0, 200))  # Random delay before generating the number
            dice1_number = urandom.randint(1, 6)
            dice2_number = urandom.randint(1, 6)
            show_number(dice1_leds, dice1_number)
            show_number(dice2_leds, dice2_number)
            utime.sleep(3)  # Keep the LEDs on for 5 seconds
            turn_off_leds(dice1_leds)  # Then turn them off
            turn_off_leds(dice2_leds)  # Then turn them off
    elif button3.value() == 1:
        utime.sleep(0.3)
        if button3.value() == 1:
            utime.sleep_ms(urandom.randint(0, 200))  # Random delay before generating the number
            show_number(dice2_leds, urandom.randint(1, 6))
            utime.sleep(2)  # Keep the LEDs on for 5 seconds
            turn_off_leds(dice2_leds)  # Then turn them off
    utime.sleep_ms(10)  # Short delay to debounce the buttons

Enclosure

The enclosure was designed in Fusion 360.

You can download all the 3D files here: Link

Conclusion

This is a simple but fun project, and it makes a great introduction for beginners learning soldering, coding, and 3D modeling.

If you have any questions, feel free to leave a comment on my YouTube video. And while youโ€™re there, consider subscribing to the channel to support more open-source projects like this one.