树莓派-Pico控制WS2812

发布时间:2023年12月21日


前言(制作缘由)

  • 前段时间给家里设计了一款床头灯哈,那为啥自己设计呢?
    -因为想省钱。看上的那些带有设计感的床头灯较贵,买两个下来得两三百,看着就心疼。
  • 自己设计有啥好处呢?
    -很简单,就是造型全凭自己模仿与想象,可以做成自己想要的样子。
  • 那又为啥用到了WS2812呢?
    -既然是控制灯的,那就来点小花样呗,常规的线条LED灯带改为了WS2812灯带,主打的就是灯光效果、颜色、启动特效可自定义。

于是呢,总共的费用也是达到了200+(\哭笑)
玩玩而已,开心就好~


一、有啥设计方案?

设计的几个方案

二、选择的方案

设计了好几个方案,最终选择了最后一种,原因就是几个方案相对来说省点钱,并且不用走明线,直接挡住出线孔就行。
最终选择方案

三、效果图

装灯前
装灯后

四、树莓派-Pico控制WS2812的代码

提示:
以下代码的效果呢是一直循环随机变换颜色和亮灯模式的。

WS2812接板子上的5VGND,控制端接GPIO0

# Example using PIO to drive a set of WS2812 LEDs.

import array, time, random
from machine import Pin
import rp2

# Configure the number of WS2812 LEDs.
NUM_LEDS = 57
PIN_NUM = 0
brightness = 0.5


@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
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[1] << 16) + (color[0] << 8) + color[2]


def pixels_fill(color):
    for i in range(len(ar)):
        pixels_set(i, color)


def color_chase(color, wait):  # 颜色,等待时间
    for i in range(NUM_LEDS):  # 用灯的个数来遍历
        print(i)
        pixels_set(i, color)  # 单个灯(像素)设置颜色
        time.sleep(wait)
        pixels_show()
    # time.sleep(0.2)


def color_chase1(color, wait):  # 颜色,等待时间
    num_leds = int(NUM_LEDS / 2)
    for i in range(num_leds + 1):  # 用灯的个数来遍历
        if i == 0:
            print('当前输出:', i, ' ', i, '\n')
            pixels_set(num_leds, color)  # 单个灯(像素)设置颜色
            
        elif i == num_leds:
            print('当前输出:', i, ' ', i, '11111\n')
            pixels_set(0, color)  # 单个灯(像素)设置颜色
            
        else:
            print('当前输出:', i, ' ', num_leds + i)
            print('当前输出:', i, ' ', num_leds - i, '\n')
            pixels_set(num_leds + i, color)  # 单个灯(像素)设置颜色
            pixels_set(num_leds - i, color)  # 单个灯(像素)设置颜色

        # pixels_set(i, color)  # 单个灯(像素)设置颜色
        time.sleep(wait)
        pixels_show()

def color_chase2(color, wait):  # 颜色,等待时间
    num_leds = int(NUM_LEDS / 2)
    for i in range(num_leds + 1):  # 用灯的个数来遍历
        if i == 0:
            print('当前输出:', i, ' ', i, '\n')
            pixels_set(0, color)  # 单个灯(像素)设置颜色
            
            
        elif i == num_leds:
            print('当前输出:', i, ' ', i, '11111\n')
            pixels_set(num_leds, color)  # 单个灯(像素)设置颜色
            
        else:
            print('当前输出:', i, ' ', num_leds + i)
            print('当前输出:', i, ' ', num_leds - i, '\n')
            pixels_set(i, color)  # 单个灯(像素)设置颜色
            pixels_set(NUM_LEDS - i, color)  # 单个灯(像素)设置颜色

        # pixels_set(i, color)  # 单个灯(像素)设置颜色
        time.sleep(wait)
        pixels_show()

def color_chase3(color, wait):  # 颜色,等待时间
    num_leds = int(NUM_LEDS / 2)
    for i in range(NUM_LEDS):  # 用灯的个数来遍历
        if i == 0:
            print('当前输出:', i, ' ', i, '\n')
            pixels_set(0, color)  # 单个灯(像素)设置颜色
            
            
        elif i == NUM_LEDS:
            print('当前输出:', i, ' ', i, '11111\n')
            pixels_set(NUM_LEDS, color)  # 单个灯(像素)设置颜色
            
        else:
            print('当前输出:', i, ' ', NUM_LEDS + i)
            print('当前输出:', i, ' ', NUM_LEDS - i, '\n')
            
            for ii in range(NUM_LEDS):
                if ii == i:
                    pixels_set(i, color)  # 单个灯(像素)设置颜色
                else:
                    pixels_set(ii, BLACK)  # 单个灯(像素)设置颜色
            
        # pixels_set(i, color)  # 单个灯(像素)设置颜色
        time.sleep(wait)
        pixels_show()

