TakwayBoard/tools/orangepi_spi_ws2812.py

98 lines
3.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import time
import spidev
import wiringpi
# 0码 t0H 220ns~380ns
# python 中GPIO口无法翻转这么快python 可能执行一行代码需要800ns
# ws2812 波特率如果设置为800kHZ, 1/0.8M=1.25us (0码或者1码所需要的时间)
# 使用SPI产生ws2812时序产生1码和0码则可以使用传输一个byte 来代表一个0码或者1码如下
# 1111 1000 0xF8 #1码 高电平时间长,低电平时间短
# 1100 0000 0xC0 #0码 高电平时间短,低电平时间长
# 则得出SPI 波特率应该设置为800K*8
sig_1 = 0xf8
sig_0 = 0xc0
def flatten_arrays(arrays):
return [element for sublist in arrays for element in sublist]
class WS2812:
def __init__(self, led_num=1):
self.led_num = led_num
self.ws2812_data = [[sig_0 for _ in range(24)] for _ in range(led_num)]
spi = spidev.SpiDev()
# 设置一下下拉,否则第一盏灯的时序可能不正确
wiringpi.wiringPiSetup()
wiringpi.pullUpDnControl(11, 1)
spi.open(0, 0)
spi.max_speed_hz = 6400000
spi.mode = 0
self.spi = spi
def ws2812_send_data(self):
default_tx = self.ws2812_data
self.spi.xfer2(bytes(flatten_arrays(default_tx)))
def ws2812_light_led(self, red, green, blue, pix_led):
default_tx = self.ws2812_data
color = green << 16 | red << 8 | blue
for i in range(24):
if color >> (24 - i - 1) & 1:
default_tx[pix_led][i] = sig_1
else:
default_tx[pix_led][i] = sig_0
def ws2812_light_one_led(self, red, green, blue, pix_led):
self.ws2812_light_led(red, green, blue, pix_led)
self.ws2812_send_data()
def ws2812_light_all_led(self, red, green, blue):
for i in range(self.led_num):
self.ws2812_light_led(red, green, blue, i)
self.ws2812_send_data()
def ws2812_rainbow(self):
colors = [[0xff, 0, 0], [0, 0xff, 0], [0, 0, 0xff]]
for i in range(self.led_num):
cur_color = colors[i % 3]
self.ws2812_light_led(cur_color[0], cur_color[1], cur_color[2], i)
self.ws2812_send_data()
def ws2812_water_lamp(self, red, green, blue, interval_time):
self.ws2812_shutoff_all()
for i in range(self.led_num):
self.ws2812_light_one_led(red, green, blue, i)
time.sleep(interval_time)
self.ws2812_shutoff_all()
def ws2812_shutoff_led(self, n):
self.ws2812_light_led(0, 0, 0, n)
self.ws2812_send_data()
def ws2812_shutoff_all(self):
for i in range(self.led_num):
self.ws2812_light_led(0, 0, 0, i)
self.ws2812_send_data()
if __name__ == '__main__':
ws2812 = WS2812(8)
while True:
ws2812.ws2812_light_all_led(0, 0, 0xff)
time.sleep(0.5)
ws2812.ws2812_light_all_led(0xff, 0, 0)
time.sleep(0.5)
ws2812.ws2812_light_all_led(0, 0xff, 0)
time.sleep(0.5)
# ws2812.ws2812_water_lamp(0xff, 0, 0, 0.2)
# time.sleep(0.5)