查看: 3508|回复: 1

MicroPython实例之TPYBoard v102炫彩跑马灯WS2812B

[复制链接]
  • TA的每日心情
    慵懒
    2018-1-6 09:01
  • 签到天数: 7 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    发表于 2018-6-11 15:25:34 | 显示全部楼层 |阅读模式
    分享到:
        一、实验目的

        了解ws2812b的工作原理
        学习ws2812b的驱动方法

        二、实验器材

        TPYBoard v102 1块
        ws2812b RGB-Ring-8 1个
        micro USB数据线 1条
        杜邦线 若干

        三、WS2812B的介绍

        WS2812B是一个集控制电路与发光电路于一体的智能外控LED光源。 其外型与一个5050LED灯珠相同, 每个元件即为一个像素点。像素点内部包含了智能数字接口数据锁存信号整形放大驱动电路, 还包含有高精度的内部振荡器和可编程定电流控制部分, 有效保证了像素点光的颜色高度一致。

        数据协议采用单线归零码的通讯方式, 像素点在上电复位以后, DIN端接受从控制器传输过来的数据, 首先送过来的24bit数据被第一个像素点提取后, 送到像素点内部的数据锁存器, 剩余的数据经过内部整形处理电路整形放大后通过DO端口开始转发输出给下一个级联的像素点, 每经过一个像素点的传输, 信号减少24bit。像素点采用自动整形转发技术, 使得该像素点的级联个数不受信号传送的限制, 仅仅受限信号传输速度要求。

        实物图
        11.jpg

        上图是8个灯珠的。
        WS2812B的引脚说明:
    1.png

        硬件连接
        将TPYBoard v102与WS2812B的接线示意图,如下:

    2.png

        程序源码如下:
    1. import   pyb
    2. import   math
    3.   
    4. from   ws2812 import WS2812
    5.   
    6.   
    7. ring   = WS2812(spi_bus=1, led_count=8, intensity=0.1)
    8.   
    9.   
    10. def   data_generator(led_count):
    11.     data = [(0, 0, 0) for i in   range(led_count)]
    12.     step = 0
    13.     while True:
    14.         red = int((1 + math.sin(step *   0.1324)) * 127)
    15.         green = int((1 + math.sin(step *   0.1654)) * 127)
    16.         blue = int((1 + math.sin(step * 0.1))   * 127)
    17.         data[step % led_count] = (red, green,   blue)
    18.         yield data
    19.         step += 1
    20.   
    21.   
    22. for   data in data_generator(ring.led_count):
    23.     ring.show(data)
    24.     pyb.delay(100)
    复制代码


        里面还需要引入一个ws2812.py 文件。内容如下:

    1. import   gc
    2. import   pyb
    3.   
    4.   
    5. class   WS2812:
    6.     """
    7.     Driver for WS2812 RGB LEDs. May be used   for controlling single LED or chain
    8.     of LEDs.
    9.   
    10.     Example of use:
    11.   
    12.         chain = WS2812(spi_bus=1,   led_count=4)
    13.         data = [
    14.             (255, 0, 0),    # red
    15.             (0, 255, 0),    # green
    16.             (0, 0, 255),    # blue
    17.             (85, 85, 85),   # white
    18.         ]
    19.         chain.show(data)
    20.   
    21.     Version: 1.0
    22.     """
    23.     buf_bytes = (0x11, 0x13, 0x31, 0x33)
    24.   
    25.     def __init__(self, spi_bus=1,   led_count=1, intensity=1):
    26.         """
    27.         Params:
    28.         * spi_bus = SPI bus ID (1 or 2)
    29.         * led_count = count of LEDs
    30.         * intensity = light intensity (float   up to 1)
    31.         """
    32.         self.led_count = led_count
    33.         self.intensity = intensity
    34.   
    35.         # prepare SPI data buffer (4 bytes   for each color)
    36.         self.buf_length = self.led_count * 3   * 4
    37.         self.buf = bytearray(self.buf_length)
    38.   
    39.         # SPI init
    40.         self.spi = pyb.SPI(spi_bus,   pyb.SPI.MASTER, baudrate=3200000, polarity=0, phase=1)
    41.   
    42.         # turn LEDs off
    43.         self.show([])
    44.   
    45.     def show(self, data):
    46.         """
    47.         Show RGB data on LEDs. Expected data   = [(R, G, B), ...] where R, G and B
    48.         are intensities of colors in range   from 0 to 255. One RGB tuple for each
    49.         LED. Count of tuples may be less than   count of connected LEDs.
    50.         """
    51.         self.fill_buf(data)
    52.         self.send_buf()
    53.   
    54.     def send_buf(self):
    55.         """
    56.         Send buffer over SPI.
    57.         """
    58.         self.spi.send(self.buf)
    59.         gc.collect()
    60.   
    61.     def update_buf(self, data, start=0):
    62.         """
    63.         Fill a part of the buffer with RGB   data.
    64.   
    65.         Order of colors in buffer is changed   from RGB to GRB because WS2812 LED
    66.         has GRB order of colors. Each color   is represented by 4 bytes in buffer
    67.         (1 byte for each 2 bits).
    68.   
    69.         Returns the index of the first unfilled   LED
    70.   
    71.         Note: If you find this function ugly,   it's because speed optimisations
    72.         beated purity of code.
    73.         """
    74.   
    75.         buf = self.buf
    76.         buf_bytes = self.buf_bytes
    77.         intensity = self.intensity
    78.   
    79.         mask = 0x03
    80.         index = start * 12
    81.         for red, green, blue in data:
    82.             red = int(red * intensity)
    83.             green = int(green * intensity)
    84.             blue = int(blue * intensity)
    85.   
    86.             buf[index] = buf_bytes[green   >> 6 & mask]
    87.             buf[index+1] = buf_bytes[green   >> 4 & mask]
    88.             buf[index+2] = buf_bytes[green   >> 2 & mask]
    89.             buf[index+3] = buf_bytes[green   & mask]
    90.   
    91.             buf[index+4] = buf_bytes[red   >> 6 & mask]
    92.             buf[index+5] = buf_bytes[red   >> 4 & mask]
    93.             buf[index+6] = buf_bytes[red   >> 2 & mask]
    94.             buf[index+7] = buf_bytes[red   & mask]
    95.   
    96.             buf[index+8] = buf_bytes[blue   >> 6 & mask]
    97.             buf[index+9] = buf_bytes[blue   >> 4 & mask]
    98.             buf[index+10] = buf_bytes[blue   >> 2 & mask]
    99.             buf[index+11] = buf_bytes[blue   & mask]
    100.   
    101.             index += 12
    102.   
    103.         return index // 12
    104.   
    105.     def fill_buf(self, data):
    106.         """
    107.         Fill buffer with RGB data.
    108.   
    109.         All LEDs after the data are turned   off.
    110.         """
    111.         end = self.update_buf(data)
    112.   
    113.         # turn off the rest of the LEDs
    114.         buf = self.buf
    115.         off = self.buf_bytes[0]
    116.         for index in range(end * 12,   self.buf_length):
    117.             buf[index] = off
    118.             index += 1
    复制代码

        本次参考的github上的一个项目。项目地址:
        https://github.com/JanBednarik/micropython-ws2812
        给大家看一下效果(额 最后一个灯珠坏了 大家可以自行忽略……)
        https://v.qq.com/x/page/d05297wxo1b.html

    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-11-19 20:36 , Processed in 0.132774 second(s), 18 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.