def color_chase4(color, wait):  # 颜色,等待时间
    num_leds = int(NUM_LEDS / 2)
    for i in range(num_leds+1):  # 用灯的个数来遍历
        if i == 0:
            print('当前输出:', i, ' ', i, '\n')
            pixels_set(0, color)  # 单个灯(像素)设置颜色
            pixels_set(num_leds, color)  # 单个灯(像素)设置颜色
            
        elif i == num_leds :
            print('当前输出:', i, ' ', i, '11111\n')
            for iii in range(NUM_LEDS):
                pixels_set(iii, BLACK)  # 单个灯(像素)设置颜色
            pixels_set(0, color)  # 单个灯(像素)设置颜色
            pixels_set(num_leds, color)  # 单个灯(像素)设置颜色
            
        else:
            print('当前输出:', i, ' ', NUM_LEDS + i)
            print('当前输出:', i, ' ', NUM_LEDS - i, '\n')
            
            for ii in range(NUM_LEDS):
                if ii == i:
                    pixels_set(i, color)  # 单个灯(像素)设置颜色
                elif ii == i + num_leds:
                    pixels_set(i + num_leds, color)
                else:
                    pixels_set(ii, BLACK)  # 单个灯(像素)设置颜色
            
        # pixels_set(i, color)  # 单个灯(像素)设置颜色
        time.sleep(wait)
        pixels_show()

def wheel(pos):
    # Input a value 0 to 255 to get a color value.
    # The colours are a transition r - g - b - back to r.
    if pos < 0 or pos > 255:
        return (0, 0, 0)
    if pos < 85:
        return (255 - pos * 3, pos * 3, 0)
    if pos < 170:
        pos -= 85
        return (0, 255 - pos * 3, pos * 3)
    pos -= 170
    return (pos * 3, 0, 255 - pos * 3)


def rainbow_cycle(wait):
    for j in range(255):
        for i in range(NUM_LEDS):
            rc_index = (i * 256 // NUM_LEDS) + j
            pixels_set(i, wheel(rc_index & 255))
        pixels_show()
        time.sleep(wait)


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)

# print("颜色填充")
# for color in COLORS:
#     pixels_fill(color)
#     pixels_show()
#     time.sleep(0.2)

# print("彩虹色")
# while 1:
#     rainbow_cycle(0)

print("颜色追逐")
while 1:
    RANDOM_COLORS = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
    print(RANDOM_COLORS)
    color_chase1(RANDOM_COLORS, 0.05)
    RANDOM_COLORS = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
    color_chase2(RANDOM_COLORS, 0.05)
    RANDOM_COLORS = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
    color_chase3(RANDOM_COLORS, 0.05)
    RANDOM_COLORS = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
    color_chase4(RANDOM_COLORS, 0.05)

print("颜色追逐")
while 1:
    RANDOM_COLORS = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
    print(RANDOM_COLORS)
    color_chase1(RANDOM_COLORS, 0.05)
    RANDOM_COLORS = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
    color_chase2(RANDOM_COLORS, 0.05)
    RANDOM_COLORS = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
    color_chase3(RANDOM_COLORS, 0.05)
    RANDOM_COLORS = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
    color_chase4(RANDOM_COLORS, 0.05)

将以上代码改为以下代码即可。

print("颜色追逐")
color_chase1(YELLOW, 0.05)

目前自己写了四种流水灯的模式,可能不适用与WS2812灯带,选择合适即可,当然还需要自己添加一些代码的。

color_chase1(YELLOW, 0.05)
color_chase2(YELLOW, 0.05)
color_chase3(YELLOW, 0.05)
color_chase4(YELLOW, 0.05)

总结

弄完之后其实感觉这床头灯还是差了很多东西,不尽人意。首先木板选短了10cm,没能完全遮住墙壁上的出线孔,需要后期买点什么东西延长挡住它。


2023.12.21写

文章来源:https://blog.csdn.net/qq_46476163/article/details/135133873
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。