【得捷电子Follow me第1期】006:摇摇灯设计
[复制链接]
上一帖介绍利用3轴数字加速度计做一个简易水平仪。这一贴介绍在水平仪基础上添加WS2812B灯珠做一个摇摇灯。参考GitHub上的文档和代码,我的试验过程如下。
首先介绍一下WS2812B灯珠。WS2812B是一个集控制电路与发光电路于一体的智能外控LED光源,内置RGB三色灯珠,每个灯珠控制需要24位数据,8Bit绿色亮度+8Bit红色亮度+8Bit蓝色亮度,每个像素点的三基色颜色可实现256级亮度显示,完成16777216种颜色的全真色彩显示。多个灯珠组合在一起可形成灯带,灯带上的灯珠供电并联,信号线“串联”。信号由DI进到灯珠,灯珠在锁存24Bit数据后,将剩余数据整形放大后通过DO端口输出给下一个级联的灯珠,每经过一个灯珠的传输,信号减少24bit。当灯珠接收到280μs以上的RESET数据,灯珠根据自己锁存的数据完成对RGB三色灯的控制。
图1、WS2812B彩灯
我买这个WS2812B灯珠是用来凑单的,剩余额度只够买了三颗灯珠。下面我就把这三个灯珠焊一起,串联使用。电路原理如下图。
图2、WS2812B原理图
电源采用开发板上的VBUS(5V)供电,串行数据输入使用GP22接口。下图是焊接好的三颗灯珠,我把它们固定到一个硬纸板上,和底板接口也都打胶加固。
图3、灯珠焊接完成
顺路的,我给Pico W小板加了一个复位键,不然有时候运行程序死机后,只能把电源才能解决,比较麻烦。复位键的原理就是在RUN引脚和地之间加一个按键,需要复位时,按下接地,Pico W小板就复位了。为了方便使用,我直接把按键焊接在了WiFi屏蔽罩上,为了防止短路,按键另一半下面垫了一层美纹纸,看起来毫不违和。如下图。
图4、Pico W复位键
为了实现摇摇灯,需要把灯珠和加速度计模块绑定到一起。我先在加速度计模背面粘贴美纹纸和双面胶,然后把灯珠板粘在加速度计模背面,让它们构成一个整体,如下图。
图5、粘贴灯珠
硬件搭建好后,接下来设计程序。按照管理,先从GitHub上找现成的库,这里我选用了NeoPixel library,这个库附带好几个例程,可以快速上手。GitHub的链接如下:
为了让颜色变化时,过渡的更丝滑、自然,我选用NeoPixel library的HSV颜色空间。其中,色调(H)取值范围为0-65536,饱和度(S)取值范围为0-255,亮度(V)取值范围为0-255。具体的颜色变化如下图。
图7、HSV颜色空间
如果有同学想了解更细的关于NeoPixel library的HSV颜色空间详细信息,可以参见如下链接:
https://learn.adafruit.com/adafruit-neopixel-uberguide/arduino-library-use#hsv-hue-saturation-value-colors-dot-dot-dot-3024464
具体的程序是在水平仪的基础上改造的,代码如下。
from machine import Pin,I2C
from ssd1306 import SSD1306_I2C
import math
import time
from micropython_lis3dh import lis3dh
from neopixel import Neopixel
def numberMap(x, in_min, in_max, out_min, out_max):
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
led = machine.Pin('LED', machine.Pin.OUT)
numpix = 3
strip = Neopixel(numpix, 0, 22, "GRB")
i2c0 = machine.I2C(0,sda=machine.Pin("GP8"), scl=machine.Pin("GP9"), freq=400000)
lis = lis3dh.LIS3DH(i2c0)
i2c1=machine.I2C(1, sda=machine.Pin("GP6"), scl=machine.Pin("GP7"), freq=400000)
oled = SSD1306_I2C(128, 64, i2c1)
oled.fill(0)
oled.show()
oled.text("hello eeworld",5,10)
oled.show()
time.sleep(0.1)
oled.fill(0)
Center_x=63 #设定中心点(原点)x的坐标
Center_y=31 #设定中心点(原点)y的坐标
offsetX = 0
offsetY = 0
oled.rect(20,25,8,8,1) #绘制起始坐标(60, 25),宽30,高25的矩形
oled.fill_rect(80,25,4,4,1) #绘制起始坐标(100, 25),宽20,高25填充满颜色的矩形
oled.show()
lis.data_rate = lis3dh.DATARATE_200
hue = 0
sat = 0
val = 0
while True:
accx,accy,accz = lis.acceleration
x=accx #获取X轴的加速度
y=accy #获取Y轴的加速度
z=accz #获取Z轴的加速度
if y<=10 and y>=-10:
offsetX =int(numberMap(y,10,-10,-64,64)) #映射Y轴偏移值
if x<=10 and x>=-10:
offsetY =int(numberMap(x,10,-10,32,-32)) #映射X轴偏移值
move_x=Center_x + offsetX #水平球在X坐标上的移动
move_y=Center_y + offsetY #水平球在Y坐标上的移动
'''
print("X: ", x)
print("offsetX: ", offsetX)
print("Y: ", y)
print("offsetY: ", offsetY)
print("----------")
'''
oled.rect(Center_x-2,Center_y-2,8,8,1) #画中心固定圆:空心
oled.fill_rect(move_x,move_y,4,4,1) #画移动的水平球:实心
oled.text("%0.1f,%0.1f" %(x,y),0,0) #显示水平球在X、Y轴的加速度值
if offsetX==0 and offsetY==0:
led.on() #水平球在中心位置亮绿灯,亮度为10
else:
led.off() #水平球不在中心位置灭灯
oled.show()
time.sleep(0.1)
oled.fill(0)
if y<=10 and y>=-10:
hue =int(numberMap(y,10,-10,0,32767)) #映射Y轴偏移值
if x<=10 and x>=-10:
val =int(numberMap(x,10,-10,0,32767)) #映射X轴偏移值
hue = hue + val
sat = 255
val = 2
color = strip.colorHSV(hue, sat, val)
strip.fill(color)
strip.show()
代码1、摇摇灯程序
经过多次尝试改进,运行效果如下视频,其中为了防止炫光影响拍摄效果,我用纸巾把灯珠包了起来,起到灯罩的作用,就是有点难看,各位看官别嫌弃。
a88bee8722e3f35b74f585fb201d0eaa
视频1、摇摇灯演示
参考资料:
https://www.cnblogs.com/arxive/p/7008460.html
|