TA的每日心情 | 慵懒 2018-1-6 09:01 |
---|
签到天数: 7 天 连续签到: 1 天 [LV.3]偶尔看看II
|
一、实验目的
了解ws2812b的工作原理
学习ws2812b的驱动方法
二、实验器材
TPYBoard v102 1块
ws2812b RGB-Ring-8 1个
micro USB数据线 1条
杜邦线 若干
三、WS2812B的介绍
WS2812B是一个集控制电路与发光电路于一体的智能外控LED光源。 其外型与一个5050LED灯珠相同, 每个元件即为一个像素点。像素点内部包含了智能数字接口数据锁存信号整形放大驱动电路, 还包含有高精度的内部振荡器和可编程定电流控制部分, 有效保证了像素点光的颜色高度一致。
数据协议采用单线归零码的通讯方式, 像素点在上电复位以后, DIN端接受从控制器传输过来的数据, 首先送过来的24bit数据被第一个像素点提取后, 送到像素点内部的数据锁存器, 剩余的数据经过内部整形处理电路整形放大后通过DO端口开始转发输出给下一个级联的像素点, 每经过一个像素点的传输, 信号减少24bit。像素点采用自动整形转发技术, 使得该像素点的级联个数不受信号传送的限制, 仅仅受限信号传输速度要求。
实物图
上图是8个灯珠的。
WS2812B的引脚说明:
硬件连接
将TPYBoard v102与WS2812B的接线示意图,如下:
程序源码如下:
- import pyb
- import math
-
- from ws2812 import WS2812
-
-
- ring = WS2812(spi_bus=1, led_count=8, intensity=0.1)
-
-
- def data_generator(led_count):
- data = [(0, 0, 0) for i in range(led_count)]
- step = 0
- while True:
- red = int((1 + math.sin(step * 0.1324)) * 127)
- green = int((1 + math.sin(step * 0.1654)) * 127)
- blue = int((1 + math.sin(step * 0.1)) * 127)
- data[step % led_count] = (red, green, blue)
- yield data
- step += 1
-
-
- for data in data_generator(ring.led_count):
- ring.show(data)
- pyb.delay(100)
复制代码
里面还需要引入一个ws2812.py 文件。内容如下:
- import gc
- import pyb
-
-
- class WS2812:
- """
- Driver for WS2812 RGB LEDs. May be used for controlling single LED or chain
- of LEDs.
-
- Example of use:
-
- chain = WS2812(spi_bus=1, led_count=4)
- data = [
- (255, 0, 0), # red
- (0, 255, 0), # green
- (0, 0, 255), # blue
- (85, 85, 85), # white
- ]
- chain.show(data)
-
- Version: 1.0
- """
- buf_bytes = (0x11, 0x13, 0x31, 0x33)
-
- def __init__(self, spi_bus=1, led_count=1, intensity=1):
- """
- Params:
- * spi_bus = SPI bus ID (1 or 2)
- * led_count = count of LEDs
- * intensity = light intensity (float up to 1)
- """
- self.led_count = led_count
- self.intensity = intensity
-
- # prepare SPI data buffer (4 bytes for each color)
- self.buf_length = self.led_count * 3 * 4
- self.buf = bytearray(self.buf_length)
-
- # SPI init
- self.spi = pyb.SPI(spi_bus, pyb.SPI.MASTER, baudrate=3200000, polarity=0, phase=1)
-
- # turn LEDs off
- self.show([])
-
- def show(self, data):
- """
- Show RGB data on LEDs. Expected data = [(R, G, B), ...] where R, G and B
- are intensities of colors in range from 0 to 255. One RGB tuple for each
- LED. Count of tuples may be less than count of connected LEDs.
- """
- self.fill_buf(data)
- self.send_buf()
-
- def send_buf(self):
- """
- Send buffer over SPI.
- """
- self.spi.send(self.buf)
- gc.collect()
-
- def update_buf(self, data, start=0):
- """
- Fill a part of the buffer with RGB data.
-
- Order of colors in buffer is changed from RGB to GRB because WS2812 LED
- has GRB order of colors. Each color is represented by 4 bytes in buffer
- (1 byte for each 2 bits).
-
- Returns the index of the first unfilled LED
-
- Note: If you find this function ugly, it's because speed optimisations
- beated purity of code.
- """
-
- buf = self.buf
- buf_bytes = self.buf_bytes
- intensity = self.intensity
-
- mask = 0x03
- index = start * 12
- for red, green, blue in data:
- red = int(red * intensity)
- green = int(green * intensity)
- blue = int(blue * intensity)
-
- buf[index] = buf_bytes[green >> 6 & mask]
- buf[index+1] = buf_bytes[green >> 4 & mask]
- buf[index+2] = buf_bytes[green >> 2 & mask]
- buf[index+3] = buf_bytes[green & mask]
-
- buf[index+4] = buf_bytes[red >> 6 & mask]
- buf[index+5] = buf_bytes[red >> 4 & mask]
- buf[index+6] = buf_bytes[red >> 2 & mask]
- buf[index+7] = buf_bytes[red & mask]
-
- buf[index+8] = buf_bytes[blue >> 6 & mask]
- buf[index+9] = buf_bytes[blue >> 4 & mask]
- buf[index+10] = buf_bytes[blue >> 2 & mask]
- buf[index+11] = buf_bytes[blue & mask]
-
- index += 12
-
- return index // 12
-
- def fill_buf(self, data):
- """
- Fill buffer with RGB data.
-
- All LEDs after the data are turned off.
- """
- end = self.update_buf(data)
-
- # turn off the rest of the LEDs
- buf = self.buf
- off = self.buf_bytes[0]
- for index in range(end * 12, self.buf_length):
- buf[index] = off
- index += 1
复制代码
本次参考的github上的一个项目。项目地址:
https://github.com/JanBednarik/micropython-ws2812
给大家看一下效果(额 最后一个灯珠坏了 大家可以自行忽略……)
https://v.qq.com/x/page/d05297wxo1b.html
|
|