-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcode.py
158 lines (130 loc) · 4.97 KB
/
code.py
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# Control code for creepy pumpkin eyes.
#
# Based on Adafruit Itsy Bitsy M0 Express IO demo
import board
import time
import gc
import random
from digitalio import DigitalInOut, Direction, Pull
import pulseio
import adafruit_dotstar
from adafruit_motor import servo
import neopixel
FREQ=50
ANGLE_MIN=0
ANGLE_MAX=180
ANGLE_MIDPOINT=90
# One pixel connected internally!
dot = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.5)
# Neopixel ring
pixel_pin = board.D5
num_pixels = 12
pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=0.3, auto_write=False)
# Built in red LED. Conflicts with servo on D13 below
# led = DigitalInOut(board.D13)
# led.direction = Direction.OUTPUT
# Global state
running = True
staring = False
# Button to toggle between run and standby (servos back to midpoint)
button = DigitalInOut(board.D0)
button.direction = Direction.INPUT
button.pull = Pull.UP
# Pin numbers and ordering figured out by a bit of trial and error
servo1 = servo.Servo(pulseio.PWMOut(board.D10, frequency=FREQ))
servo2 = servo.Servo(pulseio.PWMOut(board.D1, frequency=FREQ))
servo3 = servo.Servo(pulseio.PWMOut(board.D2, frequency=FREQ))
servo4 = servo.Servo(pulseio.PWMOut(board.D3, frequency=FREQ))
# NeoPixels need a 5V logic line, so piggyback servo 5 onto some other servo's pin
# so we can free up D5
# servo5 = servo.Servo(pulseio.PWMOut(board.D5, frequency=FREQ))
servo6 = servo.Servo(pulseio.PWMOut(board.D7, frequency=FREQ))
servo7 = servo.Servo(pulseio.PWMOut(board.D9, frequency=FREQ))
servo8 = servo.Servo(pulseio.PWMOut(board.D11, frequency=FREQ))
servo9 = servo.Servo(pulseio.PWMOut(board.D13, frequency=FREQ)) # Side effect, controls LED
servo10 = servo.Servo(pulseio.PWMOut(board.SCK, frequency=FREQ))
servo11 = servo.Servo(pulseio.PWMOut(board.SCL, frequency=FREQ))
# Can't figure out how to get a 12th PWM, so piggyback servo 12 on some other servo's pin
# servo12 = servo.Servo(pulseio.PWMOut(board.A2, frequency=FREQ))
######################### HELPERS ##############################
def randomOrange():
'''Generate a random orange-ish color, like a flame'''
r = random.randint(200, 255)
g = random.randint(0, 60)
r = r if r > g else g
b = 0
return [r, g, b]
def flicker(dot, pixels):
'''Change color + brightness. Assumes a single DotStar and a set of NeoPixels'''
brightness = random.random()
orange = randomOrange()
dot[0] = orange
dot.brightness = brightness
pixels.fill(orange)
pixels.brightness = brightness
pixels.show()
def checkButton():
'''Toggle the 'running' global on button press'''
if (not button.value): # Button pressed
global running
running = not running
while (not button.value): # Wait for button to be released
time.sleep(0.1)
def lookAround():
'''Main routine to look all around'''
# Group 1
servo1.angle = random.randint(ANGLE_MIN, ANGLE_MAX)
servo2.angle = random.randint(ANGLE_MIN, ANGLE_MAX)
servo3.angle = random.randint(ANGLE_MIN, ANGLE_MAX)
servo4.angle = random.randint(ANGLE_MIN, ANGLE_MAX)
for i in range(random.randint(0, 4)):
flicker(dot, pixels)
time.sleep(0.1)
checkButton()
# Group 2
# servo5 needs to be piggybacked on some other servo's pin - see above
# servo5.angle = random.randint(ANGLE_MIN, ANGLE_MAX)
servo6.angle = random.randint(ANGLE_MIN, ANGLE_MAX)
servo7.angle = random.randint(ANGLE_MIN, ANGLE_MAX)
servo8.angle = random.randint(ANGLE_MIN, ANGLE_MAX)
for i in range(random.randint(0, 4)):
flicker(dot, pixels)
time.sleep(0.1)
checkButton()
# Group 3
servo9.angle = random.randint(ANGLE_MIN, ANGLE_MAX)
servo10.angle = random.randint(ANGLE_MIN, ANGLE_MAX)
servo11.angle = random.randint(ANGLE_MIN, ANGLE_MAX)
# servo12 needs to be piggybacked on some other servo's pin - see above
# servo12.angle = random.randint(ANGLE_MIN, ANGLE_MAX)
for i in range(random.randint(0, 4)):
flicker(dot, pixels)
time.sleep(0.1)
checkButton()
def stare():
'''Reset servos to midpoint'''
global staring
if (not staring):
servo1.angle = ANGLE_MIDPOINT
servo2.angle = ANGLE_MIDPOINT
servo3.angle = ANGLE_MIDPOINT
servo4.angle = ANGLE_MIDPOINT
# servo5 needs to be piggybacked on some other servo's pin - see above
# servo5.angle = ANGLE_MIDPOINT
servo6.angle = ANGLE_MIDPOINT
servo7.angle = ANGLE_MIDPOINT
servo8.angle = ANGLE_MIDPOINT
servo9.angle = ANGLE_MIDPOINT
servo10.angle = ANGLE_MIDPOINT
servo11.angle = ANGLE_MIDPOINT
# servo12 needs to be piggybacked on some other servo's pin - see above
# servo12.angle = ANGLE_MIDPOINT
staring = True
######################### MAIN LOOP ##############################
while True:
checkButton() # No interrupts in CircuitPython, so we have to poll
if running:
staring = False
lookAround()
else:
stare()