§01 控制WS2812
一、研究目标
根据 WS2812 给出了WS2812控制的RGB每个颜色都是 8bit 控制发光强度,扫描的频率不少于400Hz。在 WS2812串行可控彩色LED灯珠 测试了利用ESP32的硬件SPI控制WS2812的显示。下面将会就WS2812的发光特性进行测试,主要问题吧烤鹅:
- WS2812发光扫描频率;
- WS2812发光强度与设置之间的关系。
二、测试方法
1、测量光强
使用 SP-45ML光电管 测量LED的发光强度。通过实验大体可以测量SP-45ML的响应频率大约为25kHz。
▲ 图1.2.1 通过光导纤维将光导入光电管测量模块
设置WS2812的RGB为:0x80,0x0,0x0,测量光强信号的波形如下图所示:
▲ 图1.2.2 设置RGB(0x80, 0x0,0x0)时,光电管输出信号
波形的频率为: 3937Hz,周期为:254us。
2、ESP32程序
编程通过Tonny 的Shell接收外部的输入的命令,可以动态更改WS2812的RGB设置。
from machine import Pin,Timer,SPI
import time
hspi = SPI(1, 3000000, sck=Pin(14), mosi=Pin(13), miso=Pin(12),
polarity=0)
def byte2bin(b):
bstr = bin(b)[2:]
return '0'*(8-len(bstr)) + bstr
def rgb2byte(r,g,b):
str = byte2bin(g) + byte2bin(r) + byte2bin(b)
spistr = ''.join([(lambda s: '011' if s=='0' else '001')(x) for x in str])
rgbdim = [int(spistr[i*8:i*8+8], 2) for i in range(9)]
return bytes(rgbdim)
rgbbyte = rgb2byte(0xff,0x0,0x0)
rstbyte = bytes([0xff]*16)
outbyte = rstbyte+rgbbyte+rstbyte
hspi.write(outbyte)
while True:
str = [int(s, 16) for s in input('Input RGB\n').split()]
print(str)
rgbbyte = rgb2byte(str[0], str[1], str[2])
outbyte = rstbyte+rgbbyte+rstbyte
hspi.write(outbyte)
hspi.write(outbyte)
time.sleep_ms(10)
三、测量结果
1、不同R设置与光强
设置RGB中,R取值不同设置,测量输出光强的波形。
(1)执行程序
from machine import Pin,Timer,SPI
import time
hspi = SPI(1, 3000000, sck=Pin(14), mosi=Pin(13), miso=Pin(12),
polarity=0)
def byte2bin(b):
bstr = bin(b)[2:]
return '0'*(8-len(bstr)) + bstr
def rgb2byte(r,g,b):
str = byte2bin(g) + byte2bin(r) + byte2bin(b)
spistr = ''.join([(lambda s: '011' if s=='0' else '001')(x) for x in str])
rgbdim = [int(spistr[i*8:i*8+8], 2) for i in range(9)]
return bytes(rgbdim)
rgbbyte = rgb2byte(0xff,0x0,0x0)
rstbyte = bytes([0xff]*16)
outbyte = rstbyte+rgbbyte+rstbyte
hspi.write(outbyte)
while True:
str = [int(s, 16) for s in input('Input RGB\n').split()]
print(str)
rgbbyte = rgb2byte(str[0], str[1], str[2])
outbyte = rstbyte+rgbbyte+rstbyte
hspi.write(outbyte)
hspi.write(outbyte)
time.sleep_ms(10)
(2)测量结果
下图显示了随着R的设置从新到大,对应的光强信号。
▲ 图1.3.1 不同R的设置下对应的光强
考虑到 SP-45ML光电管 的频带宽度,所以可以看到随着R的设置逐步增加,光强的占空比增加。
2、不同的RGB设置
(1)同时设置RGB
同时设置RGB为相同的数值,测试光强对的波形。
▲ 图1.3.2 不同的RGB设置对应的光强信号
(2)对比RGB不同设置对应的波形
【Ⅰ.RGB:80 0 0】
▲ 图1.3.3 RGB: 80 0 0 对应的光强
【Ⅱ.RGB:0 80 0】
▲ 图1.3.4 RGB: 0 80 0 对应的光强
【Ⅲ.RGB:0 0 80】
▲ 图1.3.5 RGB: 0 0 80 对应的光强
【Ⅳ.RGB:80 80 0】
▲ 图1.3.6 RGB: 80 80 0 对应的光强
【Ⅴ.RGB:80 80 80】
▲ 图1.3.7 RGB: 80 80 80 对应的光强
3、设置与电压
(1)R的设置于输出电压
测量设置不同的R的占空比,测量得到的光强输出电压。其中出现的图片,实际上对应的是WS2812输出突然出现的RGB都被设置成对应的电压。这说明在输出的信号出现过对应的错误设置。
▲ 图1.3.8 不同的设置R对应光强输出电压
将其中的hspi的波特率设置为2.8MHz,出现的错误就少多了。
▲ 图1.3.9 不同的设置R对应光强输出电压
将波特率设置为3MHz,设置的可靠性更好了。
▲ 图1.3.10 不同的设置R对应光强输出电压
(2)设置G与输出电压
▲ 图1.3.11 设置G不同的强度与光强输出电压
(3)设置不同的B强度
▲ 图1.3.12 不同的B的设置值与光强电压
(4)RGB对比曲线
▲ 图1.3.13 对比RGB的设置与输出电压
§02 级联WS2812
一、同时设置六个WS2812
1、设置相同颜色
while True:
str = [int(s, 16) for s in input('Input RGB\n').split()]
print(str)
rgbbyte = rgb2byte(str[0], str[1], str[2])
outbyte = rstbyte+rgbbyte*6+ff 1rstbyte
hspi.write(outbyte)
hspi.write(outbyte)
time.sleep_ms(10)
▲ 图2.1.1 设置六个RGB显示绿色
2、设置不同颜色
▲ 图2.1.2 设置不同的WS2812
count = 0
LIGHT_NUM = 6
while True:
ldim = [0] * LIGHT_NUM
ldim[count] = 255
outbyte = rstbyte
for l in ldim:
rgbbyte = rgb2byte(l, 0, 0)
outbyte += rgbbyte
outbyte += rstbyte
hspi.write(outbyte)
count += 1
if count >= LIGHT_NUM: count = 0
time.sleep_ms(250)
▲ 图2.1.3 设置不同的LED
※ 实验总结 ※
测试了WS2812的亮度控制特性。它使用了占空比不同来控制不同的亮度。亮度的PWM频率大约8kHz。 设置数值与平均亮度呈现线性。
from machine import Pin,Timer,SPI
import time
hspi = SPI(1, 3000000, sck=Pin(14), mosi=Pin(13), miso=Pin(12),
polarity=0)
def byte2bin(b):
bstr = bin(b)[2:]
return '0'*(8-len(bstr)) + bstr
def rgb2byte(r,g,b):
str = byte2bin(g) + byte2bin(r) + byte2bin(b)
spistr = ''.join([(lambda s: '011' if s=='0' else '001')(x) for x in str])
rgbdim = [int(spistr[i*8:i*8+8], 2) for i in range(9)]
return bytes(rgbdim)
rgbbyte = rgb2byte(0xff,0x0,0x0)
rstbyte = bytes([0xff]*16)
outbyte = rstbyte+rgbbyte+rstbyte
count = 0
LIGHT_NUM = 6
while True:
ldim = [0] * LIGHT_NUM
ldim[count] = 255
outbyte = b''
for l in ldim:
rgbbyte = rgb2byte(l, 0, l)
outbyte += rgbbyte
outbyte += rstbyte
hspi.write(outbyte)
count += 1
if count >= LIGHT_NUM: count = 0
time.sleep_ms(25)
'''
str = [int(s, 16) for s in input('Input RGB\n').split()]
print(str)
rgbbyte = rgb2byte(str[0], str[1], str[2])
outbyte = rstbyte+rgbbyte*6+ff 1rstbyte
hspi.write(outbyte)
hspi.write(outbyte)
time.sleep_ms(10)
'''
■ 相关文献链接:
● 相关图表链接:
- 图1.2.1 通过光导纤维将光导入光电管测量模块
- 图1.2.2 设置RGB(0x80, 0x0,0x0)时,光电管输出信号
- 图1.3.1 不同R的设置下对应的光强
- 图1.3.2 不同的RGB设置对应的光强信号
- 图1.3.3 RGB: 80 0 0 对应的光强
- 图1.3.4 RGB: 0 80 0 对应的光强
- 图1.3.5 RGB: 0 0 80 对应的光强
- 图1.3.6 RGB: 80 80 0 对应的光强
- 图1.3.7 RGB: 80 80 80 对应的光强
- 图1.3.8 不同的设置R对应光强输出电压
- 图1.3.9 不同的设置R对应光强输出电压
- 图1.3.10 不同的设置R对应光强输出电压
- 图1.3.11 设置G不同的强度与光强输出电压
- 图1.3.12 不同的B的设置值与光强电压
- 图1.3.13 对比RGB的设置与输出电压
- 图2.1.1 设置六个RGB显示绿色
- 图2.1.2 设置不同的WS2812
- 图2.1.3 设置不同的LED