Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# Using PIO to drive a set of WS2812 LEDs.
import array, utime, _thread
from machine import Pin
import rp2
@rp2.asm_pio(sideset_init=rp2.PIO.OUT_LOW, out_shiftdir=rp2.PIO.SHIFT_LEFT, autopull=True, pull_thresh=24)
def ws2812():
T1 = 2
T2 = 5
T3 = 3
wrap_target()
label("bitloop")
out(x, 1) .side(0) [T3 - 1]
jmp(not_x, "do_zero") .side(1) [T1 - 1]
jmp("bitloop") .side(1) [T2 - 1]
label("do_zero")
nop() .side(0) [T2 - 1]
wrap()
class strip:
''' Methods to manipulate 2812 stripes:
pset ( position, color,[optional show(0 or 1)])
fill ( (r,g,b),[optional show(0 or 1)] )
rotate ( steps,[optional show(0 or 1)] )
shift ( steps,[optional show(0 or 1)] )
rainbow ( [starthue , [endhue]],[optional show(0 or 1)] )
show ()
Properties:
BRIGHTNESS (value between 0 and 1)
'''
counter = 0
thread_user = None
def __init__(self,NUM_LEDS, PIN_NUM, BRIGHTNESS):
self.NUM_LEDS = NUM_LEDS
self.PIN_NUM = PIN_NUM
self.BRIGHTNESS = BRIGHTNESS
self.now = 0
if strip.counter < 4:
# Create the StateMachine
self.sm = rp2.StateMachine(strip.counter, ws2812, freq=8_000_000, sideset_base=Pin(self.PIN_NUM))
self.counter=strip.counter
# Start the StateMachine
self.sm.active(1)
# Displayarray on the LEDs
self.ar = array.array("I", [0 for _ in range(self.NUM_LEDS)])
print("Strip with state machine",strip.counter,"on pin",self.PIN_NUM,"active")
else:
print("the maximum of 4 state machines was reached ")
strip.counter += 1
def renew(self,attr,obj):
print("renew state machine",self.counter)
del self
def _dimm(self,col):
c1 = int(((col >> 16) & 0xFF) * self.BRIGHTNESS)
c2 = int(((col >> 8) & 0xFF) * self.BRIGHTNESS)
c3 = int((col & 0xFF) * self.BRIGHTNESS)
return (c1<<16) + (c2<<8) + c3
def show(self):
if strip.thread_user == None:
_thread.start_new_thread(self._put_thread,())
elif (strip.thread_user == self):
#Waiting for tread completion
while strip.thread_user != None:
pass
_thread.start_new_thread(self._put_thread,())
else:
self.sm.put(self.ar, 8)
utime.sleep_us(50)
def _put_thread(self):
strip.thread_user = self
ar_out=self.ar[:]
self.sm.put(ar_out, 8)
utime.sleep_us(50)
strip.thread_user = None
def pset(self,i, col,show=False):
self.ar[i] = self._dimm((col[1]<<16) + (col[0]<<8) + col[2])
if show==1:
self.show()
def fill(self,col,show=False):
fillcol=self._dimm((col[1]<<16) + (col[0]<<8) + col[2])
self.ar = array.array("I", [fillcol for _ in range(self.NUM_LEDS)])
if show:
self.show()
def rotate(self,step,show=False):
cp = array.array("I", self.ar[-step:])
cp.extend(self.ar[:-step])
self.ar = cp
if show:
self.show()
def shift(self,step,show=False):
if step >= 0:
cp = array.array("I",[0 for _ in range(step)])
cp.extend(self.ar[:-step])
else:
cp = array.array("I",self.ar[-step:])
blackpix = array.array("I",[0]*-step)
cp.extend(blackpix[:])
self.ar = cp
if show:
self.show()
def rainbow(self, start=0, end=360,show=False):
steps=int((end-start)/self.NUM_LEDS)
for i in range(self.NUM_LEDS):
self.pset(i, hue2col(start+(i*steps)))
if show:
self.show()
##########################################################################
# color definations
def hue2col(angle):
rgb = [0,0,0]
sec = ((0,1),(1,2),(2,0))
rgb[sec[int(angle/120)][1]]=int(255/120*(angle%120))
rgb[sec[int(angle/120)][0]]=int(255/120*(120-(angle%120)))
return (rgb[0],rgb[1],rgb[2])
RED = (hue2col(0))
YEL = (hue2col(60))
GRE = (hue2col(120))
CYA = (hue2col(180))
BLU = (hue2col(240))
PUR = (hue2col(300))
WHT = (255, 255, 255)
BLK = (0,0,0)
COLORS = (RED, YEL, GRE, CYA, BLU, PUR, WHT, BLK)