Merge branch 'pylint'
This commit is contained in:
commit
00d491c4e3
192 changed files with 3579 additions and 2889 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,2 +1,3 @@
|
||||||
*~
|
*~
|
||||||
Hue_Controller/secrets.h
|
Hue_Controller/secrets.h
|
||||||
|
.idea
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,18 @@
|
||||||
# 3D_Printed_Guardian_Sword
|
# 3D_Printed_Guardian_Sword
|
||||||
# https://learn.adafruit.com/breath-of-the-wild-guardian-sword-led-3d-printed
|
# https://learn.adafruit.com/breath-of-the-wild-guardian-sword-led-3d-printed
|
||||||
|
|
||||||
import board
|
|
||||||
import neopixel
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
pin = board.D4 # DIGITAL IO pin for NeoPixel OUTPUT from GEMMA
|
import board
|
||||||
pixel_count = 93 # number of neopixels
|
import neopixel
|
||||||
delayval = .01 # 10 ms delay
|
|
||||||
|
|
||||||
APIXELS = 14 # number of first orange pixels
|
pin = board.D4 # DIGITAL IO pin for NeoPixel OUTPUT from GEMMA
|
||||||
BPIXELS = 84 # number of blue pixels
|
pixel_count = 93 # number of neopixels
|
||||||
CPIXELS = 93 # second orange pixels
|
delayval = .01 # 10 ms delay
|
||||||
|
|
||||||
|
APIXELS = 14 # number of first orange pixels
|
||||||
|
BPIXELS = 84 # number of blue pixels
|
||||||
|
CPIXELS = 93 # second orange pixels
|
||||||
|
|
||||||
# initialize neopixels
|
# initialize neopixels
|
||||||
pixels = neopixel.NeoPixel(pin, pixel_count, brightness=1, auto_write=False)
|
pixels = neopixel.NeoPixel(pin, pixel_count, brightness=1, auto_write=False)
|
||||||
|
|
|
||||||
|
|
@ -26,42 +26,47 @@
|
||||||
# Written by Paul Badger 2007
|
# Written by Paul Badger 2007
|
||||||
# Modified fromhere code by Greg Shakar
|
# Modified fromhere code by Greg Shakar
|
||||||
# Ported to Circuit Python by Mikey Sklar
|
# Ported to Circuit Python by Mikey Sklar
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import board
|
import board
|
||||||
import neopixel
|
import neopixel
|
||||||
from analogio import AnalogIn
|
from analogio import AnalogIn
|
||||||
|
|
||||||
n_pixels = 16 # Number of pixels you are using
|
n_pixels = 16 # Number of pixels you are using
|
||||||
mic_pin = AnalogIn(board.A1) # Microphone is attached to this analog pin
|
mic_pin = AnalogIn(board.A1) # Microphone is attached to this analog pin
|
||||||
led_pin = board.D1 # NeoPixel LED strand is connected to this pin
|
led_pin = board.D1 # NeoPixel LED strand is connected to this pin
|
||||||
sample_window = .1 # Sample window for average level
|
sample_window = .1 # Sample window for average level
|
||||||
peak_hang = 24 # Time of pause before peak dot falls
|
peak_hang = 24 # Time of pause before peak dot falls
|
||||||
peak_fall = 4 # Rate of falling peak dot
|
peak_fall = 4 # Rate of falling peak dot
|
||||||
input_floor = 10 # Lower range of analogRead input
|
input_floor = 10 # Lower range of analogRead input
|
||||||
input_ceiling = 300 # Max range of analogRead input, the lower
|
# Max range of analogRead input, the lower the value the more sensitive
|
||||||
# the value the more sensitive (1023 = max)
|
# (1023 = max)
|
||||||
|
input_ceiling = 300
|
||||||
|
|
||||||
peak = 16 # Peak level of column; used for falling dots
|
peak = 16 # Peak level of column; used for falling dots
|
||||||
sample = 0
|
sample = 0
|
||||||
|
|
||||||
dotcount = 0 # Frame counter for peak dot
|
dotcount = 0 # Frame counter for peak dot
|
||||||
dothangcount = 0 # Frame counter for holding peak dot
|
dothangcount = 0 # Frame counter for holding peak dot
|
||||||
|
|
||||||
strip = neopixel.NeoPixel(led_pin, n_pixels, brightness=1, auto_write=False)
|
strip = neopixel.NeoPixel(led_pin, n_pixels, brightness=1, auto_write=False)
|
||||||
|
|
||||||
|
|
||||||
def wheel(pos):
|
def wheel(pos):
|
||||||
# Input a value 0 to 255 to get a color value.
|
# Input a value 0 to 255 to get a color value.
|
||||||
# The colours are a transition r - g - b - back to r.
|
# The colours are a transition r - g - b - back to r.
|
||||||
if pos < 0 or pos > 255:
|
if pos < 0 or pos > 255:
|
||||||
return (0, 0, 0)
|
return (0, 0, 0)
|
||||||
if pos < 85:
|
if pos < 85:
|
||||||
return (int(pos * 3), int(255 - (pos*3)), 0)
|
return (int(pos * 3), int(255 - (pos * 3)), 0)
|
||||||
elif pos < 170:
|
elif pos < 170:
|
||||||
pos -= 85
|
pos -= 85
|
||||||
return (int(255 - pos*3), 0, int(pos*3))
|
return (int(255 - pos * 3), 0, int(pos * 3))
|
||||||
else:
|
else:
|
||||||
pos -= 170
|
pos -= 170
|
||||||
return (0, int(pos*3), int(255 - pos*3))
|
return (0, int(pos * 3), int(255 - pos * 3))
|
||||||
|
|
||||||
|
|
||||||
def remapRange(value, leftMin, leftMax, rightMin, rightMax):
|
def remapRange(value, leftMin, leftMax, rightMin, rightMax):
|
||||||
# this remaps a value fromhere original (left) range to new (right) range
|
# this remaps a value fromhere original (left) range to new (right) range
|
||||||
|
|
@ -75,12 +80,8 @@ def remapRange(value, leftMin, leftMax, rightMin, rightMax):
|
||||||
# Convert the 0-1 range into a value in the right range.
|
# Convert the 0-1 range into a value in the right range.
|
||||||
return int(rightMin + (valueScaled * rightSpan))
|
return int(rightMin + (valueScaled * rightSpan))
|
||||||
|
|
||||||
|
|
||||||
def fscale(originalmin, originalmax, newbegin, newend, inputvalue, curve):
|
def fscale(originalmin, originalmax, newbegin, newend, inputvalue, curve):
|
||||||
originalrange = 0
|
|
||||||
newrange = 0
|
|
||||||
zerorefcurval = 0
|
|
||||||
normalizedcurval = 0
|
|
||||||
rangedvalue = 0
|
|
||||||
invflag = 0
|
invflag = 0
|
||||||
|
|
||||||
# condition curve parameter
|
# condition curve parameter
|
||||||
|
|
@ -94,7 +95,8 @@ def fscale(originalmin, originalmax, newbegin, newend, inputvalue, curve):
|
||||||
# this seems more intuitive
|
# this seems more intuitive
|
||||||
# postive numbers give more weight to high end on output
|
# postive numbers give more weight to high end on output
|
||||||
curve = (curve * -.1)
|
curve = (curve * -.1)
|
||||||
curve = pow(10, curve) # convert linear scale into lograthimic exponent for other pow function
|
# convert linear scale into lograthimic exponent for other pow function
|
||||||
|
curve = pow(10, curve)
|
||||||
|
|
||||||
# Check for out of range inputValues
|
# Check for out of range inputValues
|
||||||
if inputvalue < originalmin:
|
if inputvalue < originalmin:
|
||||||
|
|
@ -113,7 +115,8 @@ def fscale(originalmin, originalmax, newbegin, newend, inputvalue, curve):
|
||||||
invflag = 1
|
invflag = 1
|
||||||
|
|
||||||
zerorefcurval = inputvalue - originalmin
|
zerorefcurval = inputvalue - originalmin
|
||||||
normalizedcurval = zerorefcurval / originalrange # normalize to 0 - 1 float
|
# normalize to 0 - 1 float
|
||||||
|
normalizedcurval = zerorefcurval / originalrange
|
||||||
|
|
||||||
# Check for originalMin > originalMax
|
# Check for originalMin > originalMax
|
||||||
# -the math for all other cases
|
# -the math for all other cases
|
||||||
|
|
@ -122,44 +125,44 @@ def fscale(originalmin, originalmax, newbegin, newend, inputvalue, curve):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if invflag == 0:
|
if invflag == 0:
|
||||||
rangedvalue = (pow(normalizedcurval, curve) * newrange) + newbegin
|
rangedvalue = (pow(normalizedcurval, curve) * newrange) + newbegin
|
||||||
else: # invert the ranges
|
else: # invert the ranges
|
||||||
rangedvalue = newbegin - (pow(normalizedcurval, curve) * newrange)
|
rangedvalue = newbegin - (pow(normalizedcurval, curve) * newrange)
|
||||||
|
|
||||||
return rangedvalue
|
return rangedvalue
|
||||||
|
|
||||||
|
|
||||||
def drawLine(fromhere, to):
|
def drawLine(fromhere, to):
|
||||||
|
|
||||||
fromheretemp = 0
|
|
||||||
|
|
||||||
if fromhere > to:
|
if fromhere > to:
|
||||||
fromheretemp = fromhere
|
fromheretemp = fromhere
|
||||||
fromhere = to
|
fromhere = to
|
||||||
to = fromheretemp
|
to = fromheretemp
|
||||||
|
|
||||||
for n in range(fromhere, to):
|
for index in range(fromhere, to):
|
||||||
strip[n] = (0, 0, 0)
|
strip[index] = (0, 0, 0)
|
||||||
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
|
||||||
time_start = time.monotonic() # current time used for sample window
|
time_start = time.monotonic() # current time used for sample window
|
||||||
peaktopeak = 0 # peak-to-peak level
|
peaktopeak = 0 # peak-to-peak level
|
||||||
signalmax = 0
|
signalmax = 0
|
||||||
signalmin = 1023
|
signalmin = 1023
|
||||||
c = 0
|
c = 0
|
||||||
y = 0
|
y = 0
|
||||||
|
|
||||||
# collect data for length of sample window (in seconds)
|
# collect data for length of sample window (in seconds)
|
||||||
while (time.monotonic() - time_start ) < sample_window:
|
while (time.monotonic() - time_start) < sample_window:
|
||||||
|
|
||||||
sample = mic_pin.value / 64 # convert to arduino 10-bit [1024] fromhere 16-bit [65536]
|
# convert to arduino 10-bit [1024] fromhere 16-bit [65536]
|
||||||
|
sample = mic_pin.value / 64
|
||||||
|
|
||||||
if sample < 1024: # toss out spurious readings
|
if sample < 1024: # toss out spurious readings
|
||||||
|
|
||||||
if sample > signalmax:
|
if sample > signalmax:
|
||||||
signalmax = sample # save just the max levels
|
signalmax = sample # save just the max levels
|
||||||
elif sample < signalmin:
|
elif sample < signalmin:
|
||||||
signalmin = sample # save just the min levels
|
signalmin = sample # save just the min levels
|
||||||
|
|
||||||
peaktopeak = signalmax - signalmin # max - min = peak-peak amplitude
|
peaktopeak = signalmax - signalmin # max - min = peak-peak amplitude
|
||||||
|
|
||||||
|
|
@ -171,10 +174,10 @@ while True:
|
||||||
c = fscale(input_floor, input_ceiling, (n_pixels - 1), 0, peaktopeak, 2)
|
c = fscale(input_floor, input_ceiling, (n_pixels - 1), 0, peaktopeak, 2)
|
||||||
|
|
||||||
if c < peak:
|
if c < peak:
|
||||||
peak = c # keep dot on top
|
peak = c # keep dot on top
|
||||||
dothangcount = 0 # make the dot hang before falling
|
dothangcount = 0 # make the dot hang before falling
|
||||||
|
|
||||||
if c <= n_pixels: # fill partial column with off pixels
|
if c <= n_pixels: # fill partial column with off pixels
|
||||||
drawLine(n_pixels, n_pixels - int(c))
|
drawLine(n_pixels, n_pixels - int(c))
|
||||||
|
|
||||||
# Set the peak dot to match the rainbow gradient
|
# Set the peak dot to match the rainbow gradient
|
||||||
|
|
@ -183,9 +186,9 @@ while True:
|
||||||
strip.write()
|
strip.write()
|
||||||
|
|
||||||
# Frame based peak dot animation
|
# Frame based peak dot animation
|
||||||
if dothangcount > peak_hang: # Peak pause length
|
if dothangcount > peak_hang: # Peak pause length
|
||||||
dotcount = dotcount + 1
|
dotcount += 1
|
||||||
if dotcount >= peak_fall: # Fall rate
|
if dotcount >= peak_fall: # Fall rate
|
||||||
peak += 1
|
peak += 1
|
||||||
dotcount = 0
|
dotcount = 0
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,28 @@
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import board
|
import board
|
||||||
import neopixel
|
import neopixel
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import urandom as random # for v1.0 API support
|
import urandom as random # for v1.0 API support
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import random
|
import random
|
||||||
|
|
||||||
numpix = 24 # Number of NeoPixels
|
numpix = 24 # Number of NeoPixels
|
||||||
pixpin = board.D0 # Pin where NeoPixels are connected
|
pixpin = board.D0 # Pin where NeoPixels are connected
|
||||||
strip = neopixel.NeoPixel(pixpin, numpix, brightness=0.3)
|
strip = neopixel.NeoPixel(pixpin, numpix, brightness=0.3)
|
||||||
|
|
||||||
mode = 0 # Current animation effect
|
mode = 0 # Current animation effect
|
||||||
offset = 0 # Position of spinner animation
|
offset = 0 # Position of spinner animation
|
||||||
color = [255, 0, 0] # RGB color - red
|
color = [255, 0, 0] # RGB color - red
|
||||||
prevtime = time.monotonic() # Time of last animation mode switch
|
prevtime = time.monotonic() # Time of last animation mode switch
|
||||||
|
|
||||||
while True: # Loop forever...
|
while True: # Loop forever...
|
||||||
|
|
||||||
if mode == 0: # Random sparkles - lights just one LED at a time
|
if mode == 0: # Random sparkles - lights just one LED at a time
|
||||||
i = random.randint(0, numpix - 1) # Choose random pixel
|
i = random.randint(0, numpix - 1) # Choose random pixel
|
||||||
strip[i] = color # Set it to current color
|
strip[i] = color # Set it to current color
|
||||||
strip.write() # Refresh LED states
|
strip.write() # Refresh LED states
|
||||||
# Set same pixel to "off" color now but DON'T refresh...
|
# Set same pixel to "off" color now but DON'T refresh...
|
||||||
# it stays on for now...bot this and the next random
|
# it stays on for now...bot this and the next random
|
||||||
# pixel will be refreshed on the next pass.
|
# pixel will be refreshed on the next pass.
|
||||||
|
|
@ -35,22 +37,22 @@ while True: # Loop forever...
|
||||||
# types, so we get the reversed motion on #2 for free).
|
# types, so we get the reversed motion on #2 for free).
|
||||||
for i in range(numpix): # For each LED...
|
for i in range(numpix): # For each LED...
|
||||||
if ((offset + i) & 7) < 2: # 2 pixels out of 8...
|
if ((offset + i) & 7) < 2: # 2 pixels out of 8...
|
||||||
strip[i] = color # are set to current color
|
strip[i] = color # are set to current color
|
||||||
else:
|
else:
|
||||||
strip[i] = [0, 0, 0] # other pixels are off
|
strip[i] = [0, 0, 0] # other pixels are off
|
||||||
strip.write() # Refresh LED states
|
strip.write() # Refresh LED states
|
||||||
time.sleep(0.04) # 40 millisecond delay
|
time.sleep(0.04) # 40 millisecond delay
|
||||||
offset += 1 # Shift animation by 1 pixel on next frame
|
offset += 1 # Shift animation by 1 pixel on next frame
|
||||||
if offset >= 8:
|
if offset >= 8:
|
||||||
offset = 0
|
offset = 0
|
||||||
# Additional animation modes could be added here!
|
# Additional animation modes could be added here!
|
||||||
|
|
||||||
t = time.monotonic() # Current time in seconds
|
t = time.monotonic() # Current time in seconds
|
||||||
if (t - prevtime) >= 8: # Every 8 seconds...
|
if (t - prevtime) >= 8: # Every 8 seconds...
|
||||||
mode += 1 # Advance to next mode
|
mode += 1 # Advance to next mode
|
||||||
if mode > 1: # End of modes?
|
if mode > 1: # End of modes?
|
||||||
mode = 0 # Start over from beginning
|
mode = 0 # Start over from beginning
|
||||||
# Rotate color R->G->B
|
# Rotate color R->G->B
|
||||||
color = [color[2], color[0], color[1]]
|
color = [color[2], color[0], color[1]]
|
||||||
strip.fill([0, 0, 0]) # Turn off all pixels
|
strip.fill([0, 0, 0]) # Turn off all pixels
|
||||||
prevtime = t # Record time of last mode change
|
prevtime = t # Record time of last mode change
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
# major bug, you don't need tochange anything here
|
# major bug, you don't need tochange anything here
|
||||||
#
|
#
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import board
|
import board
|
||||||
import neopixel
|
import neopixel
|
||||||
|
|
||||||
|
|
@ -19,39 +20,43 @@ except ImportError:
|
||||||
from analogio import AnalogIn
|
from analogio import AnalogIn
|
||||||
|
|
||||||
# available actions
|
# available actions
|
||||||
ACT_NOP = 0x00 # all leds off, do nothing
|
ACT_NOP = 0x00 # all leds off, do nothing
|
||||||
ACT_SIMPLE_RING = 0x01 # all leds on
|
ACT_SIMPLE_RING = 0x01 # all leds on
|
||||||
ACT_CYCLING_RING_ACLK = 0x02 # anti clockwise cycling colors
|
ACT_CYCLING_RING_ACLK = 0x02 # anti clockwise cycling colors
|
||||||
ACT_CYCLING_RING_CLKW = 0x04 # clockwise cycling colors
|
ACT_CYCLING_RING_CLKW = 0x04 # clockwise cycling colors
|
||||||
ACT_WHEEL_ACLK = 0x08 # anti clockwise spinning wheel
|
ACT_WHEEL_ACLK = 0x08 # anti clockwise spinning wheel
|
||||||
ACT_WHEEL_CLKW = 0x10 # clockwise spinning wheel
|
ACT_WHEEL_CLKW = 0x10 # clockwise spinning wheel
|
||||||
ACT_SPARKLING_RING = 0x20 # sparkling effect
|
ACT_SPARKLING_RING = 0x20 # sparkling effect
|
||||||
|
|
||||||
numpix = 16 # total number of NeoPixels
|
numpix = 16 # total number of NeoPixels
|
||||||
pixel_output = board.D0 # pin where NeoPixels are connected
|
pixel_output = board.D0 # pin where NeoPixels are connected
|
||||||
analog_input = board.A0 # needed to seed the random generator
|
analog_input = board.A0 # needed to seed the random generator
|
||||||
strip = neopixel.NeoPixel(pixel_output, numpix, brightness=.3, auto_write=False)
|
strip = neopixel.NeoPixel(pixel_output, numpix,
|
||||||
|
brightness=.3, auto_write=False)
|
||||||
|
|
||||||
# available color generation methods
|
# available color generation methods
|
||||||
COL_RANDOM = 0x40 # colors will be generated randomly
|
COL_RANDOM = 0x40 # colors will be generated randomly
|
||||||
COL_SPECTRUM = 0x80 # colors will be set as cyclic spectral wipe
|
COL_SPECTRUM = 0x80 # colors will be set as cyclic spectral wipe
|
||||||
|
|
||||||
# specifiyng the action list
|
# specifiyng the action list
|
||||||
action_duration = 0 # the action's overall duration in milliseconds (be careful not
|
# the action's overall duration in milliseconds (be careful not
|
||||||
# to use values > 2^16-1 - roughly one minute :-)
|
action_duration = 0
|
||||||
|
# to use values > 2^16-1 - roughly one minute :-)
|
||||||
|
|
||||||
action_and_color_gen = 1 # the color generation method
|
action_and_color_gen = 1 # the color generation method
|
||||||
|
|
||||||
action_step_duration = 2 # the duration of each action step rsp. the delay of the main
|
# the duration of each action step rsp. the delay of the main
|
||||||
# loop in milliseconds - thus, controls the action speed (be
|
action_step_duration = 2
|
||||||
# careful not to use values > 2^16-1 - roughly one minute :-)
|
# loop in milliseconds - thus, controls the action speed (be
|
||||||
|
# careful not to use values > 2^16-1 - roughly one minute :-)
|
||||||
|
|
||||||
color_granularity = 3 # controls the increment of the R, G, and B portions of the
|
color_granularity = 3 # controls the increment of the R, G, and B
|
||||||
# rsp. color. 1 means the increment is 0,1,2,3,..., 10 means
|
# portions of the rsp. color. 1 means the increment is 0,1,2,3,...,
|
||||||
# the increment is 0,10,20,... don't use values > 255, and note
|
# 10 means the increment is 0,10,20,... don't use values > 255, and
|
||||||
# that even values > 127 wouldn't make much sense...
|
# note that even values > 127 wouldn't make much sense...
|
||||||
|
|
||||||
color_interval = 4 # controls the speed of color changing independently from action
|
# controls the speed of color changing independently from action
|
||||||
|
color_interval = 4
|
||||||
|
|
||||||
# general global variables
|
# general global variables
|
||||||
color = 0
|
color = 0
|
||||||
|
|
@ -75,60 +80,87 @@ spectrum_part = 0
|
||||||
# this array variable must be called theactionlist !!!
|
# this array variable must be called theactionlist !!!
|
||||||
#
|
#
|
||||||
# valid actions are:
|
# valid actions are:
|
||||||
# ACT_NOP simply do nothing and switch everything off
|
# ACT_NOP simply do nothing and switch everything off
|
||||||
# ACT_SIMPLE_RING all leds on
|
# ACT_SIMPLE_RING all leds on
|
||||||
# ACT_CYCLING_RING_ACLK anti clockwise cycling colors
|
# ACT_CYCLING_RING_ACLK anti clockwise cycling colors
|
||||||
# ACT_CYCLING_RING_CLKW clockwise cycling colors acording
|
# ACT_CYCLING_RING_CLKW clockwise cycling colors acording
|
||||||
# ACT_WHEEL_ACLK anti clockwise spinning wheel
|
# ACT_WHEEL_ACLK anti clockwise spinning wheel
|
||||||
# ACT_WHEEL_CLKW clockwise spinning wheel
|
# ACT_WHEEL_CLKW clockwise spinning wheel
|
||||||
# ACT_SPARKLING_RING sparkling effect
|
# ACT_SPARKLING_RING sparkling effect
|
||||||
#
|
#
|
||||||
# valid color options are:
|
# valid color options are:
|
||||||
# COL_RANDOM colors will be selected randomly, which might
|
# COL_RANDOM colors will be selected randomly, which might
|
||||||
# be not very sufficient due to well known
|
# be not very sufficient due to well known
|
||||||
# limitations of the random generation algorithm
|
# limitations of the random generation algorithm
|
||||||
# COL_SPECTRUM colors will be set as cyclic spectral wipe
|
# COL_SPECTRUM colors will be set as cyclic spectral wipe
|
||||||
# R -> G -> B -> R -> G -> B -> R -> ...
|
# R -> G -> B -> R -> G -> B -> R -> ...
|
||||||
|
|
||||||
# action action name & action step color color change
|
# action action name & action step color color change
|
||||||
# duration color generation method duration granularity interval
|
# duration color generation method duration granularity interval
|
||||||
theactionlist = [
|
theactionlist = [
|
||||||
[5, ACT_SPARKLING_RING | COL_RANDOM, 0.01, 25, 1 ],
|
[5, ACT_SPARKLING_RING | COL_RANDOM, 0.01, 25, 1],
|
||||||
[2, ACT_CYCLING_RING_CLKW | COL_RANDOM, 0.02, 1, 0.005 ],
|
[2, ACT_CYCLING_RING_CLKW | COL_RANDOM,
|
||||||
[5, ACT_SPARKLING_RING | COL_RANDOM, 0.01, 25, 1 ],
|
0.02, 1, 0.005],
|
||||||
[2, ACT_CYCLING_RING_ACLK | COL_RANDOM, 0.02, 1, 0.005 ],
|
[5, ACT_SPARKLING_RING | COL_RANDOM, 0.01, 25, 1],
|
||||||
[5, ACT_SPARKLING_RING | COL_RANDOM, 0.01, 25, 1 ],
|
[2, ACT_CYCLING_RING_ACLK | COL_RANDOM,
|
||||||
[2.5, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.25, 20, 0.020 ],
|
0.02, 1, 0.005],
|
||||||
[1, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.50, 1, 0.020 ],
|
[5, ACT_SPARKLING_RING | COL_RANDOM, 0.01, 25, 1],
|
||||||
[.750, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.075, 1, 0.020 ],
|
[2.5, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
|
||||||
[.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.100, 1, 0.020 ],
|
0.25, 20, 0.020],
|
||||||
[.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.125, 1, 0.020 ],
|
[1, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
|
||||||
[.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.150, 1, 0.050 ],
|
0.50, 1, 0.020],
|
||||||
[.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.175, 1, 0.100 ],
|
[.750, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
|
||||||
[.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.200, 1, 0.200 ],
|
0.075, 1, 0.020],
|
||||||
[.750, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.225, 1, 0.250 ],
|
[.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
|
||||||
[1, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.250, 1, 0.350 ],
|
0.100, 1, 0.020],
|
||||||
[30, ACT_SIMPLE_RING | COL_SPECTRUM, 0.050, 1, 0.010 ],
|
[.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
|
||||||
[2.5, ACT_WHEEL_ACLK | COL_SPECTRUM, 0.010, 1, 0.010 ],
|
0.125, 1, 0.020],
|
||||||
[2.5, ACT_WHEEL_ACLK | COL_SPECTRUM, 0.015, 1, 0.020 ],
|
[.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
|
||||||
[2, ACT_WHEEL_ACLK | COL_SPECTRUM, 0.025, 1, 0.030 ],
|
0.150, 1, 0.050],
|
||||||
[1, ACT_WHEEL_ACLK | COL_SPECTRUM, 0.050, 1, 0.040 ],
|
[.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
|
||||||
[1, ACT_WHEEL_ACLK | COL_SPECTRUM, 0.075, 1, 0.040 ],
|
0.175, 1, 0.100],
|
||||||
[1, ACT_WHEEL_ACLK | COL_SPECTRUM, 0.100, 1, 0.050 ],
|
[.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
|
||||||
[.500, ACT_WHEEL_ACLK | COL_SPECTRUM, 0.125, 1, 0.060 ],
|
0.200, 1, 0.200],
|
||||||
[.500, ACT_WHEEL_CLKW | COL_SPECTRUM, 0.125, 5, 0.050 ],
|
[.750, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
|
||||||
[1, ACT_WHEEL_CLKW | COL_SPECTRUM, 0.100, 10, 0.040 ],
|
0.225, 1, 0.250],
|
||||||
[1.5, ACT_WHEEL_CLKW | COL_SPECTRUM, 0.075, 15, 0.030 ],
|
[1, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
|
||||||
[2, ACT_WHEEL_CLKW | COL_SPECTRUM, 0.050, 20, 0.020 ],
|
0.250, 1, 0.350],
|
||||||
[2.5, ACT_WHEEL_CLKW | COL_SPECTRUM, 0.025, 25, 0.010 ],
|
[30, ACT_SIMPLE_RING | COL_SPECTRUM,
|
||||||
[3, ACT_WHEEL_CLKW | COL_SPECTRUM, 0.010, 30, 0.005 ],
|
0.050, 1, 0.010],
|
||||||
[5, ACT_SPARKLING_RING | COL_RANDOM, 0.010, 25, 1 ],
|
[2.5, ACT_WHEEL_ACLK | COL_SPECTRUM,
|
||||||
[5, ACT_NOP, 0, 0, 0]
|
0.010, 1, 0.010],
|
||||||
|
[2.5, ACT_WHEEL_ACLK | COL_SPECTRUM,
|
||||||
|
0.015, 1, 0.020],
|
||||||
|
[2, ACT_WHEEL_ACLK | COL_SPECTRUM,
|
||||||
|
0.025, 1, 0.030],
|
||||||
|
[1, ACT_WHEEL_ACLK | COL_SPECTRUM,
|
||||||
|
0.050, 1, 0.040],
|
||||||
|
[1, ACT_WHEEL_ACLK | COL_SPECTRUM,
|
||||||
|
0.075, 1, 0.040],
|
||||||
|
[1, ACT_WHEEL_ACLK | COL_SPECTRUM,
|
||||||
|
0.100, 1, 0.050],
|
||||||
|
[.500, ACT_WHEEL_ACLK | COL_SPECTRUM,
|
||||||
|
0.125, 1, 0.060],
|
||||||
|
[.500, ACT_WHEEL_CLKW | COL_SPECTRUM,
|
||||||
|
0.125, 5, 0.050],
|
||||||
|
[1, ACT_WHEEL_CLKW | COL_SPECTRUM,
|
||||||
|
0.100, 10, 0.040],
|
||||||
|
[1.5, ACT_WHEEL_CLKW | COL_SPECTRUM,
|
||||||
|
0.075, 15, 0.030],
|
||||||
|
[2, ACT_WHEEL_CLKW | COL_SPECTRUM,
|
||||||
|
0.050, 20, 0.020],
|
||||||
|
[2.5, ACT_WHEEL_CLKW | COL_SPECTRUM,
|
||||||
|
0.025, 25, 0.010],
|
||||||
|
[3, ACT_WHEEL_CLKW | COL_SPECTRUM,
|
||||||
|
0.010, 30, 0.005],
|
||||||
|
[5, ACT_SPARKLING_RING | COL_RANDOM, 0.010, 25, 1],
|
||||||
|
[5, ACT_NOP, 0, 0, 0]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def nextspectrumcolor():
|
def nextspectrumcolor():
|
||||||
global spectrum_part, color_idx, curr_color_granularity, color
|
global spectrum_part, color_idx, curr_color_granularity, color
|
||||||
|
|
||||||
# spectral wipe from green to red
|
# spectral wipe from green to red
|
||||||
if spectrum_part == 2:
|
if spectrum_part == 2:
|
||||||
color = (color_idx, 0, 255-color_idx)
|
color = (color_idx, 0, 255-color_idx)
|
||||||
|
|
@ -153,23 +185,25 @@ def nextspectrumcolor():
|
||||||
spectrum_part = 1
|
spectrum_part = 1
|
||||||
color_idx = 0
|
color_idx = 0
|
||||||
|
|
||||||
|
|
||||||
def nextrandomcolor():
|
def nextrandomcolor():
|
||||||
global color
|
global color
|
||||||
|
|
||||||
# granularity = 1 --> [0 .. 255] * 1 --> 0,1,2,3 ... 255
|
# granularity = 1 --> [0 .. 255] * 1 --> 0,1,2,3 ... 255
|
||||||
# granularity = 10 --> [0 .. 25] * 10 --> 0,10,20,30 ... 250
|
# granularity = 10 --> [0 .. 25] * 10 --> 0,10,20,30 ... 250
|
||||||
# granularity = 100 --> [0 .. 2] * 100 --> 0,100, 200 (boaring...)
|
# granularity = 100 --> [0 .. 2] * 100 --> 0,100, 200 (boaring...)
|
||||||
random_red = random.randint(0, int (256 / curr_color_granularity))
|
random_red = random.randint(0, int(256 / curr_color_granularity))
|
||||||
random_red *= curr_color_granularity
|
random_red *= curr_color_granularity
|
||||||
|
|
||||||
random_green = random.randint(0, int (256 / curr_color_granularity))
|
random_green = random.randint(0, int(256 / curr_color_granularity))
|
||||||
random_green *= curr_color_granularity
|
random_green *= curr_color_granularity
|
||||||
|
|
||||||
random_blue = random.randint(0, int (256 / curr_color_granularity))
|
random_blue = random.randint(0, int(256 / curr_color_granularity))
|
||||||
random_blue *= curr_color_granularity
|
random_blue *= curr_color_granularity
|
||||||
|
|
||||||
color = (random_red, random_green, random_blue)
|
color = (random_red, random_green, random_blue)
|
||||||
|
|
||||||
|
|
||||||
def nextcolor():
|
def nextcolor():
|
||||||
# save some RAM for more animation actions
|
# save some RAM for more animation actions
|
||||||
if curr_color_gen & COL_RANDOM:
|
if curr_color_gen & COL_RANDOM:
|
||||||
|
|
@ -177,8 +211,8 @@ def nextcolor():
|
||||||
else:
|
else:
|
||||||
nextspectrumcolor()
|
nextspectrumcolor()
|
||||||
|
|
||||||
def setup():
|
|
||||||
|
|
||||||
|
def setup():
|
||||||
# fingers corssed, the seeding makes sense to really get random colors...
|
# fingers corssed, the seeding makes sense to really get random colors...
|
||||||
apin = AnalogIn(analog_input)
|
apin = AnalogIn(analog_input)
|
||||||
random.seed(apin.value)
|
random.seed(apin.value)
|
||||||
|
|
@ -188,18 +222,21 @@ def setup():
|
||||||
nextcolor()
|
nextcolor()
|
||||||
strip.write()
|
strip.write()
|
||||||
|
|
||||||
|
|
||||||
setup()
|
setup()
|
||||||
|
|
||||||
while True: # Loop forever...
|
while True: # Loop forever...
|
||||||
|
|
||||||
# do we need to load the next action?
|
# do we need to load the next action?
|
||||||
if (time.monotonic() - action_timer) > curr_action_duration:
|
if (time.monotonic() - action_timer) > curr_action_duration:
|
||||||
curr_action_duration = theactionlist[curr_action_idx][action_duration]
|
current_action = theactionlist[curr_action_idx]
|
||||||
curr_action = theactionlist[curr_action_idx][action_and_color_gen] & 0x3F
|
|
||||||
curr_action_step_duration = theactionlist[curr_action_idx][action_step_duration]
|
curr_action_duration = current_action[action_duration]
|
||||||
curr_color_gen = theactionlist[curr_action_idx][action_and_color_gen] & 0xC0
|
curr_action = current_action[action_and_color_gen] & 0x3F
|
||||||
curr_color_granularity = theactionlist[curr_action_idx][color_granularity]
|
curr_action_step_duration = current_action[action_step_duration]
|
||||||
curr_color_interval = theactionlist[curr_action_idx][color_interval]
|
curr_color_gen = current_action[action_and_color_gen] & 0xC0
|
||||||
|
curr_color_granularity = current_action[color_granularity]
|
||||||
|
curr_color_interval = current_action[color_interval]
|
||||||
curr_action_idx += 1
|
curr_action_idx += 1
|
||||||
|
|
||||||
# take care to rotate the action list!
|
# take care to rotate the action list!
|
||||||
|
|
@ -216,6 +253,8 @@ while True: # Loop forever...
|
||||||
|
|
||||||
if curr_action:
|
if curr_action:
|
||||||
|
|
||||||
|
is_act_cycling = (ACT_CYCLING_RING_ACLK or ACT_CYCLING_RING_CLKW)
|
||||||
|
|
||||||
if curr_action == ACT_NOP:
|
if curr_action == ACT_NOP:
|
||||||
# rather trivial even tho this will be repeated as long as the
|
# rather trivial even tho this will be repeated as long as the
|
||||||
# NOP continues - i could have prevented it from repeating
|
# NOP continues - i could have prevented it from repeating
|
||||||
|
|
@ -229,7 +268,7 @@ while True: # Loop forever...
|
||||||
for i in range(0, numpix):
|
for i in range(0, numpix):
|
||||||
strip[i] = color
|
strip[i] = color
|
||||||
|
|
||||||
elif curr_action == (ACT_CYCLING_RING_ACLK or ACT_CYCLING_RING_CLKW):
|
elif curr_action == is_act_cycling:
|
||||||
# spin the ring clockwise or anti clockwise
|
# spin the ring clockwise or anti clockwise
|
||||||
if curr_action == ACT_CYCLING_RING_ACLK:
|
if curr_action == ACT_CYCLING_RING_ACLK:
|
||||||
idx += 1
|
idx += 1
|
||||||
|
|
@ -242,7 +281,7 @@ while True: # Loop forever...
|
||||||
# set the new color, if there is one
|
# set the new color, if there is one
|
||||||
strip[idx] = color
|
strip[idx] = color
|
||||||
|
|
||||||
elif (curr_action == ACT_WHEEL_ACLK or ACT_WHEEL_CLKW):
|
elif curr_action == ACT_WHEEL_ACLK or ACT_WHEEL_CLKW:
|
||||||
# switch on / off the appropriate pixels according to
|
# switch on / off the appropriate pixels according to
|
||||||
# the current offset
|
# the current offset
|
||||||
for idx in range(0, numpix):
|
for idx in range(0, numpix):
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import time
|
import time
|
||||||
from digitalio import DigitalInOut, Direction
|
|
||||||
import board
|
import board
|
||||||
import neopixel
|
import neopixel
|
||||||
|
from digitalio import DigitalInOut, Direction
|
||||||
|
|
||||||
pixpin = board.D1
|
pixpin = board.D1
|
||||||
numpix = 8
|
numpix = 8
|
||||||
|
|
@ -11,6 +12,7 @@ led.direction = Direction.OUTPUT
|
||||||
|
|
||||||
strip = neopixel.NeoPixel(pixpin, numpix, brightness=1, auto_write=True)
|
strip = neopixel.NeoPixel(pixpin, numpix, brightness=1, auto_write=True)
|
||||||
|
|
||||||
|
|
||||||
def wheel(pos):
|
def wheel(pos):
|
||||||
# Input a value 0 to 255 to get a color value.
|
# Input a value 0 to 255 to get a color value.
|
||||||
# The colours are a transition r - g - b - back to r.
|
# The colours are a transition r - g - b - back to r.
|
||||||
|
|
@ -20,23 +22,27 @@ def wheel(pos):
|
||||||
return (int(pos * 3), int(255 - (pos*3)), 0)
|
return (int(pos * 3), int(255 - (pos*3)), 0)
|
||||||
elif pos < 170:
|
elif pos < 170:
|
||||||
pos -= 85
|
pos -= 85
|
||||||
return (int(255 - pos*3), 0, int(pos*3))
|
return (int(255 - pos * 3), 0, int(pos * 3))
|
||||||
else:
|
else:
|
||||||
pos -= 170
|
pos -= 170
|
||||||
return (0, int(pos*3), int(255 - pos*3))
|
return (0, int(pos * 3), int(255 - pos * 3))
|
||||||
|
|
||||||
|
|
||||||
def rainbow_cycle(wait):
|
def rainbow_cycle(wait):
|
||||||
for j in range(255*5):
|
for j in range(255 * 5):
|
||||||
for i in range(len(strip)):
|
for i in range(len(strip)):
|
||||||
idx = int ((i * 256 / len(strip)) + j)
|
idx = int((i * 256 / len(strip)) + j)
|
||||||
strip[i] = wheel(idx & 255)
|
strip[i] = wheel(idx & 255)
|
||||||
time.sleep(wait)
|
time.sleep(wait)
|
||||||
|
|
||||||
|
|
||||||
def rainbow(wait):
|
def rainbow(wait):
|
||||||
for j in range(255):
|
for j in range(255):
|
||||||
for i in range(len(strip)):
|
for i in range(len(strip)):
|
||||||
idx = int (i+j)
|
idx = int(i + j)
|
||||||
strip[i] = wheel(idx & 255)
|
strip[i] = wheel(idx & 255)
|
||||||
|
time.sleep(wait)
|
||||||
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
rainbow_cycle(0.05)
|
rainbow_cycle(0.05)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import board
|
import board
|
||||||
import pulseio
|
import pulseio
|
||||||
from digitalio import DigitalInOut, Direction
|
from digitalio import DigitalInOut, Direction
|
||||||
|
|
@ -10,10 +11,9 @@ pwm = pulseio.PWMOut(pwm_leds, frequency=1000, duty_cycle=0)
|
||||||
# digital LEDs connected on D2
|
# digital LEDs connected on D2
|
||||||
digital_leds = DigitalInOut(board.D2)
|
digital_leds = DigitalInOut(board.D2)
|
||||||
digital_leds.direction = Direction.OUTPUT
|
digital_leds.direction = Direction.OUTPUT
|
||||||
|
brightness = 0 # how bright the LED is
|
||||||
brightness = 0 # how bright the LED is
|
fade_amount = 1285 # 2% steping of 2^16
|
||||||
fade_amount = 1285 # 2% steping of 2^16
|
counter = 0 # counter to keep track of cycles
|
||||||
counter = 0 # counter to keep track of cycles
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,23 @@
|
||||||
|
import adafruit_fancyled.adafruit_fancyled as fancy
|
||||||
import board
|
import board
|
||||||
import neopixel
|
import neopixel
|
||||||
import time
|
from digitalio import DigitalInOut, Direction, Pull
|
||||||
from digitalio import DigitalInOut, Direction, Pull
|
|
||||||
import adafruit_fancyled.adafruit_fancyled as fancy
|
|
||||||
|
|
||||||
led_pin = board.D1 # which pin your pixels are connected to
|
led_pin = board.D1 # which pin your pixels are connected to
|
||||||
num_leds = 78 # how many LEDs you have
|
num_leds = 78 # how many LEDs you have
|
||||||
brightness = 1.0 # 0-1, higher number is brighter
|
brightness = 1.0 # 0-1, higher number is brighter
|
||||||
saturation = 255 # 0-255, 0 is pure white, 255 is fully saturated color
|
saturation = 255 # 0-255, 0 is pure white, 255 is fully saturated color
|
||||||
steps = 0.01 # how wide the bands of color are.
|
steps = 0.01 # how wide the bands of color are.
|
||||||
offset = 0 # cummulative steps
|
offset = 0 # cummulative steps
|
||||||
fadeup = True # start with fading up - increase steps until offset reaches 1
|
fadeup = True # start with fading up - increase steps until offset reaches 1
|
||||||
index = 8 # midway color selection
|
index = 8 # midway color selection
|
||||||
blend = True # color blending between palette indices
|
blend = True # color blending between palette indices
|
||||||
|
|
||||||
# initialize list with all pixels off
|
# initialize list with all pixels off
|
||||||
palette = [ 0 ] * num_leds
|
palette = [0] * num_leds
|
||||||
|
|
||||||
# Declare a NeoPixel object on led_pin with num_leds as pixels
|
# Declare a NeoPixel object on led_pin with num_leds as pixels
|
||||||
# No auto-write.
|
# No auto-write.
|
||||||
# Set brightness to max.
|
# Set brightness to max.
|
||||||
# We will be using FancyLED's brightness control.
|
# We will be using FancyLED's brightness control.
|
||||||
strip = neopixel.NeoPixel(led_pin, num_leds, brightness=1, auto_write=False)
|
strip = neopixel.NeoPixel(led_pin, num_leds, brightness=1, auto_write=False)
|
||||||
|
|
@ -28,127 +27,130 @@ button = DigitalInOut(board.D2)
|
||||||
button.direction = Direction.INPUT
|
button.direction = Direction.INPUT
|
||||||
button.pull = Pull.UP
|
button.pull = Pull.UP
|
||||||
prevkeystate = False
|
prevkeystate = False
|
||||||
ledmode = 0 # button press counter, switch color palettes
|
ledmode = 0 # button press counter, switch color palettes
|
||||||
|
|
||||||
# FancyLED allows for assigning a color palette using these formats:
|
# FancyLED allows for assigning a color palette using these formats:
|
||||||
# * The first (5) palettes here are mixing between 2-elements
|
# * The first (5) palettes here are mixing between 2-elements
|
||||||
# * The last (3) palettes use a format identical to the FastLED Arduino Library
|
# * The last (3) palettes use a format identical to the FastLED Arduino Library
|
||||||
# see FastLED - colorpalettes.cpp
|
# see FastLED - colorpalettes.cpp
|
||||||
forest = [ fancy.CRGB( 0, 255, 0 ), # green
|
forest = [fancy.CRGB(0, 255, 0), # green
|
||||||
fancy.CRGB( 255, 255, 0) ] # yellow
|
fancy.CRGB(255, 255, 0)] # yellow
|
||||||
|
|
||||||
ocean = [ fancy.CRGB( 0, 0, 255 ), # blue
|
ocean = [fancy.CRGB(0, 0, 255), # blue
|
||||||
fancy.CRGB( 0, 255, 0 ) ] # green
|
fancy.CRGB(0, 255, 0)] # green
|
||||||
|
|
||||||
purple = [ fancy.CRGB( 160, 32, 240 ), # purple
|
purple = [fancy.CRGB(160, 32, 240), # purple
|
||||||
fancy.CRGB( 238, 130, 238 ) ] # violet
|
fancy.CRGB(238, 130, 238)] # violet
|
||||||
|
|
||||||
all_colors = [ fancy.CRGB( 0, 0, 0 ), # black
|
all_colors = [fancy.CRGB(0, 0, 0), # black
|
||||||
fancy.CRGB( 255, 255, 255 ) ] # white
|
fancy.CRGB(255, 255, 255)] # white
|
||||||
|
|
||||||
washed_out = [ fancy.CRGB( 0, 0, 0 ), # black
|
washed_out = [fancy.CRGB(0, 0, 0), # black
|
||||||
fancy.CRGB( 255, 0, 255 ) ] # purple
|
fancy.CRGB(255, 0, 255)] # purple
|
||||||
|
|
||||||
rainbow = [ 0xFF0000, 0xD52A00, 0xAB5500, 0xAB7F00,
|
rainbow = [0xFF0000, 0xD52A00, 0xAB5500, 0xAB7F00,
|
||||||
0xABAB00, 0x56D500, 0x00FF00, 0x00D52A,
|
0xABAB00, 0x56D500, 0x00FF00, 0x00D52A,
|
||||||
0x00AB55, 0x0056AA, 0x0000FF, 0x2A00D5,
|
0x00AB55, 0x0056AA, 0x0000FF, 0x2A00D5,
|
||||||
0x5500AB, 0x7F0081, 0xAB0055, 0xD5002B ]
|
0x5500AB, 0x7F0081, 0xAB0055, 0xD5002B]
|
||||||
|
|
||||||
rainbow_stripe= [ 0xFF0000, 0x000000, 0xAB5500, 0x000000,
|
rainbow_stripe = [0xFF0000, 0x000000, 0xAB5500, 0x000000,
|
||||||
0xABAB00, 0x000000, 0x00FF00, 0x000000,
|
0xABAB00, 0x000000, 0x00FF00, 0x000000,
|
||||||
0x00AB55, 0x000000, 0x0000FF, 0x000000,
|
0x00AB55, 0x000000, 0x0000FF, 0x000000,
|
||||||
0x5500AB, 0x000000, 0xAB0055, 0x000000 ]
|
0x5500AB, 0x000000, 0xAB0055, 0x000000]
|
||||||
|
|
||||||
heat_colors = [ 0x330000, 0x660000, 0x990000, 0xCC0000, 0xFF0000,
|
heat_colors = [0x330000, 0x660000, 0x990000, 0xCC0000, 0xFF0000,
|
||||||
0xFF3300, 0xFF6600, 0xFF9900, 0xFFCC00, 0xFFFF00,
|
0xFF3300, 0xFF6600, 0xFF9900, 0xFFCC00, 0xFFFF00,
|
||||||
0xFFFF33, 0xFFFF66, 0xFFFF99, 0xFFFFCC ]
|
0xFFFF33, 0xFFFF66, 0xFFFF99, 0xFFFFCC]
|
||||||
|
|
||||||
|
|
||||||
def wheel(pos):
|
def wheel(pos):
|
||||||
|
|
||||||
# Input a value 0 to 255 to get a color value.
|
# Input a value 0 to 255 to get a color value.
|
||||||
# The colours are a transition r - g - b - back to r.
|
# The colours are a transition r - g - b - back to r.
|
||||||
if (pos < 0) or (pos > 255):
|
if (pos < 0) or (pos > 255):
|
||||||
return (0, 0, 0)
|
return (0, 0, 0)
|
||||||
if (pos < 85):
|
if pos < 85:
|
||||||
return (int(pos * 3), int(255 - (pos*3)), 0)
|
return (int(pos * 3), int(255 - (pos * 3)), 0)
|
||||||
elif (pos < 170):
|
elif pos < 170:
|
||||||
pos -= 85
|
pos -= 85
|
||||||
return (int(255 - pos*3), 0, int(pos*3))
|
return (int(255 - pos * 3), 0, int(pos * 3))
|
||||||
else:
|
else:
|
||||||
pos -= 170
|
pos -= 170
|
||||||
return (0, int(pos*3), int(255 - pos*3))
|
return (0, int(pos * 3), int(255 - pos * 3))
|
||||||
|
|
||||||
|
|
||||||
def remapRange(value, leftMin, leftMax, rightMin, rightMax):
|
def remapRange(value, leftMin, leftMax, rightMin, rightMax):
|
||||||
|
# this remaps a value fromhere original (left) range to new (right) range
|
||||||
# this remaps a value from original (left) range to new (right) range
|
|
||||||
# Figure out how 'wide' each range is
|
# Figure out how 'wide' each range is
|
||||||
leftSpan = leftMax - leftMin
|
leftSpan = leftMax - leftMin
|
||||||
rightSpan = rightMax - rightMin
|
rightSpan = rightMax - rightMin
|
||||||
|
|
||||||
|
# Convert the left range into a 0-1 range (int)
|
||||||
|
valueScaled = int(value - leftMin) / int(leftSpan)
|
||||||
|
|
||||||
# Convert the 0-1 range into a value in the right range.
|
# Convert the 0-1 range into a value in the right range.
|
||||||
return int(rightMin + (valueScaled * rightSpan))
|
return int(rightMin + (valueScaled * rightSpan))
|
||||||
|
|
||||||
def shortkeypress(color_palette):
|
|
||||||
|
|
||||||
|
def shortkeypress(color_palette):
|
||||||
color_palette += 1
|
color_palette += 1
|
||||||
|
|
||||||
if ( color_palette > 6):
|
if color_palette > 6:
|
||||||
color_palette = 1
|
color_palette = 1
|
||||||
|
|
||||||
return ( color_palette )
|
return color_palette
|
||||||
|
|
||||||
while True:
|
|
||||||
|
while True:
|
||||||
|
|
||||||
# check for button press
|
# check for button press
|
||||||
currkeystate = button.value
|
currkeystate = button.value
|
||||||
|
|
||||||
# button press, move to next pattern
|
# button press, move to next pattern
|
||||||
if ( ( prevkeystate == False ) and ( currkeystate == True ) ):
|
if (prevkeystate is not True) and currkeystate:
|
||||||
ledmode = shortkeypress(ledmode)
|
ledmode = shortkeypress(ledmode)
|
||||||
|
|
||||||
# save button press state
|
# save button press state
|
||||||
prevkeystate = currkeystate
|
prevkeystate = currkeystate
|
||||||
|
|
||||||
# Fire Colors [ HEAT ]
|
# Fire Colors [ HEAT ]
|
||||||
if ( ledmode == 1 ):
|
if ledmode == 1:
|
||||||
palette = heat_colors
|
palette = heat_colors
|
||||||
|
|
||||||
# Forest
|
# Forest
|
||||||
elif ( ledmode == 2 ):
|
elif ledmode == 2:
|
||||||
palette = forest
|
palette = forest
|
||||||
|
|
||||||
# Ocean
|
# Ocean
|
||||||
elif ( ledmode == 3 ):
|
elif ledmode == 3:
|
||||||
palette = ocean
|
palette = ocean
|
||||||
|
|
||||||
# Purple Lovers
|
# Purple Lovers
|
||||||
elif ( ledmode == 4 ):
|
elif ledmode == 4:
|
||||||
palette = purple
|
palette = purple
|
||||||
|
|
||||||
# All the colors!
|
# All the colors!
|
||||||
elif ( ledmode == 5 ):
|
elif ledmode == 5:
|
||||||
palette = rainbow
|
palette = rainbow
|
||||||
|
|
||||||
# Rainbow stripes
|
# Rainbow stripes
|
||||||
elif ( ledmode == 6 ):
|
elif ledmode == 6:
|
||||||
palette = rainbow_stripe
|
palette = rainbow_stripe
|
||||||
|
|
||||||
# All the colors except the greens, washed out
|
# All the colors except the greens, washed out
|
||||||
elif ( ledmode == 7 ):
|
elif ledmode == 7:
|
||||||
palette = washed_out
|
palette = washed_out
|
||||||
|
|
||||||
for i in range(num_leds):
|
for i in range(num_leds):
|
||||||
color = fancy.palette_lookup(palette, offset + i / num_leds)
|
color = fancy.palette_lookup(palette, offset + i / num_leds)
|
||||||
color = fancy.gamma_adjust(color, brightness=brightness)
|
color = fancy.gamma_adjust(color, brightness=brightness)
|
||||||
strip[i] = color.pack()
|
strip[i] = color.pack()
|
||||||
strip.show()
|
strip.show()
|
||||||
|
|
||||||
if ( fadeup ):
|
if fadeup:
|
||||||
offset += steps
|
offset += steps
|
||||||
if ( offset >= 1 ):
|
if offset >= 1:
|
||||||
fadeup = False
|
fadeup = False
|
||||||
else:
|
else:
|
||||||
offset -= steps
|
offset -= steps
|
||||||
if ( offset <= 0 ):
|
if offset <= 0:
|
||||||
fadeup = True
|
fadeup = True
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
# Annoy-O-Matic Sound Prank Device
|
# Annoy-O-Matic Sound Prank Device
|
||||||
# choose from a variety of sounds and timings to drive your victim bonkers
|
# choose from a variety of sounds and timings to drive your victim bonkers
|
||||||
import pulseio
|
|
||||||
import board
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
import board
|
||||||
|
import pulseio
|
||||||
|
|
||||||
piezo = pulseio.PWMOut(board.D0, duty_cycle=0, frequency=440,
|
piezo = pulseio.PWMOut(board.D0, duty_cycle=0, frequency=440,
|
||||||
variable_frequency=True)
|
variable_frequency=True)
|
||||||
|
|
||||||
|
|
@ -33,26 +34,28 @@ ringtone_tempo = 1.6 # suggested Nokia 0.9 , iPhone 1.3 , Rickroll 2.0
|
||||||
|
|
||||||
|
|
||||||
def annoy_beep(frequency, length, repeat, rest, interval):
|
def annoy_beep(frequency, length, repeat, rest, interval):
|
||||||
for r in range(repeat):
|
for _ in range(repeat):
|
||||||
piezo.frequency = frequency # 2600 is a nice choice
|
piezo.frequency = frequency # 2600 is a nice choice
|
||||||
piezo.duty_cycle = 65536//2 # on 50%
|
piezo.duty_cycle = 65536 // 2 # on 50%
|
||||||
time.sleep(length) # sound on
|
time.sleep(length) # sound on
|
||||||
piezo.duty_cycle = 0 # off
|
piezo.duty_cycle = 0 # off
|
||||||
time.sleep(rest)
|
time.sleep(rest)
|
||||||
time.sleep(interval) # wait time until next beep
|
time.sleep(interval) # wait time until next beep
|
||||||
|
|
||||||
|
|
||||||
def annoy_doorbell(interval):
|
def annoy_doorbell(interval):
|
||||||
piezo.frequency = 740
|
piezo.frequency = 740
|
||||||
piezo.duty_cycle = 65536//2
|
piezo.duty_cycle = 65536 // 2
|
||||||
time.sleep(0.85)
|
time.sleep(0.85)
|
||||||
piezo.duty_cycle = 0
|
piezo.duty_cycle = 0
|
||||||
time.sleep(0.05)
|
time.sleep(0.05)
|
||||||
piezo.frequency = 588
|
piezo.frequency = 588
|
||||||
piezo.duty_cycle = 65536//2
|
piezo.duty_cycle = 65536 // 2
|
||||||
time.sleep(1.25)
|
time.sleep(1.25)
|
||||||
piezo.duty_cycle = 0
|
piezo.duty_cycle = 0
|
||||||
time.sleep(interval)
|
time.sleep(interval)
|
||||||
|
|
||||||
|
|
||||||
def annoy_ringtone(ringtone, tempo, interval):
|
def annoy_ringtone(ringtone, tempo, interval):
|
||||||
# ringtone 1: Nokia
|
# ringtone 1: Nokia
|
||||||
# ringtone 2: Apple iPhone
|
# ringtone 2: Apple iPhone
|
||||||
|
|
@ -61,94 +64,94 @@ def annoy_ringtone(ringtone, tempo, interval):
|
||||||
# tempo is length of whole note in seconds, e.g. 1.5
|
# tempo is length of whole note in seconds, e.g. 1.5
|
||||||
# set up time signature
|
# set up time signature
|
||||||
whole_note = tempo # adjust this to change tempo of everything
|
whole_note = tempo # adjust this to change tempo of everything
|
||||||
dotted_whole_note = whole_note * 1.5
|
# dotted_whole_note = whole_note * 1.5
|
||||||
# these notes are fractions of the whole note
|
# these notes are fractions of the whole note
|
||||||
half_note = whole_note / 2
|
# half_note = whole_note / 2
|
||||||
dotted_half_note = half_note * 1.5
|
# dotted_half_note = half_note * 1.5
|
||||||
quarter_note = whole_note / 4
|
quarter_note = whole_note / 4
|
||||||
dotted_quarter_note = quarter_note * 1.5
|
# dotted_quarter_note = quarter_note * 1.5
|
||||||
eighth_note = whole_note / 8
|
eighth_note = whole_note / 8
|
||||||
dotted_eighth_note = eighth_note * 1.5
|
dotted_eighth_note = eighth_note * 1.5
|
||||||
sixteenth_note = whole_note / 16
|
sixteenth_note = whole_note / 16
|
||||||
|
|
||||||
# set up note values
|
# set up note values
|
||||||
A2 = 110
|
# A2 = 110
|
||||||
As2 = 117 # 's' stands for sharp: A#2
|
# As2 = 117 # 's' stands for sharp: A#2
|
||||||
Bb2 = 117
|
# Bb2 = 117
|
||||||
B2 = 123
|
# B2 = 123
|
||||||
|
|
||||||
C3 = 131
|
# C3 = 131
|
||||||
Cs3 = 139
|
# Cs3 = 139
|
||||||
Db3 = 139
|
# Db3 = 139
|
||||||
D3 = 147
|
# D3 = 147
|
||||||
Ds3 = 156
|
# Ds3 = 156
|
||||||
Eb3 = 156
|
# Eb3 = 156
|
||||||
E3 = 165
|
# E3 = 165
|
||||||
F3 = 175
|
# F3 = 175
|
||||||
Fs3 = 185
|
# Fs3 = 185
|
||||||
Gb3 = 185
|
# Gb3 = 185
|
||||||
G3 = 196
|
# G3 = 196
|
||||||
Gs3 = 208
|
# Gs3 = 208
|
||||||
Ab3 = 208
|
# Ab3 = 208
|
||||||
A3 = 220
|
A3 = 220
|
||||||
As3 = 233
|
# As3 = 233
|
||||||
Bb3 = 233
|
# Bb3 = 233
|
||||||
B3 = 247
|
B3 = 247
|
||||||
|
|
||||||
C4 = 262
|
# C4 = 262
|
||||||
Cs4 = 277
|
Cs4 = 277
|
||||||
Db4 = 277
|
# Db4 = 277
|
||||||
D4 = 294
|
D4 = 294
|
||||||
Ds4 = 311
|
# Ds4 = 311
|
||||||
Eb4 = 311
|
# Eb4 = 311
|
||||||
E4 = 330
|
E4 = 330
|
||||||
F4 = 349
|
# F4 = 349
|
||||||
Fs4 = 370
|
Fs4 = 370
|
||||||
Gb4 = 370
|
# Gb4 = 370
|
||||||
G4 = 392
|
G4 = 392
|
||||||
Gs4 = 415
|
# Gs4 = 415
|
||||||
Ab4 = 415
|
# Ab4 = 415
|
||||||
A4 = 440
|
# A4 = 440
|
||||||
As4 = 466
|
# As4 = 466
|
||||||
Bb4 = 466
|
# Bb4 = 466
|
||||||
B4 = 494
|
B4 = 494
|
||||||
|
|
||||||
C5 = 523
|
# C5 = 523
|
||||||
Cs5 = 554
|
Cs5 = 554
|
||||||
Db5 = 554
|
# Db5 = 554
|
||||||
D5 = 587
|
D5 = 587
|
||||||
Ds5 = 622
|
# Ds5 = 622
|
||||||
Eb5 = 622
|
# Eb5 = 622
|
||||||
E5 = 659
|
E5 = 659
|
||||||
F5 = 698
|
# F5 = 698
|
||||||
Fs5 = 740
|
Fs5 = 740
|
||||||
Gb5 = 740
|
# Gb5 = 740
|
||||||
G5 = 784
|
# G5 = 784
|
||||||
Gs5 = 831
|
Gs5 = 831
|
||||||
Ab5 = 831
|
# Ab5 = 831
|
||||||
A5 = 880
|
A5 = 880
|
||||||
As5 = 932
|
# As5 = 932
|
||||||
Bb5 = 932
|
# Bb5 = 932
|
||||||
B5 = 987
|
B5 = 987
|
||||||
|
|
||||||
# here's another way to express the note pitch, double the previous octave
|
# here's another way to express the note pitch, double the previous octave
|
||||||
C6 = C5 * 2
|
# C6 = C5 * 2
|
||||||
Cs6 = Cs5 * 2
|
Cs6 = Cs5 * 2
|
||||||
Db6 = Db5 * 2
|
# Db6 = Db5 * 2
|
||||||
D6 = D5 * 2
|
D6 = D5 * 2
|
||||||
Ds6 = Ds5 * 2
|
# Ds6 = Ds5 * 2
|
||||||
Eb6 = Eb5 * 2
|
# Eb6 = Eb5 * 2
|
||||||
E6 = E5 * 2
|
E6 = E5 * 2
|
||||||
F6 = F5 * 2
|
# F6 = F5 * 2
|
||||||
Fs6 = Fs5 * 2
|
# Fs6 = Fs5 * 2
|
||||||
Gb6 = Gb5 * 2
|
# Gb6 = Gb5 * 2
|
||||||
G6 = G5 * 2
|
# G6 = G5 * 2
|
||||||
Gs6 = Gs5 * 2
|
# Gs6 = Gs5 * 2
|
||||||
Ab6 = Ab5 * 2
|
# Ab6 = Ab5 * 2
|
||||||
A6 = A5 * 2
|
# A6 = A5 * 2
|
||||||
As6 = As5 * 2
|
# As6 = As5 * 2
|
||||||
Bb6 = Bb5 * 2
|
# Bb6 = Bb5 * 2
|
||||||
B6 = B5 * 2
|
# B6 = B5 * 2
|
||||||
|
|
||||||
if ringtone == 1:
|
if ringtone == 1:
|
||||||
# Nokia
|
# Nokia
|
||||||
|
|
@ -162,7 +165,7 @@ def annoy_ringtone(ringtone, tempo, interval):
|
||||||
|
|
||||||
for n in range(len(nokia_ringtone)):
|
for n in range(len(nokia_ringtone)):
|
||||||
piezo.frequency = (nokia_ringtone[n][0])
|
piezo.frequency = (nokia_ringtone[n][0])
|
||||||
piezo.duty_cycle = 65536//2 # on 50%
|
piezo.duty_cycle = 65536 // 2 # on 50%
|
||||||
time.sleep(nokia_ringtone[n][1]) # note duration
|
time.sleep(nokia_ringtone[n][1]) # note duration
|
||||||
piezo.duty_cycle = 0 # off
|
piezo.duty_cycle = 0 # off
|
||||||
time.sleep(0.01)
|
time.sleep(0.01)
|
||||||
|
|
@ -178,64 +181,67 @@ def annoy_ringtone(ringtone, tempo, interval):
|
||||||
|
|
||||||
for n in range(len(iPhone_ringtone)):
|
for n in range(len(iPhone_ringtone)):
|
||||||
piezo.frequency = (iPhone_ringtone[n][0])
|
piezo.frequency = (iPhone_ringtone[n][0])
|
||||||
piezo.duty_cycle = 65536//2 # on 50%
|
piezo.duty_cycle = 65536 // 2 # on 50%
|
||||||
time.sleep(iPhone_ringtone[n][1]) # note duration
|
time.sleep(iPhone_ringtone[n][1]) # note duration
|
||||||
piezo.duty_cycle = 0 # off
|
piezo.duty_cycle = 0 # off
|
||||||
time.sleep(0.01)
|
time.sleep(0.01)
|
||||||
|
|
||||||
if ringtone == 3:
|
if ringtone == 3:
|
||||||
# Rickroll
|
# Rickroll
|
||||||
rick_ringtone = [[A3, sixteenth_note], [B3, sixteenth_note],
|
rick_ringtone = [[A3, sixteenth_note], [B3, sixteenth_note],
|
||||||
[D4, sixteenth_note], [B3, sixteenth_note],
|
[D4, sixteenth_note], [B3, sixteenth_note],
|
||||||
[Fs4, dotted_eighth_note], [Fs4, sixteenth_note],
|
[Fs4, dotted_eighth_note], [Fs4, sixteenth_note],
|
||||||
[Fs4, eighth_note], [E4, eighth_note],
|
[Fs4, eighth_note], [E4, eighth_note],
|
||||||
[E4, quarter_note],
|
[E4, quarter_note],
|
||||||
[A3, sixteenth_note], [B3, sixteenth_note],
|
[A3, sixteenth_note], [B3, sixteenth_note],
|
||||||
[Cs4, sixteenth_note], [A3, sixteenth_note],
|
[Cs4, sixteenth_note], [A3, sixteenth_note],
|
||||||
[E4, dotted_eighth_note], [E4, sixteenth_note],
|
[E4, dotted_eighth_note], [E4, sixteenth_note],
|
||||||
[E4, eighth_note], [D4, eighth_note],
|
[E4, eighth_note], [D4, eighth_note],
|
||||||
[D4, sixteenth_note], [Cs4, sixteenth_note],
|
[D4, sixteenth_note], [Cs4, sixteenth_note],
|
||||||
[B3, eighth_note]]
|
[B3, eighth_note]]
|
||||||
|
|
||||||
for n in range(len(rick_ringtone)):
|
for n in range(len(rick_ringtone)):
|
||||||
piezo.frequency = (rick_ringtone[n][0])
|
piezo.frequency = (rick_ringtone[n][0])
|
||||||
piezo.duty_cycle = 65536//2 # on 50%
|
piezo.duty_cycle = 65536 // 2 # on 50%
|
||||||
time.sleep(rick_ringtone[n][1]) # note duration
|
time.sleep(rick_ringtone[n][1]) # note duration
|
||||||
piezo.duty_cycle = 0 # off
|
piezo.duty_cycle = 0 # off
|
||||||
time.sleep(0.035)
|
time.sleep(0.035)
|
||||||
|
|
||||||
time.sleep(interval)
|
time.sleep(interval)
|
||||||
|
|
||||||
|
|
||||||
def annoy_crickets(repeat, interval):
|
def annoy_crickets(repeat, interval):
|
||||||
for i in range(repeat):
|
for _ in range(repeat):
|
||||||
for r in range(6):
|
for _ in range(6):
|
||||||
piezo.frequency = 8000 # 2600 is a nice choice
|
piezo.frequency = 8000 # 2600 is a nice choice
|
||||||
piezo.duty_cycle = 65536//2 # on 50%
|
piezo.duty_cycle = 65536 // 2 # on 50%
|
||||||
time.sleep(0.02) # sound on
|
time.sleep(0.02) # sound on
|
||||||
piezo.duty_cycle = 0 # off
|
piezo.duty_cycle = 0 # off
|
||||||
time.sleep(0.05)
|
time.sleep(0.05)
|
||||||
time.sleep(0.2)
|
time.sleep(0.2)
|
||||||
time.sleep(interval) # wait time until next beep
|
time.sleep(interval) # wait time until next beep
|
||||||
|
|
||||||
|
|
||||||
def annoy_teen_tone(interval):
|
def annoy_teen_tone(interval):
|
||||||
piezo.frequency = 17400
|
piezo.frequency = 17400
|
||||||
piezo.duty_cycle = 65536//2 # on 50%
|
piezo.duty_cycle = 65536 // 2 # on 50%
|
||||||
time.sleep(10)
|
time.sleep(10)
|
||||||
piezo.duty_cycle = 0
|
piezo.duty_cycle = 0
|
||||||
time.sleep(interval)
|
time.sleep(interval)
|
||||||
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
if annoy_mode is 1:
|
if annoy_mode == 1:
|
||||||
annoy_beep(frequency, length, repeat, rest, interval)
|
annoy_beep(frequency, length, repeat, rest, interval)
|
||||||
elif annoy_mode is 2:
|
elif annoy_mode == 2:
|
||||||
annoy_doorbell(interval)
|
annoy_doorbell(interval)
|
||||||
elif annoy_mode is 3:
|
elif annoy_mode == 3:
|
||||||
annoy_ringtone(ringtone, ringtone_tempo, interval)
|
annoy_ringtone(ringtone, ringtone_tempo, interval)
|
||||||
elif annoy_mode is 4:
|
elif annoy_mode == 4:
|
||||||
annoy_crickets(repeat, interval)
|
annoy_crickets(repeat, interval)
|
||||||
elif annoy_mode is 5:
|
elif annoy_mode == 5:
|
||||||
annoy_teen_tone(interval)
|
annoy_teen_tone(interval)
|
||||||
elif annoy_mode is 6:
|
elif annoy_mode == 6:
|
||||||
annoy_beep(5000, 0.2, 2, 0.05, 3)
|
annoy_beep(5000, 0.2, 2, 0.05, 3)
|
||||||
annoy_doorbell(3)
|
annoy_doorbell(3)
|
||||||
annoy_ringtone(1, 0.9, 3)
|
annoy_ringtone(1, 0.9, 3)
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
import digitalio
|
|
||||||
from board import *
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
import digitalio
|
||||||
from adafruit_hid.keyboard import Keyboard
|
from adafruit_hid.keyboard import Keyboard
|
||||||
from adafruit_hid.keycode import Keycode
|
from adafruit_hid.keycode import Keycode
|
||||||
|
from board import D13, D12, D11, D10, D9, D6, D5, A0, A1, A2, A3, A4, A5
|
||||||
|
|
||||||
# A simple neat keyboard demo in circuitpython
|
# A simple neat keyboard demo in circuitpython
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import board
|
|
||||||
import busio
|
|
||||||
import adafruit_CCS811
|
import adafruit_CCS811
|
||||||
|
import board
|
||||||
|
import busio
|
||||||
import neopixel
|
import neopixel
|
||||||
|
|
||||||
# i2c interface for the gas sensor
|
# i2c interface for the gas sensor
|
||||||
|
|
@ -13,11 +13,11 @@ ccs = adafruit_CCS811.CCS811(i2c_bus)
|
||||||
# 1 - Temperature - Circuit Playground Built-In LEDs
|
# 1 - Temperature - Circuit Playground Built-In LEDs
|
||||||
# 2 - Total Volatile Organic Compounds [strip]
|
# 2 - Total Volatile Organic Compounds [strip]
|
||||||
# 3 - Co2 Output - NeoPixel [strip]
|
# 3 - Co2 Output - NeoPixel [strip]
|
||||||
num_leds = 8
|
num_leds = 8
|
||||||
temperature_pix = neopixel.NeoPixel(board.NEOPIXEL, num_leds, brightness=.1)
|
temperature_pix = neopixel.NeoPixel(board.NEOPIXEL, num_leds, brightness=.1)
|
||||||
tvoc_pix = neopixel.NeoPixel(board.A1, num_leds, bpp=4, brightness=.1)
|
tvoc_pix = neopixel.NeoPixel(board.A1, num_leds, bpp=4, brightness=.1)
|
||||||
co2_pix = neopixel.NeoPixel(board.A2, num_leds, bpp=4, brightness=.1)
|
co2_pix = neopixel.NeoPixel(board.A2, num_leds, bpp=4, brightness=.1)
|
||||||
led_draw = .05 # delay for LED pixel turn on/off
|
led_draw = .05 # delay for LED pixel turn on/off
|
||||||
|
|
||||||
# wait for the sensor to be ready and calibrate the thermistor
|
# wait for the sensor to be ready and calibrate the thermistor
|
||||||
while not ccs.data_ready:
|
while not ccs.data_ready:
|
||||||
|
|
@ -25,63 +25,76 @@ while not ccs.data_ready:
|
||||||
temp = ccs.temperature
|
temp = ccs.temperature
|
||||||
ccs.temp_offset = temp - 25.0
|
ccs.temp_offset = temp - 25.0
|
||||||
|
|
||||||
# clear all LEDs for breathing effect
|
|
||||||
|
# clear all LEDs for breathing effect
|
||||||
|
|
||||||
|
|
||||||
def clear_pix(delay):
|
def clear_pix(delay):
|
||||||
for i in range(0, num_leds):
|
for i in range(0, num_leds):
|
||||||
temperature_pix[i] = (0,0,0)
|
temperature_pix[i] = (0, 0, 0)
|
||||||
co2_pix[i] = (0,0,0,0)
|
co2_pix[i] = (0, 0, 0, 0)
|
||||||
tvoc_pix[i] = (0,0,0,0)
|
tvoc_pix[i] = (0, 0, 0, 0)
|
||||||
time.sleep(delay)
|
time.sleep(delay)
|
||||||
|
|
||||||
|
|
||||||
# Show Carbon Dioxide on a NeoPixel Strip
|
# Show Carbon Dioxide on a NeoPixel Strip
|
||||||
|
|
||||||
|
|
||||||
def co2_led_meter():
|
def co2_led_meter():
|
||||||
co2_floor = 400
|
co2_floor = 400
|
||||||
co2_ceiling = 8192
|
co2_ceiling = 8192
|
||||||
|
|
||||||
# Map CO2 range to 8 LED NeoPixel Stick
|
# Map CO2 range to 8 LED NeoPixel Stick
|
||||||
co2_range = co2_ceiling - co2_floor
|
co2_range = co2_ceiling - co2_floor
|
||||||
co2_led_steps = co2_range / num_leds
|
co2_led_steps = co2_range / num_leds
|
||||||
co2_leds = int( (ccs.eCO2 - co2_floor ) / co2_led_steps)
|
co2_leds = int((ccs.eCO2 - co2_floor) / co2_led_steps)
|
||||||
|
|
||||||
# Insert Colors
|
# Insert Colors
|
||||||
for i in range(0, (co2_leds - 1) ):
|
for i in range(0, (co2_leds - 1)):
|
||||||
co2_pix[i] = (255,0,255,0)
|
co2_pix[i] = (255, 0, 255, 0)
|
||||||
time.sleep(led_draw)
|
time.sleep(led_draw)
|
||||||
|
|
||||||
|
|
||||||
# Show Total Volatile Organic Compounds on a NeoPixel Strip
|
# Show Total Volatile Organic Compounds on a NeoPixel Strip
|
||||||
|
|
||||||
|
|
||||||
def tvoc_led_meter():
|
def tvoc_led_meter():
|
||||||
tvoc_floor = 0
|
tvoc_floor = 0
|
||||||
tvoc_ceiling = 1187
|
tvoc_ceiling = 1187
|
||||||
|
|
||||||
# Map CO2 range to 8 LED NeoPixel Stick
|
# Map CO2 range to 8 LED NeoPixel Stick
|
||||||
tvoc_range = tvoc_ceiling - tvoc_floor
|
tvoc_range = tvoc_ceiling - tvoc_floor
|
||||||
tvoc_led_steps = tvoc_range / num_leds
|
tvoc_led_steps = tvoc_range / num_leds
|
||||||
tvoc_leds = int(ccs.TVOC / tvoc_led_steps)
|
tvoc_leds = int(ccs.TVOC / tvoc_led_steps)
|
||||||
|
|
||||||
# Insert Colors
|
# Insert Colors
|
||||||
for i in range(0, (tvoc_leds - 1) ):
|
for i in range(0, (tvoc_leds - 1)):
|
||||||
tvoc_pix[i] = (0,0,255,0)
|
tvoc_pix[i] = (0, 0, 255, 0)
|
||||||
time.sleep(led_draw)
|
time.sleep(led_draw)
|
||||||
|
|
||||||
|
|
||||||
# Show Temperature on Circuit Playground built-in NeoPixels
|
# Show Temperature on Circuit Playground built-in NeoPixels
|
||||||
|
|
||||||
|
|
||||||
def temp_led_meter():
|
def temp_led_meter():
|
||||||
temp_floor = 23
|
temp_floor = 23
|
||||||
temp_ceiling = 36
|
temp_ceiling = 36
|
||||||
|
|
||||||
# Map temperature range to 8 LEDs on Circuit Playground
|
# Map temperature range to 8 LEDs on Circuit Playground
|
||||||
temp_range = temp_ceiling - temp_floor
|
temp_range = temp_ceiling - temp_floor
|
||||||
temp_led_steps = temp_range / num_leds
|
temp_led_steps = temp_range / num_leds
|
||||||
temp_leds = int( (ccs.temperature - temp_floor ) / temp_led_steps)
|
temp_leds = int((ccs.temperature - temp_floor) / temp_led_steps)
|
||||||
|
|
||||||
# Insert Colors
|
# Insert Colors
|
||||||
for i in range(0, (temp_leds - 1) ):
|
for i in range(0, (temp_leds - 1)):
|
||||||
temperature_pix[i] = (255,255,0)
|
temperature_pix[i] = (255, 255, 0)
|
||||||
time.sleep(led_draw)
|
time.sleep(led_draw)
|
||||||
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
# print to console
|
# print to console
|
||||||
# - co2
|
# - co2
|
||||||
# - total voltatile organic compounds
|
# - total voltatile organic compounds
|
||||||
# - temperature in celsius
|
# - temperature in celsius
|
||||||
print("CO2: ", ccs.eCO2, " TVOC:", ccs.TVOC, " temp:", ccs.temperature)
|
print("CO2: ", ccs.eCO2, " TVOC:", ccs.TVOC, " temp:", ccs.temperature)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
import adafruit_sgp30
|
||||||
import board
|
import board
|
||||||
import busio
|
import busio
|
||||||
import adafruit_sgp30
|
|
||||||
|
|
||||||
i2c = busio.I2C(board.SCL, board.SDA, frequency=100000)
|
i2c = busio.I2C(board.SCL, board.SDA, frequency=100000)
|
||||||
|
|
||||||
|
|
@ -13,26 +14,29 @@ sgp30.set_iaq_baseline(0x8973, 0x8aae)
|
||||||
# highest tVOC recorded in 30 seconds
|
# highest tVOC recorded in 30 seconds
|
||||||
highest_breath_result = 0
|
highest_breath_result = 0
|
||||||
|
|
||||||
def warmup_message():
|
|
||||||
|
|
||||||
warmup_time = 20
|
def warmup_message():
|
||||||
|
warmup_time = 20
|
||||||
warmup_counter = 0
|
warmup_counter = 0
|
||||||
|
|
||||||
co2eq, tvoc = sgp30.iaq_measure() # initial read required to get sensor going
|
# initial read required to get sensor going
|
||||||
|
sgp30.iaq_measure()
|
||||||
|
|
||||||
print()
|
print()
|
||||||
print("Warming Up [%d seconds]..." % warmup_time)
|
print("Warming Up [%d seconds]..." % warmup_time)
|
||||||
|
|
||||||
while ( warmup_counter <= 20 ):
|
while warmup_counter <= 20:
|
||||||
print('.', end='')
|
print('.', end='')
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
warmup_counter += 1
|
warmup_counter += 1
|
||||||
|
|
||||||
def get_breath_reading():
|
|
||||||
|
|
||||||
breath_time = 30 # seconds to record breath reading
|
def get_breath_reading():
|
||||||
breath_counter = 0 # one second count up to breath_time value
|
breath_time = 30 # seconds to record breath reading
|
||||||
breath_saves = [0] * ( breath_time + 1 ) # initialize list with empty values
|
# one second count up to breath_time value
|
||||||
|
breath_counter = 0
|
||||||
|
# initialize list with empty values
|
||||||
|
breath_saves = [0] * (breath_time + 1)
|
||||||
|
|
||||||
print()
|
print()
|
||||||
print("We will collect breath samples for 30 seconds.")
|
print("We will collect breath samples for 30 seconds.")
|
||||||
|
|
@ -40,27 +44,31 @@ def get_breath_reading():
|
||||||
input(" *** Press a key when ready. *** ")
|
input(" *** Press a key when ready. *** ")
|
||||||
print()
|
print()
|
||||||
|
|
||||||
while ( breath_counter <= breath_time ):
|
while breath_counter <= breath_time:
|
||||||
co2eq, tvoc = sgp30.iaq_measure()
|
_, tvoc = sgp30.iaq_measure()
|
||||||
breath_saves[breath_counter] = tvoc
|
breath_saves[breath_counter] = tvoc
|
||||||
print(tvoc, ', ', end='')
|
print(tvoc, ', ', end='')
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
breath_counter += 1
|
breath_counter += 1
|
||||||
|
|
||||||
breath_saves = sorted(breath_saves)
|
breath_saves = sorted(breath_saves)
|
||||||
highest_breath_result = breath_saves[breath_counter - 1]
|
result = breath_saves[breath_counter - 1]
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
return(highest_breath_result)
|
|
||||||
|
|
||||||
# show the highest reading recorded
|
# show the highest reading recorded
|
||||||
def show_results(highest_breath_result):
|
|
||||||
|
|
||||||
|
def show_results(breath_result):
|
||||||
print()
|
print()
|
||||||
print()
|
print()
|
||||||
print("peak VOC reading:", highest_breath_result)
|
print("peak VOC reading:", breath_result)
|
||||||
print()
|
print()
|
||||||
input("Press any key to test again")
|
input("Press any key to test again")
|
||||||
print()
|
print()
|
||||||
|
|
||||||
|
|
||||||
# main
|
# main
|
||||||
while True:
|
while True:
|
||||||
warmup_message()
|
warmup_message()
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
# Chilled Drinkibot
|
# Chilled Drinkibot
|
||||||
|
|
||||||
from digitalio import DigitalInOut, Direction, Pull
|
|
||||||
import board
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
import board
|
||||||
|
from digitalio import DigitalInOut, Direction, Pull
|
||||||
|
|
||||||
led = DigitalInOut(board.D2) # Button LED
|
led = DigitalInOut(board.D2) # Button LED
|
||||||
led.direction = Direction.OUTPUT
|
led.direction = Direction.OUTPUT
|
||||||
|
|
||||||
|
|
@ -17,7 +18,6 @@ chiller.direction = Direction.OUTPUT
|
||||||
pump = DigitalInOut(board.D4) # Pin to control the pump
|
pump = DigitalInOut(board.D4) # Pin to control the pump
|
||||||
pump.direction = Direction.OUTPUT
|
pump.direction = Direction.OUTPUT
|
||||||
|
|
||||||
|
|
||||||
chillTime = 5 # How many _minutes_ of cooling
|
chillTime = 5 # How many _minutes_ of cooling
|
||||||
|
|
||||||
pumpTime = 35 # How many seconds of pumping
|
pumpTime = 35 # How many seconds of pumping
|
||||||
|
|
@ -26,18 +26,18 @@ while True:
|
||||||
# we could also just do "led.value = not button.value" !
|
# we could also just do "led.value = not button.value" !
|
||||||
if button.value:
|
if button.value:
|
||||||
print('not')
|
print('not')
|
||||||
led.value = False # turn OFF LED
|
led.value = False # turn OFF LED
|
||||||
chiller.value = False # turn OFF chiller
|
chiller.value = False # turn OFF chiller
|
||||||
pump.value = False # turn OFF pump
|
pump.value = False # turn OFF pump
|
||||||
else:
|
else:
|
||||||
print('pressed')
|
print('pressed')
|
||||||
led.value = True # turn ON LED
|
led.value = True # turn ON LED
|
||||||
chiller.value = True # turn ON chiller
|
chiller.value = True # turn ON chiller
|
||||||
time.sleep(chillTime * 60) # wait chiller time (in seconds)
|
time.sleep(chillTime * 60) # wait chiller time (in seconds)
|
||||||
chiller.value = False # turn OFF chiller
|
chiller.value = False # turn OFF chiller
|
||||||
pump.value = True # turn ON pump
|
pump.value = True # turn ON pump
|
||||||
time.sleep(pumpTime) # wait pump time
|
time.sleep(pumpTime) # wait pump time
|
||||||
pump.value = False # turn OFF pump
|
pump.value = False # turn OFF pump
|
||||||
led.value = False # turn OFF LED
|
led.value = False # turn OFF LED
|
||||||
|
|
||||||
time.sleep(0.01) # debounce delay
|
time.sleep(0.01) # debounce delay
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,23 @@
|
||||||
import time
|
import time
|
||||||
import machine
|
|
||||||
|
import adafruit_ssd1306
|
||||||
|
import bitbangio as io
|
||||||
|
import board
|
||||||
import network
|
import network
|
||||||
import ntptime
|
import ntptime
|
||||||
import uhashlib
|
|
||||||
import ubinascii
|
import ubinascii
|
||||||
import board
|
import uhashlib
|
||||||
import bitbangio as io
|
|
||||||
import adafruit_ssd1306
|
|
||||||
|
|
||||||
|
# https://github.com/pyotp/pyotp example
|
||||||
totp = [("Discord ", 'JBSWY3DPEHPK3PXP'), # https://github.com/pyotp/pyotp exmple
|
totp = [("Discord ", 'JBSWY3DPEHPK3PXP'),
|
||||||
("Gmail ", 'abcdefghijklmnopqrstuvwxyz234567'),
|
("Gmail ", 'abcdefghijklmnopqrstuvwxyz234567'),
|
||||||
("Accounts", 'asfdkwefoaiwejfa323nfjkl')]
|
("Accounts", 'asfdkwefoaiwejfa323nfjkl')]
|
||||||
ssid = 'my_wifi_ssid'
|
ssid = 'my_wifi_ssid'
|
||||||
password = 'my_wifi_password'
|
password = 'my_wifi_password'
|
||||||
|
|
||||||
TEST = False # if you want to print out the tests the hashers
|
TEST = False # if you want to print out the tests the hashers
|
||||||
ALWAYS_ON = False # Set to true if you never want to go to sleep!
|
ALWAYS_ON = False # Set to true if you never want to go to sleep!
|
||||||
ON_SECONDS = 60 # how long to stay on if not in always_on mode
|
ON_SECONDS = 60 # how long to stay on if not in always_on mode
|
||||||
|
|
||||||
i2c = io.I2C(board.SCL, board.SDA)
|
i2c = io.I2C(board.SCL, board.SDA)
|
||||||
oled = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c)
|
oled = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c)
|
||||||
|
|
@ -29,7 +29,7 @@ oled.text('PyTOTP Pal!', 0, 10)
|
||||||
oled.text(' <3 adafruit <3 ', 0, 20)
|
oled.text(' <3 adafruit <3 ', 0, 20)
|
||||||
oled.show()
|
oled.show()
|
||||||
time.sleep(0.25)
|
time.sleep(0.25)
|
||||||
|
|
||||||
EPOCH_DELTA = 946684800 # seconds between year 2000 and year 1970
|
EPOCH_DELTA = 946684800 # seconds between year 2000 and year 1970
|
||||||
SECS_DAY = 86400
|
SECS_DAY = 86400
|
||||||
|
|
||||||
|
|
@ -52,6 +52,7 @@ def HMAC(k, m):
|
||||||
outer_message = KEY_OUTER + SHA1(inner_message).digest()
|
outer_message = KEY_OUTER + SHA1(inner_message).digest()
|
||||||
return SHA1(outer_message)
|
return SHA1(outer_message)
|
||||||
|
|
||||||
|
|
||||||
if TEST:
|
if TEST:
|
||||||
KEY = b'abcd'
|
KEY = b'abcd'
|
||||||
MESSAGE = b'efgh'
|
MESSAGE = b'efgh'
|
||||||
|
|
@ -59,13 +60,16 @@ if TEST:
|
||||||
print("HMAC test: ", ubinascii.hexlify(HMAC(KEY, MESSAGE).digest()))
|
print("HMAC test: ", ubinascii.hexlify(HMAC(KEY, MESSAGE).digest()))
|
||||||
# should be e5dbcf9263188f9fce90df572afeb39b66b27198
|
# should be e5dbcf9263188f9fce90df572afeb39b66b27198
|
||||||
|
|
||||||
|
|
||||||
# Base32 decoder, since base64 lib wouldnt fit
|
# Base32 decoder, since base64 lib wouldnt fit
|
||||||
|
|
||||||
|
|
||||||
def base32_decode(encoded):
|
def base32_decode(encoded):
|
||||||
missing_padding = len(encoded) % 8
|
missing_padding = len(encoded) % 8
|
||||||
if missing_padding != 0:
|
if missing_padding != 0:
|
||||||
encoded += '=' * (8 - missing_padding)
|
encoded += '=' * (8 - missing_padding)
|
||||||
encoded = encoded.upper()
|
encoded = encoded.upper()
|
||||||
chunks = [encoded[i:i+8] for i in range(0, len(encoded), 8)]
|
chunks = [encoded[i:i + 8] for i in range(0, len(encoded), 8)]
|
||||||
|
|
||||||
out = []
|
out = []
|
||||||
for chunk in chunks:
|
for chunk in chunks:
|
||||||
|
|
@ -88,17 +92,21 @@ def base32_decode(encoded):
|
||||||
# great! we have enough to extract a byte
|
# great! we have enough to extract a byte
|
||||||
if bits >= 8:
|
if bits >= 8:
|
||||||
bits -= 8
|
bits -= 8
|
||||||
byte = bitbuff >> bits # grab top 8 bits
|
byte = bitbuff >> bits # grab top 8 bits
|
||||||
bitbuff &= ~(0xFF << bits) # and clear them
|
bitbuff &= ~(0xFF << bits) # and clear them
|
||||||
out.append(byte) # store what we got
|
out.append(byte) # store what we got
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
if TEST:
|
if TEST:
|
||||||
print("===========================================")
|
print("===========================================")
|
||||||
print("Base32 test: ", bytes(base32_decode("IFSGCZTSOVUXIIJB")))
|
print("Base32 test: ", bytes(base32_decode("IFSGCZTSOVUXIIJB")))
|
||||||
# should be "Adafruit!!"
|
# should be "Adafruit!!"
|
||||||
|
|
||||||
|
|
||||||
# Turns an integer into a padded-with-0x0 bytestr
|
# Turns an integer into a padded-with-0x0 bytestr
|
||||||
|
|
||||||
|
|
||||||
def int_to_bytestring(i, padding=8):
|
def int_to_bytestring(i, padding=8):
|
||||||
result = []
|
result = []
|
||||||
while i != 0:
|
while i != 0:
|
||||||
|
|
@ -107,12 +115,18 @@ def int_to_bytestring(i, padding=8):
|
||||||
result = [0] * (padding - len(result)) + result
|
result = [0] * (padding - len(result)) + result
|
||||||
return bytes(result)
|
return bytes(result)
|
||||||
|
|
||||||
|
|
||||||
# HMAC -> OTP generator, pretty much same as
|
# HMAC -> OTP generator, pretty much same as
|
||||||
# https://github.com/pyotp/pyotp/blob/master/src/pyotp/otp.py
|
# https://github.com/pyotp/pyotp/blob/master/src/pyotp/otp.py
|
||||||
def generate_otp(input, secret, digits=6):
|
|
||||||
if input < 0:
|
|
||||||
|
def generate_otp(int_input, secret_key, digits=6):
|
||||||
|
if int_input < 0:
|
||||||
raise ValueError('input must be positive integer')
|
raise ValueError('input must be positive integer')
|
||||||
hmac_hash = bytearray(HMAC(bytes(base32_decode(secret)), int_to_bytestring(input)).digest())
|
hmac_hash = bytearray(
|
||||||
|
HMAC(bytes(base32_decode(secret_key)),
|
||||||
|
int_to_bytestring(int_input)).digest()
|
||||||
|
)
|
||||||
offset = hmac_hash[-1] & 0xf
|
offset = hmac_hash[-1] & 0xf
|
||||||
code = ((hmac_hash[offset] & 0x7f) << 24 |
|
code = ((hmac_hash[offset] & 0x7f) << 24 |
|
||||||
(hmac_hash[offset + 1] & 0xff) << 16 |
|
(hmac_hash[offset + 1] & 0xff) << 16 |
|
||||||
|
|
@ -121,9 +135,10 @@ def generate_otp(input, secret, digits=6):
|
||||||
str_code = str(code % 10 ** digits)
|
str_code = str(code % 10 ** digits)
|
||||||
while len(str_code) < digits:
|
while len(str_code) < digits:
|
||||||
str_code = '0' + str_code
|
str_code = '0' + str_code
|
||||||
|
|
||||||
return str_code
|
return str_code
|
||||||
|
|
||||||
|
|
||||||
print("===========================================")
|
print("===========================================")
|
||||||
|
|
||||||
# Set up networking
|
# Set up networking
|
||||||
|
|
@ -152,7 +167,7 @@ t = None
|
||||||
while not t:
|
while not t:
|
||||||
try:
|
try:
|
||||||
t = ntptime.time()
|
t = ntptime.time()
|
||||||
except:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
|
@ -168,23 +183,23 @@ print("Unix time: ", t)
|
||||||
mono_time = int(time.monotonic())
|
mono_time = int(time.monotonic())
|
||||||
print("Monotonic time", mono_time)
|
print("Monotonic time", mono_time)
|
||||||
|
|
||||||
countdown = ON_SECONDS # how long to stay on if not in always_on mode
|
countdown = ON_SECONDS # how long to stay on if not in always_on mode
|
||||||
while ALWAYS_ON or (countdown > 0):
|
while ALWAYS_ON or (countdown > 0):
|
||||||
# Calculate current time based on NTP + monotonic
|
# Calculate current time based on NTP + monotonic
|
||||||
unix_time = t - mono_time + int(time.monotonic())
|
unix_time = t - mono_time + int(time.monotonic())
|
||||||
print("Unix time: ", unix_time)
|
print("Unix time: ", unix_time)
|
||||||
|
|
||||||
# Clear the screen
|
# Clear the screen
|
||||||
oled.fill(0)
|
oled.fill(0)
|
||||||
y = 0
|
y = 0
|
||||||
# We can do up to 3 per line on the Feather OLED
|
# We can do up to 3 per line on the Feather OLED
|
||||||
for name,secret in totp:
|
for name, secret in totp:
|
||||||
otp = generate_otp(unix_time//30, secret)
|
otp = generate_otp(unix_time // 30, secret)
|
||||||
print(name + " OTP output: ", otp) # serial debugging output
|
print(name + " OTP output: ", otp) # serial debugging output
|
||||||
oled.text(name + ": "+ str(otp), 0, y) # display name & OTP on OLED
|
oled.text(name + ": " + str(otp), 0, y) # display name & OTP on OLED
|
||||||
y += 10 # Go to next line on OLED
|
y += 10 # Go to next line on OLED
|
||||||
# We'll display a little bar that 'counts down' how many seconds you have left
|
# Display a little bar that 'counts down' how many seconds you have left
|
||||||
oled.framebuf.line(0,31, 128 - (unix_time % 30)*4,31, True)
|
oled.framebuf.line(0, 31, 128 - (unix_time % 30) * 4, 31, True)
|
||||||
oled.show()
|
oled.show()
|
||||||
# We'll update every 1/4 second, we can hash very fast so its no biggie!
|
# We'll update every 1/4 second, we can hash very fast so its no biggie!
|
||||||
countdown -= 0.25
|
countdown -= 0.25
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
# CircuitPython AnalogIn Demo
|
# CircuitPython AnalogIn Demo
|
||||||
|
|
||||||
import time
|
import time
|
||||||
from analogio import AnalogIn
|
|
||||||
import board
|
import board
|
||||||
|
from analogio import AnalogIn
|
||||||
|
|
||||||
analog_in = AnalogIn(board.A1)
|
analog_in = AnalogIn(board.A1)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# CircuitPython IO demo - analog output
|
# CircuitPython IO demo - analog output
|
||||||
|
|
||||||
from analogio import AnalogOut
|
|
||||||
import board
|
import board
|
||||||
|
from analogio import AnalogOut
|
||||||
|
|
||||||
analog_out = AnalogOut(board.A0)
|
analog_out = AnalogOut(board.A0)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import board
|
import board
|
||||||
import touchio
|
import touchio
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
# Example does NOT work with Trinket M0!
|
# Example does NOT work with Trinket M0!
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import board
|
import board
|
||||||
import touchio
|
import touchio
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,20 @@
|
||||||
# CircuitPython IO demo #1 - General Purpose I/O
|
# CircuitPython IO demo #1 - General Purpose I/O
|
||||||
|
|
||||||
import time
|
import time
|
||||||
from digitalio import DigitalInOut, Direction, Pull
|
|
||||||
import board
|
import board
|
||||||
|
from digitalio import DigitalInOut, Direction, Pull
|
||||||
|
|
||||||
led = DigitalInOut(board.D13)
|
led = DigitalInOut(board.D13)
|
||||||
led.direction = Direction.OUTPUT
|
led.direction = Direction.OUTPUT
|
||||||
|
|
||||||
switch = DigitalInOut(board.D2) # For Gemma M0, Trinket M0, Metro M0 Express, ItsyBitsy M0 Express
|
# For Gemma M0, Trinket M0, Metro M0 Express, ItsyBitsy M0 Express
|
||||||
|
switch = DigitalInOut(board.D2)
|
||||||
# switch = DigitalInOut(board.D5) # For Feather M0 Express
|
# switch = DigitalInOut(board.D5) # For Feather M0 Express
|
||||||
# switch = DigitalInOut(board.D7) # For Circuit Playground Express
|
# switch = DigitalInOut(board.D7) # For Circuit Playground Express
|
||||||
switch.direction = Direction.INPUT
|
switch.direction = Direction.INPUT
|
||||||
switch.pull = Pull.UP
|
switch.pull = Pull.UP
|
||||||
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
# We could also just do "led.value = not switch.value"!
|
# We could also just do "led.value = not switch.value"!
|
||||||
if switch.value:
|
if switch.value:
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
# CircuitPython demo - Dotstar
|
# CircuitPython demo - Dotstar
|
||||||
|
|
||||||
import time
|
import time
|
||||||
import board
|
|
||||||
import adafruit_dotstar
|
import adafruit_dotstar
|
||||||
|
import board
|
||||||
|
|
||||||
num_pixels = 30
|
num_pixels = 30
|
||||||
pixels = adafruit_dotstar.DotStar(board.A1, board.A2, num_pixels, brightness=0.1, auto_write=False)
|
pixels = adafruit_dotstar.DotStar(
|
||||||
|
board.A1, board.A2, num_pixels, brightness=0.1, auto_write=False)
|
||||||
|
|
||||||
|
|
||||||
def wheel(pos):
|
def wheel(pos):
|
||||||
|
|
@ -103,7 +105,8 @@ MAGENTA = (255, 0, 20)
|
||||||
WHITE = (255, 255, 255)
|
WHITE = (255, 255, 255)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
color_fill(RED, 0.5) # Change this number to change how long it stays on each solid color.
|
# Change this number to change how long it stays on each solid color.
|
||||||
|
color_fill(RED, 0.5)
|
||||||
color_fill(YELLOW, 0.5)
|
color_fill(YELLOW, 0.5)
|
||||||
color_fill(ORANGE, 0.5)
|
color_fill(ORANGE, 0.5)
|
||||||
color_fill(GREEN, 0.5)
|
color_fill(GREEN, 0.5)
|
||||||
|
|
@ -114,12 +117,15 @@ while True:
|
||||||
color_fill(MAGENTA, 0.5)
|
color_fill(MAGENTA, 0.5)
|
||||||
color_fill(WHITE, 0.5)
|
color_fill(WHITE, 0.5)
|
||||||
|
|
||||||
slice_alternating(0.1) # Increase or decrease this to speed up or slow down the animation.
|
# Increase or decrease this to speed up or slow down the animation.
|
||||||
|
slice_alternating(0.1)
|
||||||
|
|
||||||
color_fill(WHITE, 0.5)
|
color_fill(WHITE, 0.5)
|
||||||
|
|
||||||
slice_rainbow(0.1) # Increase or decrease this to speed up or slow down the animation.
|
# Increase or decrease this to speed up or slow down the animation.
|
||||||
|
slice_rainbow(0.1)
|
||||||
|
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
|
|
||||||
rainbow_cycle(0) # Increase this number to slow down the rainbow animation.
|
# Increase this number to slow down the rainbow animation.
|
||||||
|
rainbow_cycle(0)
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
# CircuitPython demo - Keyboard emulator
|
# CircuitPython demo - Keyboard emulator
|
||||||
|
|
||||||
import time
|
import time
|
||||||
import digitalio
|
|
||||||
import board
|
import board
|
||||||
|
import digitalio
|
||||||
from adafruit_hid.keyboard import Keyboard
|
from adafruit_hid.keyboard import Keyboard
|
||||||
from adafruit_hid.keycode import Keycode
|
|
||||||
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
|
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
|
||||||
|
from adafruit_hid.keycode import Keycode
|
||||||
|
|
||||||
# A simple neat keyboard demo in CircuitPython
|
# A simple neat keyboard demo in CircuitPython
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import analogio
|
import analogio
|
||||||
import board
|
import board
|
||||||
import digitalio
|
import digitalio
|
||||||
|
|
@ -21,7 +22,8 @@ def get_voltage(pin):
|
||||||
return (pin.value * 3.3) / 65536
|
return (pin.value * 3.3) / 65536
|
||||||
|
|
||||||
|
|
||||||
def steps(axis): # Maps the potentiometer voltage range to 0-20 in whole numbers
|
def steps(axis):
|
||||||
|
""" Maps the potentiometer voltage range to 0-20 """
|
||||||
return round((axis - pot_min) / step)
|
return round((axis - pot_min) / step)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
# CircuitPython demo - I2C scan
|
# CircuitPython demo - I2C scan
|
||||||
|
|
||||||
|
import time
|
||||||
|
|
||||||
import board
|
import board
|
||||||
import busio
|
import busio
|
||||||
import time
|
|
||||||
|
|
||||||
i2c = busio.I2C(board.SCL, board.SDA)
|
i2c = busio.I2C(board.SCL, board.SDA)
|
||||||
|
|
||||||
|
|
@ -10,5 +11,6 @@ while not i2c.try_lock():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
print("I2C addresses found:", [hex(device_address) for device_address in i2c.scan()])
|
print("I2C addresses found:", [hex(device_address)
|
||||||
|
for device_address in i2c.scan()])
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
# CircuitPython Demo - I2C sensor
|
# CircuitPython Demo - I2C sensor
|
||||||
|
|
||||||
|
import time
|
||||||
|
|
||||||
|
import adafruit_tsl2561
|
||||||
import board
|
import board
|
||||||
import busio
|
import busio
|
||||||
import adafruit_tsl2561
|
|
||||||
import time
|
|
||||||
|
|
||||||
i2c = busio.I2C(board.SCL, board.SDA)
|
i2c = busio.I2C(board.SCL, board.SDA)
|
||||||
|
|
||||||
|
|
@ -11,7 +12,8 @@ i2c = busio.I2C(board.SCL, board.SDA)
|
||||||
while not i2c.try_lock():
|
while not i2c.try_lock():
|
||||||
pass
|
pass
|
||||||
# Print the addresses found once
|
# Print the addresses found once
|
||||||
print("I2C addresses found:", [hex(device_address) for device_address in i2c.scan()])
|
print("I2C addresses found:", [hex(device_address)
|
||||||
|
for device_address in i2c.scan()])
|
||||||
|
|
||||||
# Unlock I2C now that we're done scanning.
|
# Unlock I2C now that we're done scanning.
|
||||||
i2c.unlock()
|
i2c.unlock()
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
import time
|
import time
|
||||||
import board
|
|
||||||
import neopixel
|
|
||||||
import adafruit_dotstar
|
import adafruit_dotstar
|
||||||
|
import board
|
||||||
|
|
||||||
# For Trinket M0, Gemma M0, and ItsyBitsy M0 Express
|
# For Trinket M0, Gemma M0, and ItsyBitsy M0 Express
|
||||||
led = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1)
|
led = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1)
|
||||||
# For Feather M0 Express, Metro M0 Express, Metro M4 Express, and Circuit Playground Express
|
# For Feather M0 Express, Metro M0 Express, Metro M4 Express, and Circuit
|
||||||
|
# Playground Express
|
||||||
# led = neopixel.NeoPixel(board.NEOPIXEL, 1)
|
# led = neopixel.NeoPixel(board.NEOPIXEL, 1)
|
||||||
|
|
||||||
led.brightness = 0.3
|
led.brightness = 0.3
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
import time
|
import time
|
||||||
import board
|
|
||||||
import neopixel
|
|
||||||
import adafruit_dotstar
|
import adafruit_dotstar
|
||||||
|
import board
|
||||||
|
|
||||||
# For Trinket M0, Gemma M0, and ItsyBitsy M0 Express
|
# For Trinket M0, Gemma M0, and ItsyBitsy M0 Express
|
||||||
led = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1)
|
led = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1)
|
||||||
# For Feather M0 Express, Metro M0 Express, Metro M4 Express and Circuit Playground Express
|
|
||||||
|
|
||||||
|
# For Feather M0 Express, Metro M0 Express, Metro M4 Express and Circuit
|
||||||
|
# Playground Express
|
||||||
# led = neopixel.NeoPixel(board.NEOPIXEL, 1)
|
# led = neopixel.NeoPixel(board.NEOPIXEL, 1)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -15,12 +18,12 @@ def wheel(pos):
|
||||||
if pos < 0 or pos > 255:
|
if pos < 0 or pos > 255:
|
||||||
return 0, 0, 0
|
return 0, 0, 0
|
||||||
if pos < 85:
|
if pos < 85:
|
||||||
return int(255 - pos*3), int(pos*3), 0
|
return int(255 - pos * 3), int(pos * 3), 0
|
||||||
if pos < 170:
|
if pos < 170:
|
||||||
pos -= 85
|
pos -= 85
|
||||||
return 0, int(255 - pos*3), int(pos*3)
|
return 0, int(255 - pos * 3), int(pos * 3)
|
||||||
pos -= 170
|
pos -= 170
|
||||||
return int(pos * 3), 0, int(255 - (pos*3))
|
return int(pos * 3), 0, int(255 - (pos * 3))
|
||||||
|
|
||||||
|
|
||||||
led.brightness = 0.3
|
led.brightness = 0.3
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
|
import time
|
||||||
|
|
||||||
import board
|
import board
|
||||||
import digitalio
|
import digitalio
|
||||||
import microcontroller
|
import microcontroller
|
||||||
import time
|
|
||||||
|
|
||||||
led = digitalio.DigitalInOut(board.D13)
|
led = digitalio.DigitalInOut(board.D13)
|
||||||
led.switch_to_output()
|
led.switch_to_output()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import digitalio
|
|
||||||
import board
|
import board
|
||||||
|
import digitalio
|
||||||
import storage
|
import storage
|
||||||
|
|
||||||
# For Gemma M0, Trinket M0, Metro M0 Express, ItsyBitsy M0 Express
|
# For Gemma M0, Trinket M0, Metro M0 Express, ItsyBitsy M0 Express
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,15 @@
|
||||||
# CircuitPython demo - NeoPixel
|
# CircuitPython demo - NeoPixel
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import board
|
import board
|
||||||
import neopixel
|
import neopixel
|
||||||
|
|
||||||
pixel_pin = board.A1
|
pixel_pin = board.A1
|
||||||
num_pixels = 8
|
num_pixels = 8
|
||||||
|
|
||||||
pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=0.3, auto_write=False)
|
pixels = neopixel.NeoPixel(pixel_pin, num_pixels,
|
||||||
|
brightness=0.3, auto_write=False)
|
||||||
|
|
||||||
|
|
||||||
def wheel(pos):
|
def wheel(pos):
|
||||||
|
|
@ -51,7 +53,8 @@ PURPLE = (180, 0, 255)
|
||||||
while True:
|
while True:
|
||||||
pixels.fill(RED)
|
pixels.fill(RED)
|
||||||
pixels.show()
|
pixels.show()
|
||||||
time.sleep(1) # Increase or decrease to change the speed of the solid color change.
|
# Increase or decrease to change the speed of the solid color change.
|
||||||
|
time.sleep(1)
|
||||||
pixels.fill(GREEN)
|
pixels.fill(GREEN)
|
||||||
pixels.show()
|
pixels.show()
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
# CircuitPython demo - NeoPixel RGBW
|
# CircuitPython demo - NeoPixel RGBW
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import board
|
import board
|
||||||
import neopixel
|
import neopixel
|
||||||
|
|
||||||
|
|
@ -8,7 +9,8 @@ pixel_pin = board.A1
|
||||||
num_pixels = 8
|
num_pixels = 8
|
||||||
|
|
||||||
pixels = neopixel.NeoPixel(pixel_pin, num_pixels,
|
pixels = neopixel.NeoPixel(pixel_pin, num_pixels,
|
||||||
brightness=0.3, auto_write=False, pixel_order=(1, 0, 2, 3))
|
brightness=0.3, auto_write=False,
|
||||||
|
pixel_order=(1, 0, 2, 3))
|
||||||
|
|
||||||
|
|
||||||
def wheel(pos):
|
def wheel(pos):
|
||||||
|
|
@ -52,7 +54,8 @@ PURPLE = (180, 0, 255, 0)
|
||||||
while True:
|
while True:
|
||||||
pixels.fill(RED)
|
pixels.fill(RED)
|
||||||
pixels.show()
|
pixels.show()
|
||||||
time.sleep(1) # Increase or decrease to change the speed of the solid color change.
|
# Increase or decrease to change the speed of the solid color change.
|
||||||
|
time.sleep(1)
|
||||||
pixels.fill(GREEN)
|
pixels.fill(GREEN)
|
||||||
pixels.show()
|
pixels.show()
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import time
|
import time
|
||||||
import pulseio
|
|
||||||
import board
|
import board
|
||||||
|
import pulseio
|
||||||
|
|
||||||
led = pulseio.PWMOut(board.D13, frequency=5000, duty_cycle=0)
|
led = pulseio.PWMOut(board.D13, frequency=5000, duty_cycle=0)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,21 @@
|
||||||
import time
|
import time
|
||||||
import pulseio
|
|
||||||
import board
|
import board
|
||||||
|
import pulseio
|
||||||
|
|
||||||
# For the M0 boards:
|
# For the M0 boards:
|
||||||
piezo = pulseio.PWMOut(board.A2, duty_cycle=0, frequency=440, variable_frequency=True)
|
piezo = pulseio.PWMOut(board.A2, duty_cycle=0,
|
||||||
|
frequency=440, variable_frequency=True)
|
||||||
# For Metro M4 Express:
|
# For Metro M4 Express:
|
||||||
# piezo = pulseio.PWMOut(board.A1, duty_cycle=0, frequency=440, variable_frequency=True)
|
# piezo = pulseio.PWMOut(
|
||||||
|
# board.A1, duty_cycle=0, frequency=440, variable_frequency=True
|
||||||
|
# )
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
for f in (262, 294, 330, 349, 392, 440, 494, 523):
|
for f in (262, 294, 330, 349, 392, 440, 494, 523):
|
||||||
piezo.frequency = f
|
piezo.frequency = f
|
||||||
piezo.duty_cycle = 65536 // 2 # On 50%
|
piezo.duty_cycle = 65536 // 2 # On 50%
|
||||||
time.sleep(0.25) # On for 1/4 second
|
time.sleep(0.25) # On for 1/4 second
|
||||||
piezo.duty_cycle = 0 # Off
|
piezo.duty_cycle = 0 # Off
|
||||||
time.sleep(0.05) # Pause between notes
|
time.sleep(0.05) # Pause between notes
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import board
|
import board
|
||||||
import simpleio
|
import simpleio
|
||||||
|
|
||||||
|
|
@ -8,5 +9,5 @@ while True:
|
||||||
simpleio.tone(board.A2, f, 0.25) # on for 1/4 second
|
simpleio.tone(board.A2, f, 0.25) # on for 1/4 second
|
||||||
# For the Metro M4 Express:
|
# For the Metro M4 Express:
|
||||||
# simpleio.tone(board.A1, f, 0.25) # on for 1/4 second
|
# simpleio.tone(board.A1, f, 0.25) # on for 1/4 second
|
||||||
time.sleep(0.05) # pause between notes
|
time.sleep(0.05) # pause between notes
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import time
|
import time
|
||||||
import simpleio
|
|
||||||
import board
|
import board
|
||||||
|
import simpleio
|
||||||
|
|
||||||
# For the M0 boards:
|
# For the M0 boards:
|
||||||
servo = simpleio.Servo(board.A2)
|
servo = simpleio.Servo(board.A2)
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
# CircuitPython Demo - USB/Serial echo
|
# CircuitPython Demo - USB/Serial echo
|
||||||
|
|
||||||
import digitalio
|
|
||||||
import board
|
import board
|
||||||
import busio
|
import busio
|
||||||
|
import digitalio
|
||||||
|
|
||||||
led = digitalio.DigitalInOut(board.D13)
|
led = digitalio.DigitalInOut(board.D13)
|
||||||
led.direction = digitalio.Direction.OUTPUT
|
led.direction = digitalio.Direction.OUTPUT
|
||||||
|
|
@ -16,7 +16,8 @@ while True:
|
||||||
if data is not None:
|
if data is not None:
|
||||||
led.value = True
|
led.value = True
|
||||||
|
|
||||||
data_string = ''.join([chr(b) for b in data]) # convert bytearray to string
|
# convert bytearray to string
|
||||||
|
data_string = ''.join([chr(b) for b in data])
|
||||||
print(data_string, end="")
|
print(data_string, end="")
|
||||||
|
|
||||||
led.value = False
|
led.value = False
|
||||||
|
|
|
||||||
|
|
@ -9,5 +9,5 @@ for pin_name in dir(board):
|
||||||
print("PWM on:", pin_name) # Prints the valid, PWM-capable pins!
|
print("PWM on:", pin_name) # Prints the valid, PWM-capable pins!
|
||||||
except ValueError: # This is the error returned when the pin is invalid.
|
except ValueError: # This is the error returned when the pin is invalid.
|
||||||
print("No PWM on:", pin_name) # Prints the invalid pins.
|
print("No PWM on:", pin_name) # Prints the invalid pins.
|
||||||
except RuntimeError: # This is the error returned when there is a timer conflict.
|
except RuntimeError: # Timer conflict error.
|
||||||
print("Timers in use:", pin_name) # Prints the timer conflict pins.
|
print("Timers in use:", pin_name) # Prints the timer conflict pins.
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import board
|
||||||
import busio
|
import busio
|
||||||
|
|
||||||
|
|
||||||
def is_hardware_SPI(clock_pin, data_pin):
|
def is_hardware_spi(clock_pin, data_pin):
|
||||||
try:
|
try:
|
||||||
p = busio.SPI(clock_pin, data_pin)
|
p = busio.SPI(clock_pin, data_pin)
|
||||||
p.deinit()
|
p.deinit()
|
||||||
|
|
@ -11,7 +11,8 @@ def is_hardware_SPI(clock_pin, data_pin):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
if is_hardware_SPI(board.A1, board.A2): # Provide the two pins you intend to use.
|
# Provide the two pins you intend to use.
|
||||||
|
if is_hardware_spi(board.A1, board.A2):
|
||||||
print("This pin combination is hardware SPI!")
|
print("This pin combination is hardware SPI!")
|
||||||
else:
|
else:
|
||||||
print("This pin combination isn't hardware SPI.")
|
print("This pin combination isn't hardware SPI.")
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import board
|
||||||
import busio
|
import busio
|
||||||
|
|
||||||
|
|
||||||
def is_hardware_UART(tx, rx):
|
def is_hardware_uart(tx, rx):
|
||||||
try:
|
try:
|
||||||
p = busio.UART(tx, rx)
|
p = busio.UART(tx, rx)
|
||||||
p.deinit()
|
p.deinit()
|
||||||
|
|
@ -32,7 +32,7 @@ for tx_pin in get_unique_pins():
|
||||||
if rx_pin is tx_pin:
|
if rx_pin is tx_pin:
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
if is_hardware_UART(tx_pin, rx_pin):
|
if is_hardware_uart(tx_pin, rx_pin):
|
||||||
print("RX pin:", rx_pin, "\t TX pin:", tx_pin)
|
print("RX pin:", rx_pin, "\t TX pin:", tx_pin)
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1 @@
|
||||||
print('Hello, World!')
|
print('Hello, World!')
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
|
import sys
|
||||||
|
|
||||||
import adafruit_sdcard
|
import adafruit_sdcard
|
||||||
|
import board
|
||||||
import busio
|
import busio
|
||||||
import digitalio
|
import digitalio
|
||||||
import board
|
|
||||||
import storage
|
import storage
|
||||||
import sys
|
|
||||||
# Connect to the card and mount the filesystem.
|
# Connect to the card and mount the filesystem.
|
||||||
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
|
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
|
||||||
cs = digitalio.DigitalInOut(board.SD_CS)
|
cs = digitalio.DigitalInOut(board.SD_CS)
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
|
import sys
|
||||||
|
|
||||||
import adafruit_sdcard
|
import adafruit_sdcard
|
||||||
|
import board
|
||||||
import busio
|
import busio
|
||||||
import digitalio
|
import digitalio
|
||||||
import board
|
|
||||||
import storage
|
import storage
|
||||||
import sys
|
|
||||||
# Connect to the card and mount the filesystem.
|
# Connect to the card and mount the filesystem.
|
||||||
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
|
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
|
||||||
cs = digitalio.DigitalInOut(board.SD_CS)
|
cs = digitalio.DigitalInOut(board.SD_CS)
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
# Dotstar painter! Can handle up to ~2300 pixel size image (e.g. 36 x 64)
|
# Dotstar painter! Can handle up to ~2300 pixel size image (e.g. 36 x 64)
|
||||||
|
|
||||||
import board
|
|
||||||
import digitalio
|
|
||||||
import time
|
|
||||||
import gc
|
import gc
|
||||||
|
import time
|
||||||
|
|
||||||
|
import board
|
||||||
import busio
|
import busio
|
||||||
|
import digitalio
|
||||||
|
|
||||||
FILENAME = "blinka.bmp"
|
FILENAME = "blinka.bmp"
|
||||||
IMAGE_DELAY = 0.2
|
IMAGE_DELAY = 0.2
|
||||||
|
|
@ -23,6 +24,7 @@ databuf = bytearray(0)
|
||||||
led = digitalio.DigitalInOut(board.D13)
|
led = digitalio.DigitalInOut(board.D13)
|
||||||
led.switch_to_output()
|
led.switch_to_output()
|
||||||
|
|
||||||
|
|
||||||
def read_le(s):
|
def read_le(s):
|
||||||
# as of this writting, int.from_bytes does not have LE support, DIY!
|
# as of this writting, int.from_bytes does not have LE support, DIY!
|
||||||
result = 0
|
result = 0
|
||||||
|
|
@ -32,32 +34,33 @@ def read_le(s):
|
||||||
shift += 8
|
shift += 8
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
class BMPError(Exception):
|
class BMPError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open("/"+FILENAME, "rb") as f:
|
with open("/" + FILENAME, "rb") as f:
|
||||||
print("File opened")
|
print("File opened")
|
||||||
if f.read(2) != b'BM': # check signature
|
if f.read(2) != b'BM': # check signature
|
||||||
raise BMPError("Not BitMap file")
|
raise BMPError("Not BitMap file")
|
||||||
|
|
||||||
bmpFileSize = read_le(f.read(4))
|
bmpFileSize = read_le(f.read(4))
|
||||||
f.read(4) # Read & ignore creator bytes
|
f.read(4) # Read & ignore creator bytes
|
||||||
|
|
||||||
bmpImageoffset = read_le(f.read(4)) # Start of image data
|
bmpImageoffset = read_le(f.read(4)) # Start of image data
|
||||||
headerSize = read_le(f.read(4))
|
headerSize = read_le(f.read(4))
|
||||||
bmpWidth = read_le(f.read(4))
|
bmpWidth = read_le(f.read(4))
|
||||||
bmpHeight = read_le(f.read(4))
|
bmpHeight = read_le(f.read(4))
|
||||||
flip = True
|
flip = True
|
||||||
|
|
||||||
print("Size: %d\nImage offset: %d\nHeader size: %d" %
|
print("Size: %d\nImage offset: %d\nHeader size: %d" %
|
||||||
(bmpFileSize, bmpImageoffset, headerSize))
|
(bmpFileSize, bmpImageoffset, headerSize))
|
||||||
print("Width: %d\nHeight: %d" % (bmpWidth, bmpHeight))
|
print("Width: %d\nHeight: %d" % (bmpWidth, bmpHeight))
|
||||||
|
|
||||||
if read_le(f.read(2)) != 1:
|
if read_le(f.read(2)) != 1:
|
||||||
raise BMPError("Not singleplane")
|
raise BMPError("Not singleplane")
|
||||||
bmpDepth = read_le(f.read(2)) # bits per pixel
|
bmpDepth = read_le(f.read(2)) # bits per pixel
|
||||||
print("Bit depth: %d" % (bmpDepth))
|
print("Bit depth: %d" % (bmpDepth))
|
||||||
if bmpDepth != 24:
|
if bmpDepth != 24:
|
||||||
raise BMPError("Not 24-bit")
|
raise BMPError("Not 24-bit")
|
||||||
|
|
@ -66,36 +69,38 @@ try:
|
||||||
|
|
||||||
print("Image OK!")
|
print("Image OK!")
|
||||||
|
|
||||||
rowSize = (bmpWidth * 3 + 3) & ~3 # 32-bit line boundary
|
rowSize = (bmpWidth * 3 + 3) & ~3 # 32-bit line boundary
|
||||||
|
|
||||||
databuf = bytearray(bmpWidth * bmpHeight * 4) # its huge! but its also fast :)
|
# its huge! but its also fast :)
|
||||||
|
databuf = bytearray(bmpWidth * bmpHeight * 4)
|
||||||
|
|
||||||
for row in range(bmpHeight): # For each scanline...
|
for row in range(bmpHeight): # For each scanline...
|
||||||
if(flip): # Bitmap is stored bottom-to-top order (normal BMP)
|
if flip: # Bitmap is stored bottom-to-top order (normal BMP)
|
||||||
pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize
|
pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize
|
||||||
else: # Bitmap is stored top-to-bottom
|
else: # Bitmap is stored top-to-bottom
|
||||||
pos = bmpImageoffset + row * rowSize;
|
pos = bmpImageoffset + row * rowSize
|
||||||
|
|
||||||
#print ("seek to %d" % pos)
|
# print ("seek to %d" % pos)
|
||||||
f.seek(pos)
|
f.seek(pos)
|
||||||
for col in range(bmpWidth):
|
for col in range(bmpWidth):
|
||||||
b,g,r = bytearray(f.read(3)) # BMP files store RGB in BGR
|
b, g, r = bytearray(f.read(3)) # BMP files store RGB in BGR
|
||||||
# front load brightness, gamma and reordering here!
|
# front load brightness, gamma and reordering here!
|
||||||
order = [b, g, r]
|
order = [b, g, r]
|
||||||
idx = (col * bmpHeight + (bmpHeight - row - 1))*4
|
idx = (col * bmpHeight + (bmpHeight - row - 1)) * 4
|
||||||
databuf[idx] = 0xFF # first byte is 'brightness'
|
databuf[idx] = 0xFF # first byte is 'brightness'
|
||||||
idx += 1
|
idx += 1
|
||||||
for color in order:
|
for color in order:
|
||||||
databuf[idx] = int(pow((color * BRIGHTNESS) / 255, 2.7) * 255 + 0.5)
|
databuf[idx] = int(
|
||||||
|
pow((color * BRIGHTNESS) / 255, 2.7) * 255 + 0.5)
|
||||||
idx += 1
|
idx += 1
|
||||||
|
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
if e.args[0] == 28:
|
if e.args[0] == 28:
|
||||||
halt("OS Error 28", 0.25)
|
raise OSError("OS Error 28 0.25")
|
||||||
else:
|
else:
|
||||||
halt("OS Error ", 0.5)
|
raise OSError("OS Error 0.5")
|
||||||
except BMPError as e:
|
except BMPError as e:
|
||||||
print("Failed to parse BMP: "+e.args[0])
|
print("Failed to parse BMP: " + e.args[0])
|
||||||
|
|
||||||
gc.collect()
|
gc.collect()
|
||||||
print(gc.mem_free())
|
print(gc.mem_free())
|
||||||
|
|
@ -105,13 +110,13 @@ while True:
|
||||||
index = 0
|
index = 0
|
||||||
|
|
||||||
for col in range(bmpWidth):
|
for col in range(bmpWidth):
|
||||||
row = databuf[index:index+bmpHeight*4]
|
row = databuf[index:index + bmpHeight * 4]
|
||||||
dotstar.write(bytearray([0x00, 0x00, 0x00, 0x00] ))
|
dotstar.write(bytearray([0x00, 0x00, 0x00, 0x00]))
|
||||||
dotstar.write(row)
|
dotstar.write(row)
|
||||||
dotstar.write(bytearray([0x00, 0x00, 0x00, 0x00]))
|
dotstar.write(bytearray([0x00, 0x00, 0x00, 0x00]))
|
||||||
index += bmpHeight * 4
|
index += bmpHeight * 4
|
||||||
time.sleep(PIXEL_DELAY)
|
time.sleep(PIXEL_DELAY)
|
||||||
|
|
||||||
# clear it out
|
# clear it out
|
||||||
dotstar.write(bytearray([0x00, 0x00, 0x00, 0x00]))
|
dotstar.write(bytearray([0x00, 0x00, 0x00, 0x00]))
|
||||||
for r in range(bmpHeight * 5):
|
for r in range(bmpHeight * 5):
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
# CircuitPython AnalogIn Demo
|
# CircuitPython AnalogIn Demo
|
||||||
|
|
||||||
import time
|
import time
|
||||||
from analogio import AnalogIn
|
|
||||||
import board
|
import board
|
||||||
|
from analogio import AnalogIn
|
||||||
|
|
||||||
analog_in = AnalogIn(board.A1)
|
analog_in = AnalogIn(board.A1)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# CircuitPython IO demo - analog output
|
# CircuitPython IO demo - analog output
|
||||||
|
|
||||||
from analogio import AnalogOut
|
|
||||||
import board
|
import board
|
||||||
|
from analogio import AnalogOut
|
||||||
|
|
||||||
analog_out = AnalogOut(board.A0)
|
analog_out = AnalogOut(board.A0)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import board
|
import board
|
||||||
import touchio
|
import touchio
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
# Example does NOT work with Trinket M0!
|
# Example does NOT work with Trinket M0!
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import board
|
import board
|
||||||
import touchio
|
import touchio
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,20 @@
|
||||||
# CircuitPython IO demo #1 - General Purpose I/O
|
# CircuitPython IO demo #1 - General Purpose I/O
|
||||||
|
|
||||||
import time
|
import time
|
||||||
from digitalio import DigitalInOut, Direction, Pull
|
|
||||||
import board
|
import board
|
||||||
|
from digitalio import DigitalInOut, Direction, Pull
|
||||||
|
|
||||||
led = DigitalInOut(board.D13)
|
led = DigitalInOut(board.D13)
|
||||||
led.direction = Direction.OUTPUT
|
led.direction = Direction.OUTPUT
|
||||||
|
|
||||||
switch = DigitalInOut(board.D2) # For Gemma M0, Trinket M0, Metro M0 Express, ItsyBitsy M0 Express
|
# For Gemma M0, Trinket M0, Metro M0 Express, ItsyBitsy M0 Express
|
||||||
|
switch = DigitalInOut(board.D2)
|
||||||
# switch = DigitalInOut(board.D5) # For Feather M0 Express
|
# switch = DigitalInOut(board.D5) # For Feather M0 Express
|
||||||
# switch = DigitalInOut(board.D7) # For Circuit Playground Express
|
# switch = DigitalInOut(board.D7) # For Circuit Playground Express
|
||||||
switch.direction = Direction.INPUT
|
switch.direction = Direction.INPUT
|
||||||
switch.pull = Pull.UP
|
switch.pull = Pull.UP
|
||||||
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
# We could also just do "led.value = not switch.value"!
|
# We could also just do "led.value = not switch.value"!
|
||||||
if switch.value:
|
if switch.value:
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
# CircuitPython demo - Dotstar
|
# CircuitPython demo - Dotstar
|
||||||
|
|
||||||
import time
|
import time
|
||||||
import board
|
|
||||||
import adafruit_dotstar
|
import adafruit_dotstar
|
||||||
|
import board
|
||||||
|
|
||||||
num_pixels = 30
|
num_pixels = 30
|
||||||
pixels = adafruit_dotstar.DotStar(board.A1, board.A2, num_pixels, brightness=0.1, auto_write=False)
|
pixels = adafruit_dotstar.DotStar(
|
||||||
|
board.A1, board.A2, num_pixels, brightness=0.1, auto_write=False)
|
||||||
|
|
||||||
|
|
||||||
def wheel(pos):
|
def wheel(pos):
|
||||||
|
|
@ -103,7 +105,8 @@ MAGENTA = (255, 0, 20)
|
||||||
WHITE = (255, 255, 255)
|
WHITE = (255, 255, 255)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
color_fill(RED, 0.5) # Change this number to change how long it stays on each solid color.
|
# Change this number to change how long it stays on each solid color.
|
||||||
|
color_fill(RED, 0.5)
|
||||||
color_fill(YELLOW, 0.5)
|
color_fill(YELLOW, 0.5)
|
||||||
color_fill(ORANGE, 0.5)
|
color_fill(ORANGE, 0.5)
|
||||||
color_fill(GREEN, 0.5)
|
color_fill(GREEN, 0.5)
|
||||||
|
|
@ -114,12 +117,15 @@ while True:
|
||||||
color_fill(MAGENTA, 0.5)
|
color_fill(MAGENTA, 0.5)
|
||||||
color_fill(WHITE, 0.5)
|
color_fill(WHITE, 0.5)
|
||||||
|
|
||||||
slice_alternating(0.1) # Increase or decrease this to speed up or slow down the animation.
|
# Increase or decrease this to speed up or slow down the animation.
|
||||||
|
slice_alternating(0.1)
|
||||||
|
|
||||||
color_fill(WHITE, 0.5)
|
color_fill(WHITE, 0.5)
|
||||||
|
|
||||||
slice_rainbow(0.1) # Increase or decrease this to speed up or slow down the animation.
|
# Increase or decrease this to speed up or slow down the animation.
|
||||||
|
slice_rainbow(0.1)
|
||||||
|
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
|
|
||||||
rainbow_cycle(0) # Increase this number to slow down the rainbow animation.
|
# Increase this number to slow down the rainbow animation.
|
||||||
|
rainbow_cycle(0)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import time
|
import time
|
||||||
import board
|
|
||||||
import neopixel
|
|
||||||
import adafruit_dotstar
|
import adafruit_dotstar
|
||||||
|
import board
|
||||||
|
|
||||||
# For Trinket M0, Gemma M0, and ItsyBitsy M0 Express
|
# For Trinket M0, Gemma M0, and ItsyBitsy M0 Express
|
||||||
led = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1)
|
led = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1)
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
import time
|
import time
|
||||||
import board
|
|
||||||
import neopixel
|
|
||||||
import adafruit_dotstar
|
import adafruit_dotstar
|
||||||
|
import board
|
||||||
|
|
||||||
# For Trinket M0, Gemma M0, and ItsyBitsy M0 Express
|
# For Trinket M0, Gemma M0, and ItsyBitsy M0 Express
|
||||||
led = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1)
|
led = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1)
|
||||||
|
|
||||||
|
|
||||||
# For Feather M0 Express, Metro M0 Express, and Circuit Playground Express
|
# For Feather M0 Express, Metro M0 Express, and Circuit Playground Express
|
||||||
# led = neopixel.NeoPixel(board.NEOPIXEL, 1)
|
# led = neopixel.NeoPixel(board.NEOPIXEL, 1)
|
||||||
|
|
||||||
|
|
@ -15,12 +17,12 @@ def wheel(pos):
|
||||||
if pos < 0 or pos > 255:
|
if pos < 0 or pos > 255:
|
||||||
return 0, 0, 0
|
return 0, 0, 0
|
||||||
if pos < 85:
|
if pos < 85:
|
||||||
return int(255 - pos*3), int(pos*3), 0
|
return int(255 - pos * 3), int(pos * 3), 0
|
||||||
if pos < 170:
|
if pos < 170:
|
||||||
pos -= 85
|
pos -= 85
|
||||||
return 0, int(255 - pos*3), int(pos*3)
|
return 0, int(255 - pos * 3), int(pos * 3)
|
||||||
pos -= 170
|
pos -= 170
|
||||||
return int(pos * 3), 0, int(255 - (pos*3))
|
return int(pos * 3), 0, int(255 - (pos * 3))
|
||||||
|
|
||||||
|
|
||||||
led.brightness = 0.3
|
led.brightness = 0.3
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,15 @@
|
||||||
# CircuitPython demo - NeoPixel
|
# CircuitPython demo - NeoPixel
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import board
|
import board
|
||||||
import neopixel
|
import neopixel
|
||||||
|
|
||||||
pixel_pin = board.A1
|
pixel_pin = board.A1
|
||||||
num_pixels = 8
|
num_pixels = 8
|
||||||
|
|
||||||
pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=0.3, auto_write=False)
|
pixels = neopixel.NeoPixel(pixel_pin, num_pixels,
|
||||||
|
brightness=0.3, auto_write=False)
|
||||||
|
|
||||||
|
|
||||||
def wheel(pos):
|
def wheel(pos):
|
||||||
|
|
@ -51,7 +53,8 @@ PURPLE = (180, 0, 255)
|
||||||
while True:
|
while True:
|
||||||
pixels.fill(RED)
|
pixels.fill(RED)
|
||||||
pixels.show()
|
pixels.show()
|
||||||
time.sleep(1) # Increase or decrease to change the speed of the solid color change.
|
# Increase or decrease to change the speed of the solid color change.
|
||||||
|
time.sleep(1)
|
||||||
pixels.fill(GREEN)
|
pixels.fill(GREEN)
|
||||||
pixels.show()
|
pixels.show()
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
# CircuitPython demo - NeoPixel RGBW
|
# CircuitPython demo - NeoPixel RGBW
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import board
|
import board
|
||||||
import neopixel
|
import neopixel
|
||||||
|
|
||||||
|
|
@ -8,7 +9,8 @@ pixel_pin = board.A1
|
||||||
num_pixels = 8
|
num_pixels = 8
|
||||||
|
|
||||||
pixels = neopixel.NeoPixel(pixel_pin, num_pixels,
|
pixels = neopixel.NeoPixel(pixel_pin, num_pixels,
|
||||||
brightness=0.3, auto_write=False, pixel_order=(1, 0, 2, 3))
|
brightness=0.3, auto_write=False,
|
||||||
|
pixel_order=(1, 0, 2, 3))
|
||||||
|
|
||||||
|
|
||||||
def wheel(pos):
|
def wheel(pos):
|
||||||
|
|
@ -52,7 +54,8 @@ PURPLE = (180, 0, 255, 0)
|
||||||
while True:
|
while True:
|
||||||
pixels.fill(RED)
|
pixels.fill(RED)
|
||||||
pixels.show()
|
pixels.show()
|
||||||
time.sleep(1) # Increase or decrease to change the speed of the solid color change.
|
# Increase or decrease to change the speed of the solid color change.
|
||||||
|
time.sleep(1)
|
||||||
pixels.fill(GREEN)
|
pixels.fill(GREEN)
|
||||||
pixels.show()
|
pixels.show()
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import time
|
import time
|
||||||
import pulseio
|
|
||||||
import board
|
import board
|
||||||
|
import pulseio
|
||||||
|
|
||||||
led = pulseio.PWMOut(board.D13, frequency=5000, duty_cycle=0)
|
led = pulseio.PWMOut(board.D13, frequency=5000, duty_cycle=0)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,16 @@
|
||||||
import time
|
import time
|
||||||
import pulseio
|
|
||||||
import board
|
|
||||||
|
|
||||||
piezo = pulseio.PWMOut(board.A2, duty_cycle=0, frequency=440, variable_frequency=True)
|
import board
|
||||||
|
import pulseio
|
||||||
|
|
||||||
|
piezo = pulseio.PWMOut(board.A2, duty_cycle=0,
|
||||||
|
frequency=440, variable_frequency=True)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
for f in (262, 294, 330, 349, 392, 440, 494, 523):
|
for f in (262, 294, 330, 349, 392, 440, 494, 523):
|
||||||
piezo.frequency = f
|
piezo.frequency = f
|
||||||
piezo.duty_cycle = 65536 // 2 # On 50%
|
piezo.duty_cycle = 65536 // 2 # On 50%
|
||||||
time.sleep(0.25) # On for 1/4 second
|
time.sleep(0.25) # On for 1/4 second
|
||||||
piezo.duty_cycle = 0 # Off
|
piezo.duty_cycle = 0 # Off
|
||||||
time.sleep(0.05) # Pause between notes
|
time.sleep(0.05) # Pause between notes
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import board
|
import board
|
||||||
import simpleio
|
import simpleio
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
for f in (262, 294, 330, 349, 392, 440, 494, 523):
|
for f in (262, 294, 330, 349, 392, 440, 494, 523):
|
||||||
simpleio.tone(board.A2, f, 0.25) # on for 1/4 second
|
simpleio.tone(board.A2, f, 0.25) # on for 1/4 second
|
||||||
time.sleep(0.05) # pause between notes
|
time.sleep(0.05) # pause between notes
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import time
|
import time
|
||||||
import simpleio
|
|
||||||
import board
|
import board
|
||||||
|
import simpleio
|
||||||
|
|
||||||
servo = simpleio.Servo(board.A2)
|
servo = simpleio.Servo(board.A2)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
# CircuitPython Demo - USB/Serial echo
|
# CircuitPython Demo - USB/Serial echo
|
||||||
|
|
||||||
import digitalio
|
|
||||||
import board
|
import board
|
||||||
import busio
|
import busio
|
||||||
|
import digitalio
|
||||||
|
|
||||||
led = digitalio.DigitalInOut(board.D13)
|
led = digitalio.DigitalInOut(board.D13)
|
||||||
led.direction = digitalio.Direction.OUTPUT
|
led.direction = digitalio.Direction.OUTPUT
|
||||||
|
|
@ -16,7 +16,8 @@ while True:
|
||||||
if data is not None:
|
if data is not None:
|
||||||
led.value = True
|
led.value = True
|
||||||
|
|
||||||
data_string = ''.join([chr(b) for b in data]) # convert bytearray to string
|
# convert bytearray to string
|
||||||
|
data_string = ''.join([chr(b) for b in data])
|
||||||
print(data_string, end="")
|
print(data_string, end="")
|
||||||
|
|
||||||
led.value = False
|
led.value = False
|
||||||
|
|
|
||||||
|
|
@ -9,5 +9,5 @@ for pin_name in dir(board):
|
||||||
print("PWM on:", pin_name) # Prints the valid, PWM-capable pins!
|
print("PWM on:", pin_name) # Prints the valid, PWM-capable pins!
|
||||||
except ValueError: # This is the error returned when the pin is invalid.
|
except ValueError: # This is the error returned when the pin is invalid.
|
||||||
print("No PWM on:", pin_name) # Prints the invalid pins.
|
print("No PWM on:", pin_name) # Prints the invalid pins.
|
||||||
except RuntimeError: # This is the error returned when there is a timer conflict.
|
except RuntimeError: # Timer conflict error.
|
||||||
print("Timers in use:", pin_name) # Prints the timer conflict pins.
|
print("Timers in use:", pin_name) # Prints the timer conflict pins.
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@ def is_hardware_SPI(clock_pin, data_pin):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
if is_hardware_SPI(board.A1, board.A2): # Provide the two pins you intend to use.
|
# Provide the two pins you intend to use.
|
||||||
|
if is_hardware_SPI(board.A1, board.A2):
|
||||||
print("This pin combination is hardware SPI!")
|
print("This pin combination is hardware SPI!")
|
||||||
else:
|
else:
|
||||||
print("This pin combination isn't hardware SPI.")
|
print("This pin combination isn't hardware SPI.")
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
import board
|
|
||||||
import array
|
import array
|
||||||
import time
|
import time
|
||||||
from digitalio import DigitalInOut, Direction, Pull
|
|
||||||
import pulseio
|
|
||||||
|
|
||||||
############## Switch to select 'stealth-mode'
|
import board
|
||||||
|
import pulseio
|
||||||
|
from digitalio import DigitalInOut, Direction, Pull
|
||||||
|
|
||||||
|
# Switch to select 'stealth-mode'
|
||||||
switch = DigitalInOut(board.SLIDE_SWITCH)
|
switch = DigitalInOut(board.SLIDE_SWITCH)
|
||||||
switch.direction = Direction.INPUT
|
switch.direction = Direction.INPUT
|
||||||
switch.pull = Pull.UP
|
switch.pull = Pull.UP
|
||||||
|
|
@ -12,14 +13,14 @@ switch.pull = Pull.UP
|
||||||
led = DigitalInOut(board.D13)
|
led = DigitalInOut(board.D13)
|
||||||
led.direction = Direction.OUTPUT
|
led.direction = Direction.OUTPUT
|
||||||
|
|
||||||
############## Speaker as haptic feedback
|
# Speaker as haptic feedback
|
||||||
spkr_en = DigitalInOut(board.SPEAKER_ENABLE)
|
spkr_en = DigitalInOut(board.SPEAKER_ENABLE)
|
||||||
spkr_en.direction = Direction.OUTPUT
|
spkr_en.direction = Direction.OUTPUT
|
||||||
spkr_en.value = True
|
spkr_en.value = True
|
||||||
spkr = DigitalInOut(board.SPEAKER)
|
spkr = DigitalInOut(board.SPEAKER)
|
||||||
spkr.direction = Direction.OUTPUT
|
spkr.direction = Direction.OUTPUT
|
||||||
|
|
||||||
############## Allow any button to trigger activity!
|
# Allow any button to trigger activity!
|
||||||
button_a = DigitalInOut(board.BUTTON_A)
|
button_a = DigitalInOut(board.BUTTON_A)
|
||||||
button_a.direction = Direction.INPUT
|
button_a.direction = Direction.INPUT
|
||||||
button_a.pull = Pull.DOWN
|
button_a.pull = Pull.DOWN
|
||||||
|
|
@ -27,8 +28,8 @@ button_b = DigitalInOut(board.BUTTON_B)
|
||||||
button_b.direction = Direction.INPUT
|
button_b.direction = Direction.INPUT
|
||||||
button_b.pull = Pull.DOWN
|
button_b.pull = Pull.DOWN
|
||||||
|
|
||||||
|
pwm = pulseio.PWMOut(board.REMOTEOUT, frequency=38000,
|
||||||
pwm = pulseio.PWMOut(board.REMOTEOUT, frequency=38000, duty_cycle=2 ** 15, variable_frequency=True)
|
duty_cycle=2 ** 15, variable_frequency=True)
|
||||||
pulse = pulseio.PulseOut(pwm)
|
pulse = pulseio.PulseOut(pwm)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
|
@ -36,7 +37,7 @@ while True:
|
||||||
while not (button_a.value or button_b.value):
|
while not (button_a.value or button_b.value):
|
||||||
pass
|
pass
|
||||||
time.sleep(0.5) # Give a half second before starting
|
time.sleep(0.5) # Give a half second before starting
|
||||||
|
|
||||||
# gooooo!
|
# gooooo!
|
||||||
f = open("/codes.txt", "r")
|
f = open("/codes.txt", "r")
|
||||||
for line in f:
|
for line in f:
|
||||||
|
|
@ -50,7 +51,7 @@ while True:
|
||||||
try:
|
try:
|
||||||
repeat = code['repeat']
|
repeat = code['repeat']
|
||||||
delay = code['repeat_delay']
|
delay = code['repeat_delay']
|
||||||
except KeyError: # by default, repeat once only!
|
except KeyError: # by default, repeat once only!
|
||||||
repeat = 1
|
repeat = 1
|
||||||
delay = 0
|
delay = 0
|
||||||
# The table holds the on/off pairs
|
# The table holds the on/off pairs
|
||||||
|
|
@ -65,9 +66,9 @@ while True:
|
||||||
for i in range(repeat):
|
for i in range(repeat):
|
||||||
pulse.send(array.array('H', pulses))
|
pulse.send(array.array('H', pulses))
|
||||||
time.sleep(delay)
|
time.sleep(delay)
|
||||||
|
|
||||||
led.value = False
|
led.value = False
|
||||||
spkr.value = False
|
spkr.value = False
|
||||||
time.sleep(code['delay'])
|
time.sleep(code['delay'])
|
||||||
|
|
||||||
f.close()
|
f.close()
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,26 @@
|
||||||
# Gemma M0 version of TVBgone!
|
# Gemma M0 version of TVBgone!
|
||||||
import board
|
|
||||||
import array
|
import array
|
||||||
import time
|
import time
|
||||||
from digitalio import DigitalInOut, Direction, Pull
|
|
||||||
import pulseio
|
|
||||||
import adafruit_dotstar
|
|
||||||
|
|
||||||
pixel = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2)
|
import adafruit_dotstar
|
||||||
|
import board
|
||||||
|
import pulseio
|
||||||
|
from digitalio import DigitalInOut, Direction
|
||||||
|
|
||||||
|
pixel = adafruit_dotstar.DotStar(
|
||||||
|
board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2)
|
||||||
pixel.fill((0, 0, 0))
|
pixel.fill((0, 0, 0))
|
||||||
|
|
||||||
# Button to see output debug
|
# Button to see output debug
|
||||||
led = DigitalInOut(board.D13)
|
led = DigitalInOut(board.D13)
|
||||||
led.direction = Direction.OUTPUT
|
led.direction = Direction.OUTPUT
|
||||||
|
|
||||||
pwm = pulseio.PWMOut(board.A1, frequency=38000, duty_cycle=2 ** 15, variable_frequency=True)
|
pwm = pulseio.PWMOut(board.A1, frequency=38000,
|
||||||
|
duty_cycle=2 ** 15, variable_frequency=True)
|
||||||
pulse = pulseio.PulseOut(pwm)
|
pulse = pulseio.PulseOut(pwm)
|
||||||
|
|
||||||
|
|
||||||
time.sleep(0.5) # Give a half second before starting
|
time.sleep(0.5) # Give a half second before starting
|
||||||
|
|
||||||
# gooooo!
|
# gooooo!
|
||||||
f = open("/codes.txt", "r")
|
f = open("/codes.txt", "r")
|
||||||
for line in f:
|
for line in f:
|
||||||
|
|
@ -30,7 +32,7 @@ for line in f:
|
||||||
try:
|
try:
|
||||||
repeat = code['repeat']
|
repeat = code['repeat']
|
||||||
delay = code['repeat_delay']
|
delay = code['repeat_delay']
|
||||||
except KeyError: # by default, repeat once only!
|
except KeyError: # by default, repeat once only!
|
||||||
repeat = 1
|
repeat = 1
|
||||||
delay = 0
|
delay = 0
|
||||||
# The table holds the on/off pairs
|
# The table holds the on/off pairs
|
||||||
|
|
@ -46,5 +48,5 @@ for line in f:
|
||||||
time.sleep(delay)
|
time.sleep(delay)
|
||||||
led.value = False
|
led.value = False
|
||||||
time.sleep(code['delay'])
|
time.sleep(code['delay'])
|
||||||
|
|
||||||
f.close()
|
f.close()
|
||||||
|
|
|
||||||
|
|
@ -4,20 +4,21 @@
|
||||||
# Photocell voltage divider center wire to GPIO #2 (analog 1)
|
# Photocell voltage divider center wire to GPIO #2 (analog 1)
|
||||||
# and output tone to GPIO #0 (digital 0)
|
# and output tone to GPIO #0 (digital 0)
|
||||||
|
|
||||||
import board
|
|
||||||
import analogio
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
import analogio
|
||||||
|
import board
|
||||||
import neopixel
|
import neopixel
|
||||||
import simpleio
|
import simpleio
|
||||||
|
|
||||||
# Initialize input/output pins
|
# Initialize input/output pins
|
||||||
photocell_pin = board.A1 # cds photocell connected to this ANALOG pin
|
photocell_pin = board.A1 # cds photocell connected to this ANALOG pin
|
||||||
speaker_pin = board.D0 # speaker is connected to this DIGITAL pin
|
speaker_pin = board.D0 # speaker is connected to this DIGITAL pin
|
||||||
pixpin = board.D1 # pin where NeoPixels are connected
|
pixpin = board.D1 # pin where NeoPixels are connected
|
||||||
numpix = 10 # number of neopixels`
|
numpix = 10 # number of neopixels`
|
||||||
darkness_min = (2**16 / 2) # more dark than light > 32k out of 64k
|
darkness_min = (2 ** 16 / 2) # more dark than light > 32k out of 64k
|
||||||
photocell = analogio.AnalogIn(photocell_pin)
|
photocell = analogio.AnalogIn(photocell_pin)
|
||||||
strip = neopixel.NeoPixel(pixpin, numpix, brightness=.4)
|
strip = neopixel.NeoPixel(pixpin, numpix, brightness=.4)
|
||||||
|
|
||||||
# this section is Close Encounters Sounds
|
# this section is Close Encounters Sounds
|
||||||
toned = 294
|
toned = 294
|
||||||
|
|
@ -26,66 +27,68 @@ tonec = 262
|
||||||
toneC = 130
|
toneC = 130
|
||||||
toneg = 392
|
toneg = 392
|
||||||
|
|
||||||
def alien():
|
|
||||||
strip[8] = (255, 255, 0) # yellow front
|
def alien():
|
||||||
strip[3] = (255, 255, 0) # yellow back
|
strip[8] = (255, 255, 0) # yellow front
|
||||||
simpleio.tone(speaker_pin, toned, 1) # play tone for 1 second
|
strip[3] = (255, 255, 0) # yellow back
|
||||||
|
simpleio.tone(speaker_pin, toned, 1) # play tone for 1 second
|
||||||
|
|
||||||
time.sleep(.025)
|
time.sleep(.025)
|
||||||
|
|
||||||
strip[8] = (0, 0, 0) # clear front
|
strip[8] = (0, 0, 0) # clear front
|
||||||
strip[3] = (0, 0, 0) # clear back
|
strip[3] = (0, 0, 0) # clear back
|
||||||
|
|
||||||
time.sleep(.025)
|
time.sleep(.025)
|
||||||
|
|
||||||
strip[7] = (255, 0, 255) # pink front
|
strip[7] = (255, 0, 255) # pink front
|
||||||
strip[2] = (255, 0, 255) # pink back
|
strip[2] = (255, 0, 255) # pink back
|
||||||
simpleio.tone(speaker_pin, tonee, 1) # play tone for 1 second
|
simpleio.tone(speaker_pin, tonee, 1) # play tone for 1 second
|
||||||
|
|
||||||
time.sleep(.025)
|
time.sleep(.025)
|
||||||
|
|
||||||
strip[7] = (0, 0, 0) # clear front
|
strip[7] = (0, 0, 0) # clear front
|
||||||
strip[2] = (0, 0, 0) # clear back
|
strip[2] = (0, 0, 0) # clear back
|
||||||
|
|
||||||
time.sleep(.025)
|
time.sleep(.025)
|
||||||
|
|
||||||
strip[4] = (128, 255, 0) # green front
|
strip[4] = (128, 255, 0) # green front
|
||||||
strip[9] = (128, 255, 0) # green back
|
strip[9] = (128, 255, 0) # green back
|
||||||
simpleio.tone(speaker_pin, tonec, 1) # play tone for 1 second
|
simpleio.tone(speaker_pin, tonec, 1) # play tone for 1 second
|
||||||
|
|
||||||
time.sleep(.025)
|
time.sleep(.025)
|
||||||
|
|
||||||
strip[4] = (0, 0, 0) # clear front
|
strip[4] = (0, 0, 0) # clear front
|
||||||
strip[9] = (0, 0, 0) # clear back
|
strip[9] = (0, 0, 0) # clear back
|
||||||
|
|
||||||
time.sleep(.025)
|
time.sleep(.025)
|
||||||
|
|
||||||
strip[5] = (0, 0, 255) # blue front
|
strip[5] = (0, 0, 255) # blue front
|
||||||
strip[0] = (0, 0, 255) # blue back
|
strip[0] = (0, 0, 255) # blue back
|
||||||
simpleio.tone(speaker_pin, toneC, 1) # play tone for 1 second
|
simpleio.tone(speaker_pin, toneC, 1) # play tone for 1 second
|
||||||
|
|
||||||
time.sleep(.075)
|
time.sleep(.075)
|
||||||
|
|
||||||
strip[5] = (0, 0, 0) # clear front
|
strip[5] = (0, 0, 0) # clear front
|
||||||
strip[0] = (0, 0, 0) # clear back
|
strip[0] = (0, 0, 0) # clear back
|
||||||
|
|
||||||
time.sleep(.1)
|
time.sleep(.1)
|
||||||
|
|
||||||
strip[6] = (255, 0, 0) # red front
|
strip[6] = (255, 0, 0) # red front
|
||||||
strip[1] = (255, 0, 0) # red back
|
strip[1] = (255, 0, 0) # red back
|
||||||
simpleio.tone(speaker_pin, toneg, 1) # play tone for 1 second
|
simpleio.tone(speaker_pin, toneg, 1) # play tone for 1 second
|
||||||
|
|
||||||
time.sleep(.1)
|
time.sleep(.1)
|
||||||
|
|
||||||
strip[6] = (0, 0, 0) # clear front
|
strip[6] = (0, 0, 0) # clear front
|
||||||
strip[1] = (0, 0, 0) # clear back
|
strip[1] = (0, 0, 0) # clear back
|
||||||
|
|
||||||
time.sleep(.1)
|
time.sleep(.1)
|
||||||
|
|
||||||
|
|
||||||
# Loop forever...
|
# Loop forever...
|
||||||
while True:
|
while True:
|
||||||
|
|
||||||
# turn lights and audio on when dark
|
# turn lights and audio on when dark
|
||||||
# (less than 50% light on analog pin)
|
# (less than 50% light on analog pin)
|
||||||
if ( photocell.value > darkness_min ):
|
if photocell.value > darkness_min:
|
||||||
alien() # close Encounters Loop
|
alien() # close Encounters Loop
|
||||||
|
|
|
||||||
|
|
@ -2,22 +2,26 @@
|
||||||
# for Adafruit Circuit Playground express
|
# for Adafruit Circuit Playground express
|
||||||
# with CircuitPython
|
# with CircuitPython
|
||||||
|
|
||||||
from adafruit_circuitplayground.express import cpx
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import board
|
import board
|
||||||
import simpleio
|
import simpleio
|
||||||
|
from adafruit_circuitplayground.express import cpx
|
||||||
|
|
||||||
# plug red servo wire to VOUT, brown to GND, yellow to A3
|
# plug red servo wire to VOUT, brown to GND, yellow to A3
|
||||||
servo = simpleio.Servo(board.A3)
|
servo = simpleio.Servo(board.A3)
|
||||||
|
|
||||||
cpx.pixels.brightness = 0.05 # set brightness value
|
cpx.pixels.brightness = 0.05 # set brightness value
|
||||||
|
|
||||||
|
|
||||||
def unlock_servo():
|
def unlock_servo():
|
||||||
servo.angle = 180
|
servo.angle = 180
|
||||||
|
|
||||||
|
|
||||||
def lock_servo():
|
def lock_servo():
|
||||||
servo.angle = 90
|
servo.angle = 90
|
||||||
|
|
||||||
|
|
||||||
correct_combo = ['B', 'D', 'C'] # this is where to set the combo
|
correct_combo = ['B', 'D', 'C'] # this is where to set the combo
|
||||||
entered_combo = [] # this will be used to store attempts
|
entered_combo = [] # this will be used to store attempts
|
||||||
current_dial_position = 'X'
|
current_dial_position = 'X'
|
||||||
|
|
@ -74,7 +78,8 @@ while True:
|
||||||
if cpx.button_a: # this means the button has been pressed
|
if cpx.button_a: # this means the button has been pressed
|
||||||
# grab the current_dial_position value and add to the list
|
# grab the current_dial_position value and add to the list
|
||||||
entered_combo.append(current_dial_position)
|
entered_combo.append(current_dial_position)
|
||||||
dial_msg = 'Dial Position: ' + str(entered_combo[(len(entered_combo)-1)])
|
dial_msg = 'Dial Position: ' + \
|
||||||
|
str(entered_combo[(len(entered_combo) - 1)])
|
||||||
print(dial_msg)
|
print(dial_msg)
|
||||||
cpx.play_tone(320, 0.3) # beep
|
cpx.play_tone(320, 0.3) # beep
|
||||||
time.sleep(1) # slow down button checks
|
time.sleep(1) # slow down button checks
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
# CircuitPython 3.0 CRICKIT demo
|
# CircuitPython 3.0 CRICKIT demo
|
||||||
from adafruit_seesaw.seesaw import Seesaw
|
|
||||||
from adafruit_seesaw.pwmout import PWMOut
|
|
||||||
from adafruit_motor import servo, motor
|
|
||||||
from busio import I2C
|
|
||||||
import board
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
import board
|
||||||
|
from adafruit_motor import servo, motor
|
||||||
|
from adafruit_seesaw.pwmout import PWMOut
|
||||||
|
from adafruit_seesaw.seesaw import Seesaw
|
||||||
|
from busio import I2C
|
||||||
|
|
||||||
i2c = I2C(board.SCL, board.SDA)
|
i2c = I2C(board.SCL, board.SDA)
|
||||||
ss = Seesaw(i2c)
|
ss = Seesaw(i2c)
|
||||||
|
|
||||||
|
|
@ -14,22 +15,22 @@ print("Bubble machine!")
|
||||||
SERVOS = True
|
SERVOS = True
|
||||||
DCMOTORS = True
|
DCMOTORS = True
|
||||||
|
|
||||||
#################### Create 4 Servos
|
# Create 4 Servos
|
||||||
servos = []
|
servos = []
|
||||||
if SERVOS:
|
if SERVOS:
|
||||||
for ss_pin in (17, 16, 15, 14):
|
for ss_pin in (17, 16, 15, 14):
|
||||||
pwm = PWMOut(ss, ss_pin)
|
pwm = PWMOut(ss, ss_pin)
|
||||||
pwm.frequency = 50
|
pwm.frequency = 50
|
||||||
_servo = servo.Servo(pwm)
|
_servo = servo.Servo(pwm)
|
||||||
_servo.angle = 90 # starting angle, middle
|
_servo.angle = 90 # starting angle, middle
|
||||||
servos.append(_servo)
|
servos.append(_servo)
|
||||||
|
|
||||||
#################### Create 2 DC motors
|
# Create 2 DC motors
|
||||||
motors = []
|
motors = []
|
||||||
if DCMOTORS:
|
if DCMOTORS:
|
||||||
for ss_pin in ((18, 19), (22, 23)):
|
for ss_pin in ((18, 19), (22, 23)):
|
||||||
pwm0 = PWMOut(ss, ss_pin[0])
|
pwm0 = PWMOut(ss, ss_pin[0])
|
||||||
pwm1 = PWMOut(ss, ss_pin[1])
|
pwm1 = PWMOut(ss, ss_pin[1])
|
||||||
_motor = motor.DCMotor(pwm0, pwm1)
|
_motor = motor.DCMotor(pwm0, pwm1)
|
||||||
motors.append(_motor)
|
motors.append(_motor)
|
||||||
|
|
||||||
|
|
@ -45,4 +46,4 @@ while True:
|
||||||
motors[0].throttle = 0
|
motors[0].throttle = 0
|
||||||
print("servo up")
|
print("servo up")
|
||||||
servos[0].angle = 0
|
servos[0].angle = 0
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
|
||||||
|
|
@ -1,65 +1,68 @@
|
||||||
# CircuitPython 3.0 CRICKIT demo
|
# CircuitPython 3.0 CRICKIT demo
|
||||||
|
|
||||||
from adafruit_seesaw.seesaw import Seesaw
|
|
||||||
from adafruit_seesaw.pwmout import PWMOut
|
|
||||||
from adafruit_motor import servo, motor
|
|
||||||
import audioio
|
|
||||||
from busio import I2C
|
|
||||||
import random
|
|
||||||
import board
|
|
||||||
import time
|
|
||||||
import gc
|
import gc
|
||||||
|
import time
|
||||||
|
|
||||||
|
import audioio
|
||||||
|
import board
|
||||||
|
from adafruit_motor import servo
|
||||||
|
from adafruit_seesaw.pwmout import PWMOut
|
||||||
|
from adafruit_seesaw.seesaw import Seesaw
|
||||||
|
from busio import I2C
|
||||||
|
|
||||||
i2c = I2C(board.SCL, board.SDA)
|
i2c = I2C(board.SCL, board.SDA)
|
||||||
ss = Seesaw(i2c)
|
ss = Seesaw(i2c)
|
||||||
|
|
||||||
print("Feynbot demo!")
|
print("Feynbot demo!")
|
||||||
|
|
||||||
#################### 1 Servo
|
# 1 Servo
|
||||||
pwm = PWMOut(ss, 17)
|
pwm = PWMOut(ss, 17)
|
||||||
pwm.frequency = 50
|
pwm.frequency = 50
|
||||||
myservo = servo.Servo(pwm)
|
myservo = servo.Servo(pwm)
|
||||||
myservo.angle = 180 # starting angle, highest
|
myservo.angle = 180 # starting angle, highest
|
||||||
|
|
||||||
#################### 2 Drivers
|
# 2 Drivers
|
||||||
drives = []
|
drives = []
|
||||||
for ss_pin in (13, 12):
|
for ss_pin in (13, 12):
|
||||||
_pwm = PWMOut(ss, ss_pin)
|
_pwm = PWMOut(ss, ss_pin)
|
||||||
_pwm.frequency = 1000
|
_pwm.frequency = 1000
|
||||||
drives.append(_pwm)
|
drives.append(_pwm)
|
||||||
|
|
||||||
#################### Audio files
|
# Audio files
|
||||||
wavfiles = ["01.wav", "02.wav", "03.wav", "04.wav", "05.wav"]
|
wavfiles = ["01.wav", "02.wav", "03.wav", "04.wav", "05.wav"]
|
||||||
a = audioio.AudioOut(board.A0)
|
a = audioio.AudioOut(board.A0)
|
||||||
|
|
||||||
|
|
||||||
# Start playing the file (in the background)
|
# Start playing the file (in the background)
|
||||||
def play_file(wavfile):
|
def play_file(wavfile):
|
||||||
f = open(wavfile, "rb")
|
f = open(wavfile, "rb")
|
||||||
wav = audioio.WaveFile(f)
|
wav = audioio.WaveFile(f)
|
||||||
a.play(wav)
|
a.play(wav)
|
||||||
|
|
||||||
|
|
||||||
# Tap the solenoids back and forth
|
# Tap the solenoids back and forth
|
||||||
def bongo(t):
|
def bongo(t):
|
||||||
for _ in range(t):
|
for _ in range(t):
|
||||||
drives[0].duty_cycle = 0xFFFF
|
drives[0].duty_cycle = 0xFFFF
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
drives[0].duty_cycle = 0
|
drives[0].duty_cycle = 0
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
drives[1].duty_cycle = 0xFFFF
|
drives[1].duty_cycle = 0xFFFF
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
drives[1].duty_cycle = 0
|
drives[1].duty_cycle = 0
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
# Move mouth back and forth
|
# Move mouth back and forth
|
||||||
def talk(t):
|
def talk(t):
|
||||||
for _ in range(t):
|
for _ in range(t):
|
||||||
myservo.angle = 150
|
myservo.angle = 150
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
myservo.angle = 180
|
myservo.angle = 180
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
filenum = 0 # counter to play all files
|
filenum = 0 # counter to play all files
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
gc.collect()
|
gc.collect()
|
||||||
|
|
@ -73,13 +76,13 @@ while True:
|
||||||
play_file(wavfiles[filenum])
|
play_file(wavfiles[filenum])
|
||||||
# and move the mouth while it does
|
# and move the mouth while it does
|
||||||
while a.playing:
|
while a.playing:
|
||||||
talk(1)
|
talk(1)
|
||||||
|
|
||||||
# Done being insightful, take a break
|
# Done being insightful, take a break
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
# If we went thru all the files, JAM OUT!
|
# If we went thru all the files, JAM OUT!
|
||||||
filenum += 1
|
filenum += 1
|
||||||
if filenum >= len(wavfiles):
|
if filenum >= len(wavfiles):
|
||||||
bongo(20)
|
bongo(20)
|
||||||
filenum = 0
|
filenum = 0
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,10 @@
|
||||||
# calibrated with your body touching it (making it less accurate).
|
# calibrated with your body touching it (making it less accurate).
|
||||||
#
|
#
|
||||||
# Also note this depends on two external modules to be loaded on the Gemma M0:
|
# Also note this depends on two external modules to be loaded on the Gemma M0:
|
||||||
# - Adafruit CircuitPython DotStar: https://github.com/adafruit/Adafruit_CircuitPython_DotStar
|
# - Adafruit CircuitPython DotStar:
|
||||||
# - Adafruit CircuitPython FancyLED: https://github.com/adafruit/Adafruit_CircuitPython_FancyLED
|
# https://github.com/adafruit/Adafruit_CircuitPython_DotStar
|
||||||
|
# - Adafruit CircuitPython FancyLED:
|
||||||
|
# https://github.com/adafruit/Adafruit_CircuitPython_FancyLED
|
||||||
#
|
#
|
||||||
# You _must_ have both adafruit_dotstar.mpy and the adafruit_fancyled folder
|
# You _must_ have both adafruit_dotstar.mpy and the adafruit_fancyled folder
|
||||||
# and files within it on your board for this code to work! If you run into
|
# and files within it on your board for this code to work! If you run into
|
||||||
|
|
@ -38,51 +40,49 @@
|
||||||
import math
|
import math
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
import adafruit_dotstar
|
||||||
|
import adafruit_fancyled.adafruit_fancyled as fancy
|
||||||
import board
|
import board
|
||||||
import digitalio
|
import digitalio
|
||||||
import touchio
|
import touchio
|
||||||
|
|
||||||
import adafruit_dotstar
|
|
||||||
import adafruit_fancyled.adafruit_fancyled as fancy
|
|
||||||
|
|
||||||
|
|
||||||
# Variables that control the code. Try changing these to modify speed, color,
|
# Variables that control the code. Try changing these to modify speed, color,
|
||||||
# etc.
|
# etc.
|
||||||
START_DELAY = 5.0 # How many seconds to wait after power up before
|
START_DELAY = 5.0 # How many seconds to wait after power up before
|
||||||
# jumping into the animation and initializing the
|
# jumping into the animation and initializing the
|
||||||
# touch input. This gives you time to take move your
|
# touch input. This gives you time to take move your
|
||||||
# fingers off the flower so the capacitive touch
|
# fingers off the flower so the capacitive touch
|
||||||
# sensing is better calibrated. During the delay
|
# sensing is better calibrated. During the delay
|
||||||
# the small red LED on the board will flash.
|
# the small red LED on the board will flash.
|
||||||
|
|
||||||
TOUCH_PIN = board.D0 # The board pin to listen for touches and trigger the
|
TOUCH_PIN = board.D0 # The board pin to listen for touches and trigger the
|
||||||
# heart beat animation. You can change this to any
|
# heart beat animation. You can change this to any
|
||||||
# other pin like board.D2 or board.D1. Make sure not
|
# other pin like board.D2 or board.D1. Make sure not
|
||||||
# to touch this pin as the board powers on or the
|
# to touch this pin as the board powers on or the
|
||||||
# capacitive sensing will get confused (just reset
|
# capacitive sensing will get confused (just reset
|
||||||
# the board and try again).
|
# the board and try again).
|
||||||
|
|
||||||
BRIGHTNESS = 1.0 # The brightness of the colors. Set this to a value
|
BRIGHTNESS = 1.0 # The brightness of the colors. Set this to a value
|
||||||
# anywhere within 0 and 1.0, where 1.0 is full bright.
|
# anywhere within 0 and 1.0, where 1.0 is full bright.
|
||||||
# For example 0.5 would be half brightness.
|
# For example 0.5 would be half brightness.
|
||||||
|
|
||||||
RAINBOW_PERIOD_S = 18.0 # How many seconds it takes for the default rainbow
|
RAINBOW_PERIOD_S = 18.0 # How many seconds it takes for the default rainbow
|
||||||
# cycle animation to perform a full cycle. Increase
|
# cycle animation to perform a full cycle. Increase
|
||||||
# this to slow down the animation or decrease to speed
|
# this to slow down the animation or decrease to speed
|
||||||
# it up.
|
# it up.
|
||||||
|
|
||||||
HEARTBEAT_BPM = 60.0 # Heartbeat animation beats per minute. Increase to
|
HEARTBEAT_BPM = 60.0 # Heartbeat animation beats per minute. Increase to
|
||||||
# speed up the heartbeat, and decrease to slow down.
|
# speed up the heartbeat, and decrease to slow down.
|
||||||
|
|
||||||
HEARTBEAT_HUE = 300.0 # The color hue to use when animating the heartbeat
|
HEARTBEAT_HUE = 300.0 # The color hue to use when animating the heartbeat
|
||||||
# animation. Pick a value in the range of 0 to 359
|
# animation. Pick a value in the range of 0 to 359
|
||||||
# degrees, see the hue spectrum here:
|
# degrees, see the hue spectrum here:
|
||||||
# https://en.wikipedia.org/wiki/Hue
|
# https://en.wikipedia.org/wiki/Hue
|
||||||
# A value of 300 is a nice pink color.
|
# A value of 300 is a nice pink color.
|
||||||
|
|
||||||
# First initialize the DotStar LED and turn it off.
|
# First initialize the DotStar LED and turn it off.
|
||||||
dotstar = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1)
|
dotstar = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1)
|
||||||
dotstar[0] = (0,0,0)
|
dotstar[0] = (0, 0, 0)
|
||||||
|
|
||||||
# Also make sure the on-board red LED is turned off.
|
# Also make sure the on-board red LED is turned off.
|
||||||
red_led = digitalio.DigitalInOut(board.L)
|
red_led = digitalio.DigitalInOut(board.L)
|
||||||
|
|
@ -103,24 +103,29 @@ while time.monotonic() - start <= START_DELAY:
|
||||||
touch = touchio.TouchIn(TOUCH_PIN)
|
touch = touchio.TouchIn(TOUCH_PIN)
|
||||||
|
|
||||||
# Convert periods to frequencies that are used later in animations.
|
# Convert periods to frequencies that are used later in animations.
|
||||||
rainbow_freq = 1.0/RAINBOW_PERIOD_S
|
rainbow_freq = 1.0 / RAINBOW_PERIOD_S
|
||||||
|
|
||||||
# Calculcate periods and values used by the heartbeat animation.
|
# Calculcate periods and values used by the heartbeat animation.
|
||||||
beat_period = 60.0/HEARTBEAT_BPM
|
beat_period = 60.0 / HEARTBEAT_BPM
|
||||||
beat_quarter_period = beat_period/4.0 # Quarter period controls the speed of
|
beat_quarter_period = beat_period / 4.0 # Quarter period controls the speed of
|
||||||
# the heartbeat drop-off (using an
|
# the heartbeat drop-off (using an
|
||||||
# exponential decay function).
|
# exponential decay function).
|
||||||
beat_phase = beat_period/5.0 # Phase controls how long in-between
|
beat_phase = beat_period / 5.0 # Phase controls how long in-between
|
||||||
# the two parts of the heart beat
|
|
||||||
# (the 'ba-boom' of the beat).
|
|
||||||
|
# the two parts of the heart beat
|
||||||
|
# (the 'ba-boom' of the beat).
|
||||||
|
|
||||||
# Handy function for linear interpolation of a value. Pass in a value
|
# Handy function for linear interpolation of a value. Pass in a value
|
||||||
# x that's within the range x0...x1 and a range y0...y1 to get an output value
|
# x that's within the range x0...x1 and a range y0...y1 to get an output value
|
||||||
# y that's proportionally within y0...y1 based on x within x0...x1. Handy for
|
# y that's proportionally within y0...y1 based on x within x0...x1. Handy for
|
||||||
# transforming a value in one range to a value in another (like Arduino's map
|
# transforming a value in one range to a value in another (like Arduino's map
|
||||||
# function).
|
# function).
|
||||||
|
|
||||||
|
|
||||||
def lerp(x, x0, x1, y0, y1):
|
def lerp(x, x0, x1, y0, y1):
|
||||||
return y0+(x-x0)*((y1-y0)/(x1-x0))
|
return y0 + (x - x0) * ((y1 - y0) / (x1 - x0))
|
||||||
|
|
||||||
|
|
||||||
# Main loop below will run forever:
|
# Main loop below will run forever:
|
||||||
while True:
|
while True:
|
||||||
|
|
@ -139,8 +144,8 @@ while True:
|
||||||
# out of phase so one occurs a little bit after the other.
|
# out of phase so one occurs a little bit after the other.
|
||||||
t0 = current % beat_period
|
t0 = current % beat_period
|
||||||
t1 = (current + beat_phase) % beat_period
|
t1 = (current + beat_phase) % beat_period
|
||||||
x0 = math.pow(math.e, -t0/beat_quarter_period)
|
x0 = math.pow(math.e, -t0 / beat_quarter_period)
|
||||||
x1 = math.pow(math.e, -t1/beat_quarter_period)
|
x1 = math.pow(math.e, -t1 / beat_quarter_period)
|
||||||
# After calculating both exponential decay values pick the biggest one
|
# After calculating both exponential decay values pick the biggest one
|
||||||
# as the secondary one will occur after the first. Scale each by
|
# as the secondary one will occur after the first. Scale each by
|
||||||
# the global brightness and then convert to RGB color using the fixed
|
# the global brightness and then convert to RGB color using the fixed
|
||||||
|
|
@ -149,14 +154,14 @@ while True:
|
||||||
# like we expect for full bright to zero brightness with HSV color
|
# like we expect for full bright to zero brightness with HSV color
|
||||||
# (i.e. no interpolation is necessary).
|
# (i.e. no interpolation is necessary).
|
||||||
val = max(x0, x1) * BRIGHTNESS
|
val = max(x0, x1) * BRIGHTNESS
|
||||||
color = fancy.gamma_adjust(fancy.CHSV(HEARTBEAT_HUE/359.0, 1.0, val))
|
color = fancy.gamma_adjust(fancy.CHSV(HEARTBEAT_HUE / 359.0, 1.0, val))
|
||||||
dotstar[0] = color.pack()
|
dotstar[0] = color.pack()
|
||||||
else:
|
else:
|
||||||
# The touch input is not being touched (touch.value is False) so
|
# The touch input is not being touched (touch.value is False) so
|
||||||
# compute the hue with a smooth cycle over time.
|
# compute the hue with a smooth cycle over time.
|
||||||
# First use the sine function to smoothly generate a value that goes
|
# First use the sine function to smoothly generate a value that goes
|
||||||
# from -1.0 to 1.0 at a certain frequency to match the rainbow period.
|
# from -1.0 to 1.0 at a certain frequency to match the rainbow period.
|
||||||
x = math.sin(2.0*math.pi*rainbow_freq*current)
|
x = math.sin(2.0 * math.pi * rainbow_freq * current)
|
||||||
# Then compute the hue by converting the sine wave value from something
|
# Then compute the hue by converting the sine wave value from something
|
||||||
# that goes from -1.0 to 1.0 to instead go from 0 to 1.0 hue.
|
# that goes from -1.0 to 1.0 to instead go from 0 to 1.0 hue.
|
||||||
hue = lerp(x, -1.0, 1.0, 0.0, 1.0)
|
hue = lerp(x, -1.0, 1.0, 0.0, 1.0)
|
||||||
|
|
|
||||||
|
|
@ -34,40 +34,39 @@ import busio
|
||||||
import digitalio
|
import digitalio
|
||||||
import touchio
|
import touchio
|
||||||
|
|
||||||
|
|
||||||
# Variables that control the code. Try changing these to modify speed, color,
|
# Variables that control the code. Try changing these to modify speed, color,
|
||||||
# etc.
|
# etc.
|
||||||
START_DELAY = 5.0 # How many seconds to wait after power up before
|
START_DELAY = 5.0 # How many seconds to wait after power up before
|
||||||
# jumping into the animation and initializing the
|
# jumping into the animation and initializing the
|
||||||
# touch input. This gives you time to take move your
|
# touch input. This gives you time to take move your
|
||||||
# fingers off the flower so the capacitive touch
|
# fingers off the flower so the capacitive touch
|
||||||
# sensing is better calibrated. During the delay
|
# sensing is better calibrated. During the delay
|
||||||
# the small red LED on the board will flash.
|
# the small red LED on the board will flash.
|
||||||
|
|
||||||
TOUCH_PIN = board.D0 # The board pin to listen for touches and trigger the
|
TOUCH_PIN = board.D0 # The board pin to listen for touches and trigger the
|
||||||
# heart beat animation. You can change this to any
|
# heart beat animation. You can change this to any
|
||||||
# other pin like board.D2 or board.D1. Make sure not
|
# other pin like board.D2 or board.D1. Make sure not
|
||||||
# to touch this pin as the board powers on or the
|
# to touch this pin as the board powers on or the
|
||||||
# capacitive sensing will get confused (just reset
|
# capacitive sensing will get confused (just reset
|
||||||
# the board and try again).
|
# the board and try again).
|
||||||
|
|
||||||
BRIGHTNESS = 1.0 # The brightness of the colors. Set this to a value
|
BRIGHTNESS = 1.0 # The brightness of the colors. Set this to a value
|
||||||
# anywhere within 0 and 1.0, where 1.0 is full bright.
|
# anywhere within 0 and 1.0, where 1.0 is full bright.
|
||||||
# For example 0.5 would be half brightness.
|
# For example 0.5 would be half brightness.
|
||||||
|
|
||||||
RAINBOW_PERIOD_S = 18.0 # How many seconds it takes for the default rainbow
|
RAINBOW_PERIOD_S = 18.0 # How many seconds it takes for the default rainbow
|
||||||
# cycle animation to perform a full cycle. Increase
|
# cycle animation to perform a full cycle. Increase
|
||||||
# this to slow down the animation or decrease to speed
|
# this to slow down the animation or decrease to speed
|
||||||
# it up.
|
# it up.
|
||||||
|
|
||||||
HEARTBEAT_BPM = 60.0 # Heartbeat animation beats per minute. Increase to
|
HEARTBEAT_BPM = 60.0 # Heartbeat animation beats per minute. Increase to
|
||||||
# speed up the heartbeat, and decrease to slow down.
|
# speed up the heartbeat, and decrease to slow down.
|
||||||
|
|
||||||
HEARTBEAT_HUE = 300.0 # The color hue to use when animating the heartbeat
|
HEARTBEAT_HUE = 300.0 # The color hue to use when animating the heartbeat
|
||||||
# animation. Pick a value in the range of 0 to 359
|
# animation. Pick a value in the range of 0 to 359
|
||||||
# degrees, see the hue spectrum here:
|
# degrees, see the hue spectrum here:
|
||||||
# https://en.wikipedia.org/wiki/Hue
|
# https://en.wikipedia.org/wiki/Hue
|
||||||
# A value of 300 is a nice pink color.
|
# A value of 300 is a nice pink color.
|
||||||
|
|
||||||
# First initialize the DotStar LED and turn it off.
|
# First initialize the DotStar LED and turn it off.
|
||||||
# We'll manually drive the dotstar instead of depending on the adafruit_dotstar
|
# We'll manually drive the dotstar instead of depending on the adafruit_dotstar
|
||||||
|
|
@ -78,7 +77,11 @@ dotstar_spi = busio.SPI(clock=board.APA102_SCK, MOSI=board.APA102_MOSI)
|
||||||
# pixel data, followed by bytes of 0xFF tail (just one for 1 pixel).
|
# pixel data, followed by bytes of 0xFF tail (just one for 1 pixel).
|
||||||
dotstar_data = bytearray([0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
|
dotstar_data = bytearray([0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
|
||||||
0xFF])
|
0xFF])
|
||||||
|
|
||||||
|
|
||||||
# Define a function to simplify setting dotstar color.
|
# Define a function to simplify setting dotstar color.
|
||||||
|
|
||||||
|
|
||||||
def dotstar_color(rgb_color):
|
def dotstar_color(rgb_color):
|
||||||
# Set the color of the dot star LED. This is barebones dotstar driving
|
# Set the color of the dot star LED. This is barebones dotstar driving
|
||||||
# code for simplicity and less dependency on other libraries. We're only
|
# code for simplicity and less dependency on other libraries. We're only
|
||||||
|
|
@ -93,6 +96,8 @@ def dotstar_color(rgb_color):
|
||||||
dotstar_spi.write(dotstar_data)
|
dotstar_spi.write(dotstar_data)
|
||||||
finally:
|
finally:
|
||||||
dotstar_spi.unlock()
|
dotstar_spi.unlock()
|
||||||
|
|
||||||
|
|
||||||
# Call the function above to turn off the dotstar initially (set it to all 0).
|
# Call the function above to turn off the dotstar initially (set it to all 0).
|
||||||
dotstar_color((0, 0, 0))
|
dotstar_color((0, 0, 0))
|
||||||
|
|
||||||
|
|
@ -115,23 +120,24 @@ while time.monotonic() - start <= START_DELAY:
|
||||||
touch = touchio.TouchIn(TOUCH_PIN)
|
touch = touchio.TouchIn(TOUCH_PIN)
|
||||||
|
|
||||||
# Convert periods to frequencies that are used later in animations.
|
# Convert periods to frequencies that are used later in animations.
|
||||||
rainbow_freq = 1.0/RAINBOW_PERIOD_S
|
rainbow_freq = 1.0 / RAINBOW_PERIOD_S
|
||||||
|
|
||||||
# Calculcate periods and values used by the heartbeat animation.
|
# Calculcate periods and values used by the heartbeat animation.
|
||||||
beat_period = 60.0/HEARTBEAT_BPM
|
beat_period = 60.0 / HEARTBEAT_BPM
|
||||||
beat_quarter_period = beat_period/4.0 # Quarter period controls the speed of
|
beat_quarter_period = beat_period / 4.0 # Quarter period controls the speed of
|
||||||
# the heartbeat drop-off (using an
|
# the heartbeat drop-off (using an
|
||||||
# exponential decay function).
|
# exponential decay function).
|
||||||
beat_phase = beat_period/5.0 # Phase controls how long in-between
|
beat_phase = beat_period / 5.0 # Phase controls how long in-between
|
||||||
# the two parts of the heart beat
|
# the two parts of the heart beat
|
||||||
# (the 'ba-boom' of the beat).
|
# (the 'ba-boom' of the beat).
|
||||||
|
|
||||||
# Define a gamma correction lookup table to make colors more accurate.
|
# Define a gamma correction lookup table to make colors more accurate.
|
||||||
# See this guide for more background on gamma correction:
|
# See this guide for more background on gamma correction:
|
||||||
# https://learn.adafruit.com/led-tricks-gamma-correction/
|
# https://learn.adafruit.com/led-tricks-gamma-correction/
|
||||||
gamma8 = bytearray(256)
|
gamma8 = bytearray(256)
|
||||||
for i in range(len(gamma8)):
|
for i in range(len(gamma8)):
|
||||||
gamma8[i] = int(math.pow(i/255.0, 2.8)*255.0+0.5) & 0xFF
|
gamma8[i] = int(math.pow(i / 255.0, 2.8) * 255.0 + 0.5) & 0xFF
|
||||||
|
|
||||||
|
|
||||||
# Define a function to convert from HSV (hue, saturation, value) color to
|
# Define a function to convert from HSV (hue, saturation, value) color to
|
||||||
# RGB colors that DotStar LEDs speak. The HSV color space is a nicer for
|
# RGB colors that DotStar LEDs speak. The HSV color space is a nicer for
|
||||||
|
|
@ -140,18 +146,17 @@ for i in range(len(gamma8)):
|
||||||
# value that range from 0 to 1.0. This will also use the gamma correction
|
# value that range from 0 to 1.0. This will also use the gamma correction
|
||||||
# table above to get the most accurate color. Adapted from C/C++ code here:
|
# table above to get the most accurate color. Adapted from C/C++ code here:
|
||||||
# https://www.cs.rit.edu/~ncs/color/t_convert.html
|
# https://www.cs.rit.edu/~ncs/color/t_convert.html
|
||||||
|
|
||||||
|
|
||||||
def HSV_to_RGB(h, s, v):
|
def HSV_to_RGB(h, s, v):
|
||||||
r = 0
|
|
||||||
g = 0
|
|
||||||
b = 0
|
|
||||||
if s == 0.0:
|
if s == 0.0:
|
||||||
r = v
|
r = v
|
||||||
g = v
|
g = v
|
||||||
b = v
|
b = v
|
||||||
else:
|
else:
|
||||||
h /= 60.0 # sector 0 to 5
|
h /= 60.0 # sector 0 to 5
|
||||||
i = int(math.floor(h))
|
i = int(math.floor(h))
|
||||||
f = h - i # factorial part of h
|
f = h - i # factorial part of h
|
||||||
p = v * (1.0 - s)
|
p = v * (1.0 - s)
|
||||||
q = v * (1.0 - s * f)
|
q = v * (1.0 - s * f)
|
||||||
t = v * (1.0 - s * (1.0 - f))
|
t = v * (1.0 - s * (1.0 - f))
|
||||||
|
|
@ -179,18 +184,22 @@ def HSV_to_RGB(h, s, v):
|
||||||
r = v
|
r = v
|
||||||
g = p
|
g = p
|
||||||
b = q
|
b = q
|
||||||
r = gamma8[int(255.0*r)]
|
r = gamma8[int(255.0 * r)]
|
||||||
g = gamma8[int(255.0*g)]
|
g = gamma8[int(255.0 * g)]
|
||||||
b = gamma8[int(255.0*b)]
|
b = gamma8[int(255.0 * b)]
|
||||||
return (r, g, b)
|
return (r, g, b)
|
||||||
|
|
||||||
|
|
||||||
# Another handy function for linear interpolation of a value. Pass in a value
|
# Another handy function for linear interpolation of a value. Pass in a value
|
||||||
# x that's within the range x0...x1 and a range y0...y1 to get an output value
|
# x that's within the range x0...x1 and a range y0...y1 to get an output value
|
||||||
# y that's proportionally within y0...y1 based on x within x0...x1. Handy for
|
# y that's proportionally within y0...y1 based on x within x0...x1. Handy for
|
||||||
# transforming a value in one range to a value in another (like Arduino's map
|
# transforming a value in one range to a value in another (like Arduino's map
|
||||||
# function).
|
# function).
|
||||||
|
|
||||||
|
|
||||||
def lerp(x, x0, x1, y0, y1):
|
def lerp(x, x0, x1, y0, y1):
|
||||||
return y0+(x-x0)*((y1-y0)/(x1-x0))
|
return y0 + (x - x0) * ((y1 - y0) / (x1 - x0))
|
||||||
|
|
||||||
|
|
||||||
# Main loop below will run forever:
|
# Main loop below will run forever:
|
||||||
while True:
|
while True:
|
||||||
|
|
@ -209,8 +218,8 @@ while True:
|
||||||
# out of phase so one occurs a little bit after the other.
|
# out of phase so one occurs a little bit after the other.
|
||||||
t0 = current % beat_period
|
t0 = current % beat_period
|
||||||
t1 = (current + beat_phase) % beat_period
|
t1 = (current + beat_phase) % beat_period
|
||||||
x0 = math.pow(math.e, -t0/beat_quarter_period)
|
x0 = math.pow(math.e, -t0 / beat_quarter_period)
|
||||||
x1 = math.pow(math.e, -t1/beat_quarter_period)
|
x1 = math.pow(math.e, -t1 / beat_quarter_period)
|
||||||
# After calculating both exponential decay values pick the biggest one
|
# After calculating both exponential decay values pick the biggest one
|
||||||
# as the secondary one will occur after the first. Scale each by
|
# as the secondary one will occur after the first. Scale each by
|
||||||
# the global brightness and then convert to RGB color using the fixed
|
# the global brightness and then convert to RGB color using the fixed
|
||||||
|
|
@ -225,7 +234,7 @@ while True:
|
||||||
# compute the hue with a smooth cycle over time.
|
# compute the hue with a smooth cycle over time.
|
||||||
# First use the sine function to smoothly generate a value that goes
|
# First use the sine function to smoothly generate a value that goes
|
||||||
# from -1.0 to 1.0 at a certain frequency to match the rainbow period.
|
# from -1.0 to 1.0 at a certain frequency to match the rainbow period.
|
||||||
x = math.sin(2.0*math.pi*rainbow_freq*current)
|
x = math.sin(2.0 * math.pi * rainbow_freq * current)
|
||||||
# Then compute the hue by converting the sine wave value from something
|
# Then compute the hue by converting the sine wave value from something
|
||||||
# that goes from -1.0 to 1.0 to instead go from 0 to 359 degrees.
|
# that goes from -1.0 to 1.0 to instead go from 0 to 359 degrees.
|
||||||
hue = lerp(x, -1.0, 1.0, 0.0, 359.0)
|
hue = lerp(x, -1.0, 1.0, 0.0, 359.0)
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
from digitalio import DigitalInOut, Direction
|
|
||||||
import board
|
|
||||||
import neopixel
|
|
||||||
import time
|
import time
|
||||||
try:
|
|
||||||
import urandom as random
|
|
||||||
except ImportError:
|
|
||||||
import random
|
|
||||||
|
|
||||||
|
import board
|
||||||
|
import neopixel
|
||||||
|
from digitalio import DigitalInOut, Direction
|
||||||
|
|
||||||
|
try:
|
||||||
|
import urandom as random
|
||||||
|
except ImportError:
|
||||||
|
import random
|
||||||
|
|
||||||
pixpin = board.D1
|
pixpin = board.D1
|
||||||
numpix = 16
|
numpix = 16
|
||||||
|
|
@ -17,74 +18,85 @@ led.direction = Direction.OUTPUT
|
||||||
strip = neopixel.NeoPixel(pixpin, numpix, brightness=.2, auto_write=True)
|
strip = neopixel.NeoPixel(pixpin, numpix, brightness=.2, auto_write=True)
|
||||||
|
|
||||||
colors = [
|
colors = [
|
||||||
[ 232, 100, 255 ], # Purple
|
[232, 100, 255], # Purple
|
||||||
[ 200, 200, 20 ], # Yellow
|
[200, 200, 20], # Yellow
|
||||||
[ 30, 200, 200 ], # Blue
|
[30, 200, 200], # Blue
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
# Fill the dots one after the other with a color
|
# Fill the dots one after the other with a color
|
||||||
|
|
||||||
|
|
||||||
def colorWipe(color, wait):
|
def colorWipe(color, wait):
|
||||||
for j in range(len(strip)):
|
for j in range(len(strip)):
|
||||||
strip[j] = (color)
|
strip[j] = (color)
|
||||||
time.sleep(wait)
|
time.sleep(wait)
|
||||||
|
|
||||||
|
|
||||||
def rainbow(wait):
|
def rainbow(wait):
|
||||||
for j in range(255):
|
for j in range(255):
|
||||||
for i in range(len(strip)):
|
for i in range(len(strip)):
|
||||||
idx = int (i+j)
|
idx = int(i + j)
|
||||||
strip[i] = wheel(idx & 255)
|
|
||||||
|
|
||||||
# Slightly different, this makes the rainbow equally distributed throughout
|
|
||||||
def rainbow_cycle(wait):
|
|
||||||
for j in range(255*5):
|
|
||||||
for i in range(len(strip)):
|
|
||||||
idx = int ((i * 256 / len(strip)) + j)
|
|
||||||
strip[i] = wheel(idx & 255)
|
strip[i] = wheel(idx & 255)
|
||||||
time.sleep(wait)
|
time.sleep(wait)
|
||||||
|
|
||||||
|
|
||||||
|
# Slightly different, this makes the rainbow equally distributed throughout
|
||||||
|
|
||||||
|
|
||||||
|
def rainbow_cycle(wait):
|
||||||
|
for j in range(255 * 5):
|
||||||
|
for i in range(len(strip)):
|
||||||
|
idx = int((i * 256 / len(strip)) + j)
|
||||||
|
strip[i] = wheel(idx & 255)
|
||||||
|
time.sleep(wait)
|
||||||
|
|
||||||
|
|
||||||
# Input a value 0 to 255 to get a color value.
|
# Input a value 0 to 255 to get a color value.
|
||||||
# The colours are a transition r - g - b - back to r.
|
# The colours are a transition r - g - b - back to r.
|
||||||
|
|
||||||
|
|
||||||
def wheel(pos):
|
def wheel(pos):
|
||||||
# Input a value 0 to 255 to get a color value.
|
# Input a value 0 to 255 to get a color value.
|
||||||
# The colours are a transition r - g - b - back to r.
|
# The colours are a transition r - g - b - back to r.
|
||||||
if (pos < 0) or (pos > 255):
|
if (pos < 0) or (pos > 255):
|
||||||
return (0, 0, 0)
|
return (0, 0, 0)
|
||||||
if (pos < 85):
|
if pos < 85:
|
||||||
return (int(pos * 3), int(255 - (pos*3)), 0)
|
return (int(pos * 3), int(255 - (pos * 3)), 0)
|
||||||
elif (pos < 170):
|
elif pos < 170:
|
||||||
pos -= 85
|
pos -= 85
|
||||||
return (int(255 - pos*3), 0, int(pos*3))
|
return (int(255 - pos * 3), 0, int(pos * 3))
|
||||||
else:
|
else:
|
||||||
pos -= 170
|
pos -= 170
|
||||||
return (0, int(pos*3), int(255 - pos*3))
|
return (0, int(pos * 3), int(255 - pos * 3))
|
||||||
|
|
||||||
|
|
||||||
def flash_random(wait,howmany):
|
def flash_random(wait, howmany):
|
||||||
|
for _ in range(howmany):
|
||||||
|
|
||||||
for k in range(howmany):
|
c = random.randint(0, len(colors) - 1) # Choose random color index
|
||||||
|
j = random.randint(0, numpix - 1) # Choose random pixel
|
||||||
|
strip[j] = colors[c] # Set pixel to color
|
||||||
|
|
||||||
c = random.randint(0, len(colors) - 1) # Choose random color index
|
for i in range(1, 5):
|
||||||
j = random.randint(0, numpix - 1) # Choose random pixel
|
strip.brightness = i / 5.0 # Ramp up brightness
|
||||||
strip[j] = colors[c] # Set pixel to color
|
time.sleep(wait)
|
||||||
|
|
||||||
for i in range(1, 5):
|
for i in range(5, 0, -1):
|
||||||
strip.brightness = i / 5.0 # Ramp up brightness
|
strip.brightness = i / 5.0 # Ramp down brightness
|
||||||
time.sleep(wait)
|
strip[j] = [0, 0, 0] # Set pixel to 'off'
|
||||||
|
time.sleep(wait)
|
||||||
|
|
||||||
for i in range(5, 0, -1):
|
|
||||||
strip.brightness = i / 5.0 # Ramp down brightness
|
|
||||||
strip[j] = [0,0,0] # Set pixel to 'off'
|
|
||||||
time.sleep(wait)
|
|
||||||
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
flash_random(.01, 8) # first number is 'wait' delay, shorter num == shorter twinkle
|
# first number is 'wait' delay, shorter num == shorter twinkle
|
||||||
flash_random(.01, 5) # second number is how many neopixels to simultaneously light up
|
flash_random(.01, 8)
|
||||||
|
# second number is how many neopixels to simultaneously light up
|
||||||
|
flash_random(.01, 5)
|
||||||
flash_random(.01, 11)
|
flash_random(.01, 11)
|
||||||
|
|
||||||
colorWipe( (232, 100, 255), .1 )
|
colorWipe((232, 100, 255), .1)
|
||||||
colorWipe( (200, 200, 20), .1 )
|
colorWipe((200, 200, 20), .1)
|
||||||
colorWipe( (30, 200, 200), .1)
|
colorWipe((30, 200, 200), .1)
|
||||||
|
|
||||||
rainbow_cycle(0.05)
|
rainbow_cycle(0.05)
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
import time
|
import time
|
||||||
import adafruit_sdcard
|
|
||||||
import adafruit_am2320
|
import adafruit_am2320
|
||||||
|
import adafruit_sdcard
|
||||||
|
import analogio
|
||||||
import board
|
import board
|
||||||
import busio
|
import busio
|
||||||
import analogio
|
|
||||||
import digitalio
|
import digitalio
|
||||||
import storage
|
import storage
|
||||||
|
|
||||||
|
|
@ -41,8 +42,10 @@ while True:
|
||||||
print("Humidity:", humidity)
|
print("Humidity:", humidity)
|
||||||
print("VBat voltage: {:.2f}".format(battery_voltage))
|
print("VBat voltage: {:.2f}".format(battery_voltage))
|
||||||
print()
|
print()
|
||||||
sdc.write("{}, {}, {}, {:.2f}\n".format(int(time_stamp), temperature,
|
sdc.write("{}, {}, {}, {:.2f}\n".format(
|
||||||
humidity, battery_voltage))
|
int(time_stamp), temperature,
|
||||||
|
humidity, battery_voltage)
|
||||||
|
)
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
except OSError:
|
except OSError:
|
||||||
pass
|
pass
|
||||||
|
|
|
||||||
|
|
@ -29,36 +29,38 @@ Explainatory comments are used verbatim from that code.
|
||||||
import math
|
import math
|
||||||
import random
|
import random
|
||||||
|
|
||||||
|
import adafruit_dotstar
|
||||||
|
import adafruit_lsm303
|
||||||
import board
|
import board
|
||||||
import busio
|
import busio
|
||||||
|
|
||||||
import adafruit_lsm303
|
N_GRAINS = 10 # Number of grains of sand
|
||||||
import adafruit_dotstar
|
WIDTH = 12 # Display width in pixels
|
||||||
|
HEIGHT = 6 # Display height in pixels
|
||||||
N_GRAINS = 10 # Number of grains of sand
|
|
||||||
WIDTH = 12 # Display width in pixels
|
|
||||||
HEIGHT = 6 # Display height in pixels
|
|
||||||
NUMBER_PIXELS = WIDTH * HEIGHT
|
NUMBER_PIXELS = WIDTH * HEIGHT
|
||||||
MAX_FPS = 45 # Maximum redraw rate, frames/second
|
MAX_FPS = 45 # Maximum redraw rate, frames/second
|
||||||
GRAIN_COLOR = (0, 0, 16)
|
GRAIN_COLOR = (0, 0, 16)
|
||||||
MAX_X = WIDTH * 256 - 1
|
MAX_X = WIDTH * 256 - 1
|
||||||
MAX_Y = HEIGHT * 256 - 1
|
MAX_Y = HEIGHT * 256 - 1
|
||||||
|
|
||||||
|
|
||||||
class Grain:
|
class Grain:
|
||||||
"""A simple struct to hold position and velocity information for a single grain."""
|
"""A simple struct to hold position and velocity information
|
||||||
|
for a single grain."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"""Initialize grain position and velocity."""
|
"""Initialize grain position and velocity."""
|
||||||
x = 0
|
self.x = 0
|
||||||
y = 0
|
self.y = 0
|
||||||
vx = 0
|
self.vx = 0
|
||||||
vy = 0
|
self.vy = 0
|
||||||
|
|
||||||
|
|
||||||
grains = [Grain() for _ in range(N_GRAINS)]
|
grains = [Grain() for _ in range(N_GRAINS)]
|
||||||
i2c = busio.I2C(board.SCL, board.SDA)
|
i2c = busio.I2C(board.SCL, board.SDA)
|
||||||
sensor = adafruit_lsm303.LSM303(i2c)
|
sensor = adafruit_lsm303.LSM303(i2c)
|
||||||
wing = adafruit_dotstar.DotStar(board.D13, board.D11, WIDTH * HEIGHT, 0.25, False)
|
wing = adafruit_dotstar.DotStar(
|
||||||
|
board.D13, board.D11, WIDTH * HEIGHT, 0.25, False)
|
||||||
|
|
||||||
oldidx = 0
|
oldidx = 0
|
||||||
newidx = 0
|
newidx = 0
|
||||||
|
|
@ -68,19 +70,23 @@ newy = 0
|
||||||
|
|
||||||
occupied_bits = [False for _ in range(WIDTH * HEIGHT)]
|
occupied_bits = [False for _ in range(WIDTH * HEIGHT)]
|
||||||
|
|
||||||
|
|
||||||
def index_of_xy(x, y):
|
def index_of_xy(x, y):
|
||||||
"""Convert an x/column and y/row into an index into a linear pixel array.
|
"""Convert an x/column and y/row into an index into
|
||||||
|
a linear pixel array.
|
||||||
|
|
||||||
:param int x: column value
|
:param int x: column value
|
||||||
:param int y: row value
|
:param int y: row value
|
||||||
"""
|
"""
|
||||||
return (y >> 8) * WIDTH + (x >> 8)
|
return (y >> 8) * WIDTH + (x >> 8)
|
||||||
|
|
||||||
|
|
||||||
def already_present(limit, x, y):
|
def already_present(limit, x, y):
|
||||||
"""Check if a pixel is already used.
|
"""Check if a pixel is already used.
|
||||||
|
|
||||||
:param int limit: the index into the grain array of the grain being assigned a pixel
|
:param int limit: the index into the grain array of
|
||||||
Only grains already allocated need to be checks against.
|
the grain being assigned a pixel Only grains already
|
||||||
|
allocated need to be checks against.
|
||||||
:param int x: proposed clumn value for the new grain
|
:param int x: proposed clumn value for the new grain
|
||||||
:param int y: proposed row valuse for the new grain
|
:param int y: proposed row valuse for the new grain
|
||||||
"""
|
"""
|
||||||
|
|
@ -89,6 +95,7 @@ def already_present(limit, x, y):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
for g in grains:
|
for g in grains:
|
||||||
placed = False
|
placed = False
|
||||||
while not placed:
|
while not placed:
|
||||||
|
|
@ -109,20 +116,20 @@ while True:
|
||||||
|
|
||||||
# Read accelerometer...
|
# Read accelerometer...
|
||||||
f_x, f_y, f_z = sensor.raw_acceleration
|
f_x, f_y, f_z = sensor.raw_acceleration
|
||||||
ax = f_x >> 8 # Transform accelerometer axes
|
ax = f_x >> 8 # Transform accelerometer axes
|
||||||
ay = f_y >> 8 # to grain coordinate space
|
ay = f_y >> 8 # to grain coordinate space
|
||||||
az = abs(f_z) >> 11 # Random motion factor
|
az = abs(f_z) >> 11 # Random motion factor
|
||||||
az = 1 if (az >= 3) else (4 - az) # Clip & invert
|
az = 1 if (az >= 3) else (4 - az) # Clip & invert
|
||||||
ax -= az # Subtract motion factor from X, Y
|
ax -= az # Subtract motion factor from X, Y
|
||||||
ay -= az
|
ay -= az
|
||||||
az2 = (az << 1) + 1 # Range of random motion to add back in
|
az2 = (az << 1) + 1 # Range of random motion to add back in
|
||||||
|
|
||||||
# ...and apply 2D accel vector to grain velocities...
|
# ...and apply 2D accel vector to grain velocities...
|
||||||
v2 = 0 # Velocity squared
|
v2 = 0 # Velocity squared
|
||||||
v = 0.0 # Absolute velociy
|
v = 0.0 # Absolute velociy
|
||||||
for g in grains:
|
for g in grains:
|
||||||
g.vx += ax + random.randint(0, az2) # A little randomness makes
|
g.vx += ax + random.randint(0, az2) # A little randomness makes
|
||||||
g.vy += ay + random.randint(0, az2) # tall stacks topple better!
|
g.vy += ay + random.randint(0, az2) # tall stacks topple better!
|
||||||
|
|
||||||
# Terminal velocity (in any direction) is 256 units -- equal to
|
# Terminal velocity (in any direction) is 256 units -- equal to
|
||||||
# 1 pixel -- which keeps moving grains from passing through each other
|
# 1 pixel -- which keeps moving grains from passing through each other
|
||||||
|
|
@ -131,10 +138,10 @@ while True:
|
||||||
# diagonal movement isn't faster
|
# diagonal movement isn't faster
|
||||||
|
|
||||||
v2 = g.vx * g.vx + g.vy * g.vy
|
v2 = g.vx * g.vx + g.vy * g.vy
|
||||||
if v2 > 65536: # If v^2 > 65536, then v > 256
|
if v2 > 65536: # If v^2 > 65536, then v > 256
|
||||||
v = math.floor(math.sqrt(v2)) # Velocity vector magnitude
|
v = math.floor(math.sqrt(v2)) # Velocity vector magnitude
|
||||||
g.vx = (g.vx // v) << 8 # Maintain heading
|
g.vx = (g.vx // v) << 8 # Maintain heading
|
||||||
g.vy = (g.vy // v) << 8 # Limit magnitude
|
g.vy = (g.vy // v) << 8 # Limit magnitude
|
||||||
|
|
||||||
# ...then update position of each grain, one at a time, checking for
|
# ...then update position of each grain, one at a time, checking for
|
||||||
# collisions and having them react. This really seems like it shouldn't
|
# collisions and having them react. This really seems like it shouldn't
|
||||||
|
|
@ -148,11 +155,11 @@ while True:
|
||||||
# the tiny 8-bit AVR microcontroller and my tiny dinosaur brain.)
|
# the tiny 8-bit AVR microcontroller and my tiny dinosaur brain.)
|
||||||
|
|
||||||
for g in grains:
|
for g in grains:
|
||||||
newx = g.x + g.vx # New position in grain space
|
newx = g.x + g.vx # New position in grain space
|
||||||
newy = g.y + g.vy
|
newy = g.y + g.vy
|
||||||
if newx > MAX_X: # If grain would go out of bounds
|
if newx > MAX_X: # If grain would go out of bounds
|
||||||
newx = MAX_X # keep it inside, and
|
newx = MAX_X # keep it inside, and
|
||||||
g.vx //= -2 # give a slight bounce off the wall
|
g.vx //= -2 # give a slight bounce off the wall
|
||||||
elif newx < 0:
|
elif newx < 0:
|
||||||
newx = 0
|
newx = 0
|
||||||
g.vx //= -2
|
g.vx //= -2
|
||||||
|
|
@ -163,56 +170,66 @@ while True:
|
||||||
newy = 0
|
newy = 0
|
||||||
g.vy //= -2
|
g.vy //= -2
|
||||||
|
|
||||||
oldidx = index_of_xy(g.x, g.y) # prior pixel
|
oldidx = index_of_xy(g.x, g.y) # prior pixel
|
||||||
newidx = index_of_xy(newx, newy) # new pixel
|
newidx = index_of_xy(newx, newy) # new pixel
|
||||||
if oldidx != newidx and occupied_bits[newidx]: # If grain is moving to a new pixel...
|
# If grain is moving to a new pixel...
|
||||||
# but if that pixel is already occupied...
|
if oldidx != newidx and occupied_bits[newidx]:
|
||||||
delta = abs(newidx - oldidx) # What direction when blocked?
|
# but if that pixel is already occupied...
|
||||||
if delta == 1: # 1 pixel left or right
|
# What direction when blocked?
|
||||||
newx = g.x # cancel x motion
|
delta = abs(newidx - oldidx)
|
||||||
g.vx //= -2 # and bounce X velocity (Y is ok)
|
if delta == 1: # 1 pixel left or right
|
||||||
newidx = oldidx # no pixel change
|
newx = g.x # cancel x motion
|
||||||
elif delta == WIDTH: # 1 pixel up or down
|
# and bounce X velocity (Y is ok)
|
||||||
newy = g.y # cancel Y motion
|
g.vx //= -2
|
||||||
g.vy //= -2 # and bounce Y velocity (X is ok)
|
newidx = oldidx # no pixel change
|
||||||
newidx = oldidx # no pixel change
|
elif delta == WIDTH: # 1 pixel up or down
|
||||||
else: # Diagonal intersection is more tricky...
|
newy = g.y # cancel Y motion
|
||||||
# Try skidding along just one axis of motion if possible (start w/
|
# and bounce Y velocity (X is ok)
|
||||||
# faster axis). Because we've already established that diagonal
|
g.vy //= -2
|
||||||
# (both-axis) motion is occurring, moving on either axis alone WILL
|
newidx = oldidx # no pixel change
|
||||||
# change the pixel index, no need to check that again.
|
else: # Diagonal intersection is more tricky...
|
||||||
if abs(g.vx) > abs(g.vy): # x axis is faster
|
# Try skidding along just one axis of motion if
|
||||||
|
# possible (start w/ faster axis). Because we've
|
||||||
|
# already established that diagonal (both-axis)
|
||||||
|
# motion is occurring, moving on either axis alone
|
||||||
|
# WILL change the pixel index, no need to check
|
||||||
|
# that again.
|
||||||
|
if abs(g.vx) > abs(g.vy): # x axis is faster
|
||||||
newidx = index_of_xy(newx, g.y)
|
newidx = index_of_xy(newx, g.y)
|
||||||
if not occupied_bits[newidx]: # that pixel is free, take it! But...
|
# that pixel is free, take it! But...
|
||||||
newy = g.y # cancel Y motion
|
if not occupied_bits[newidx]:
|
||||||
g.vy //= -2 # and bounce Y velocity
|
newy = g.y # cancel Y motion
|
||||||
else: # X pixel is taken, so try Y...
|
g.vy //= -2 # and bounce Y velocity
|
||||||
|
else: # X pixel is taken, so try Y...
|
||||||
newidx = index_of_xy(g.x, newy)
|
newidx = index_of_xy(g.x, newy)
|
||||||
if not occupied_bits[newidx]: # Pixel is free, take it, but first...
|
# Pixel is free, take it, but first...
|
||||||
newx = g.x # Cancel X motion
|
if not occupied_bits[newidx]:
|
||||||
g.vx //= -2 # Bounce X velocity
|
newx = g.x # Cancel X motion
|
||||||
else: # both spots are occupied
|
g.vx //= -2 # Bounce X velocity
|
||||||
newx = g.x # Cancel X & Y motion
|
else: # both spots are occupied
|
||||||
|
newx = g.x # Cancel X & Y motion
|
||||||
newy = g.y
|
newy = g.y
|
||||||
g.vx //= -2 # Bounce X & Y velocity
|
g.vx //= -2 # Bounce X & Y velocity
|
||||||
g.vy //= -2
|
g.vy //= -2
|
||||||
newidx = oldidx # Not moving
|
newidx = oldidx # Not moving
|
||||||
else: # y axis is faster. start there
|
else: # y axis is faster. start there
|
||||||
newidx = index_of_xy(g.x, newy)
|
newidx = index_of_xy(g.x, newy)
|
||||||
if not occupied_bits[newidx]: # Pixel's free! Take it! But...
|
# Pixel's free! Take it! But...
|
||||||
newx = g.x # Cancel X motion
|
if not occupied_bits[newidx]:
|
||||||
g.vx //= -2 # Bounce X velocity
|
newx = g.x # Cancel X motion
|
||||||
else: # Y pixel is taken, so try X...
|
g.vx //= -2 # Bounce X velocity
|
||||||
|
else: # Y pixel is taken, so try X...
|
||||||
newidx = index_of_xy(newx, g.y)
|
newidx = index_of_xy(newx, g.y)
|
||||||
if not occupied_bits[newidx]: # Pixel is free, take it, but first...
|
# Pixel is free, take it, but first...
|
||||||
newy = g.y # cancel Y motion
|
if not occupied_bits[newidx]:
|
||||||
g.vy //= -2 # and bounce Y velocity
|
newy = g.y # cancel Y motion
|
||||||
else: # both spots are occupied
|
g.vy //= -2 # and bounce Y velocity
|
||||||
newx = g.x # Cancel X & Y motion
|
else: # both spots are occupied
|
||||||
|
newx = g.x # Cancel X & Y motion
|
||||||
newy = g.y
|
newy = g.y
|
||||||
g.vx //= -2 # Bounce X & Y velocity
|
g.vx //= -2 # Bounce X & Y velocity
|
||||||
g.vy //= -2
|
g.vy //= -2
|
||||||
newidx = oldidx # Not moving
|
newidx = oldidx # Not moving
|
||||||
occupied_bits[oldidx] = False
|
occupied_bits[oldidx] = False
|
||||||
occupied_bits[newidx] = True
|
occupied_bits[newidx] = True
|
||||||
g.x = newx
|
g.x = newx
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,10 @@ Debounce an input pin.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import digitalio
|
import digitalio
|
||||||
|
|
||||||
|
|
||||||
class Debouncer(object):
|
class Debouncer(object):
|
||||||
"""Debounce an input pin"""
|
"""Debounce an input pin"""
|
||||||
|
|
||||||
|
|
@ -35,45 +37,43 @@ class Debouncer(object):
|
||||||
UNSTABLE_STATE = 0x02
|
UNSTABLE_STATE = 0x02
|
||||||
CHANGED_STATE = 0x04
|
CHANGED_STATE = 0x04
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, pin, mode=None, interval=0.010):
|
def __init__(self, pin, mode=None, interval=0.010):
|
||||||
"""Make am instance.
|
"""Make am instance.
|
||||||
:param int pin: the pin (from board) to debounce
|
:param int pin: the pin (from board) to debounce
|
||||||
:param int mode: digitalio.Pull.UP or .DOWN (default is no pull up/down)
|
:param int mode: digitalio.Pull.UP or .DOWN (default is no
|
||||||
:param int interval: bounce threshold in seconds (default is 0.010, i.e. 10 milliseconds)
|
pull up/down)
|
||||||
|
:param int interval: bounce threshold in seconds (default is 0.010,
|
||||||
|
i.e. 10 milliseconds)
|
||||||
"""
|
"""
|
||||||
self.state = 0x00
|
self.state = 0x00
|
||||||
self.pin = digitalio.DigitalInOut(pin)
|
self.pin = digitalio.DigitalInOut(pin)
|
||||||
self.pin.direction = digitalio.Direction.INPUT
|
self.pin.direction = digitalio.Direction.INPUT
|
||||||
if mode != None:
|
if mode is not None:
|
||||||
self.pin.pull = mode
|
self.pin.pull = mode
|
||||||
if self.pin.value:
|
if self.pin.value:
|
||||||
self.__set_state(Debouncer.DEBOUNCED_STATE | Debouncer.UNSTABLE_STATE)
|
self.__set_state(Debouncer.DEBOUNCED_STATE |
|
||||||
|
Debouncer.UNSTABLE_STATE)
|
||||||
self.previous_time = 0
|
self.previous_time = 0
|
||||||
if interval is None:
|
if interval is None:
|
||||||
self.interval = 0.010
|
self.interval = 0.010
|
||||||
else:
|
else:
|
||||||
self.interval = interval
|
self.interval = interval
|
||||||
|
|
||||||
|
|
||||||
def __set_state(self, bits):
|
def __set_state(self, bits):
|
||||||
self.state |= bits
|
self.state |= bits
|
||||||
|
|
||||||
|
|
||||||
def __unset_state(self, bits):
|
def __unset_state(self, bits):
|
||||||
self.state &= ~bits
|
self.state &= ~bits
|
||||||
|
|
||||||
|
|
||||||
def __toggle_state(self, bits):
|
def __toggle_state(self, bits):
|
||||||
self.state ^= bits
|
self.state ^= bits
|
||||||
|
|
||||||
|
|
||||||
def __get_state(self, bits):
|
def __get_state(self, bits):
|
||||||
return (self.state & bits) != 0
|
return (self.state & bits) != 0
|
||||||
|
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
"""Update the debouncer state. Must be called before using any of the properties below"""
|
"""Update the debouncer state. Must be called before using any of
|
||||||
|
the properties below"""
|
||||||
self.__unset_state(Debouncer.CHANGED_STATE)
|
self.__unset_state(Debouncer.CHANGED_STATE)
|
||||||
current_state = self.pin.value
|
current_state = self.pin.value
|
||||||
if current_state != self.__get_state(Debouncer.UNSTABLE_STATE):
|
if current_state != self.__get_state(Debouncer.UNSTABLE_STATE):
|
||||||
|
|
@ -81,25 +81,27 @@ class Debouncer(object):
|
||||||
self.__toggle_state(Debouncer.UNSTABLE_STATE)
|
self.__toggle_state(Debouncer.UNSTABLE_STATE)
|
||||||
else:
|
else:
|
||||||
if time.monotonic() - self.previous_time >= self.interval:
|
if time.monotonic() - self.previous_time >= self.interval:
|
||||||
if current_state != self.__get_state(Debouncer.DEBOUNCED_STATE):
|
debounced_state = self.__get_state(Debouncer.DEBOUNCED_STATE)
|
||||||
|
if current_state != debounced_state:
|
||||||
self.previous_time = time.monotonic()
|
self.previous_time = time.monotonic()
|
||||||
self.__toggle_state(Debouncer.DEBOUNCED_STATE)
|
self.__toggle_state(Debouncer.DEBOUNCED_STATE)
|
||||||
self.__set_state(Debouncer.CHANGED_STATE)
|
self.__set_state(Debouncer.CHANGED_STATE)
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def value(self):
|
def value(self):
|
||||||
"""Return the current debounced value of the input."""
|
"""Return the current debounced value of the input."""
|
||||||
return self.__get_state(Debouncer.DEBOUNCED_STATE)
|
return self.__get_state(Debouncer.DEBOUNCED_STATE)
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def rose(self):
|
def rose(self):
|
||||||
"""Return whether the debounced input went from low to high at the most recent update."""
|
"""Return whether the debounced input went from low to high at
|
||||||
return self.__get_state(self.DEBOUNCED_STATE) and self.__get_state(self.CHANGED_STATE)
|
the most recent update."""
|
||||||
|
return self.__get_state(self.DEBOUNCED_STATE) \
|
||||||
|
and self.__get_state(self.CHANGED_STATE)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def fell(self):
|
def fell(self):
|
||||||
"""Return whether the debounced input went from high to low at the most recent update."""
|
"""Return whether the debounced input went from high to low at
|
||||||
return (not self.__get_state(self.DEBOUNCED_STATE)) and self.__get_state(self.CHANGED_STATE)
|
the most recent update."""
|
||||||
|
return (not self.__get_state(self.DEBOUNCED_STATE)) \
|
||||||
|
and self.__get_state(self.CHANGED_STATE)
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ Manage a directory in the file system.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
class DirectoryNode(object):
|
class DirectoryNode(object):
|
||||||
"""Display and navigate the SD card contents"""
|
"""Display and navigate the SD card contents"""
|
||||||
|
|
||||||
|
|
@ -46,7 +47,6 @@ class DirectoryNode(object):
|
||||||
self.selected_offset = 0
|
self.selected_offset = 0
|
||||||
self.old_selected_offset = -1
|
self.old_selected_offset = -1
|
||||||
|
|
||||||
|
|
||||||
def __cleanup(self):
|
def __cleanup(self):
|
||||||
"""Dereference things for speedy gc."""
|
"""Dereference things for speedy gc."""
|
||||||
self.display = None
|
self.display = None
|
||||||
|
|
@ -55,7 +55,6 @@ class DirectoryNode(object):
|
||||||
self.files = None
|
self.files = None
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
def __is_dir(self, path):
|
def __is_dir(self, path):
|
||||||
"""Determine whether a path identifies a machine code bin file.
|
"""Determine whether a path identifies a machine code bin file.
|
||||||
:param string path: path of the file to check
|
:param string path: path of the file to check
|
||||||
|
|
@ -68,7 +67,6 @@ class DirectoryNode(object):
|
||||||
except OSError:
|
except OSError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def __sanitize(self, name):
|
def __sanitize(self, name):
|
||||||
"""Nondestructively strip off a trailing slash, if any, and return the result.
|
"""Nondestructively strip off a trailing slash, if any, and return the result.
|
||||||
:param string name: the filename
|
:param string name: the filename
|
||||||
|
|
@ -77,7 +75,6 @@ class DirectoryNode(object):
|
||||||
return name[:-1]
|
return name[:-1]
|
||||||
return name
|
return name
|
||||||
|
|
||||||
|
|
||||||
def __path(self):
|
def __path(self):
|
||||||
"""Return the result of recursively follow the parent links, building a full
|
"""Return the result of recursively follow the parent links, building a full
|
||||||
path to this directory."""
|
path to this directory."""
|
||||||
|
|
@ -85,24 +82,22 @@ class DirectoryNode(object):
|
||||||
return self.parent.__path() + os.sep + self.__sanitize(self.name)
|
return self.parent.__path() + os.sep + self.__sanitize(self.name)
|
||||||
return self.__sanitize(self.name)
|
return self.__sanitize(self.name)
|
||||||
|
|
||||||
|
|
||||||
def __make_path(self, filename):
|
def __make_path(self, filename):
|
||||||
"""Return a full path to the specified file in this directory.
|
"""Return a full path to the specified file in this directory.
|
||||||
:param string filename: the name of the file in this directory
|
:param string filename: the name of the file in this directory
|
||||||
"""
|
"""
|
||||||
return self.__path() + os.sep + filename
|
return self.__path() + os.sep + filename
|
||||||
|
|
||||||
|
|
||||||
def __number_of_files(self):
|
def __number_of_files(self):
|
||||||
"""The number of files in this directory, including the ".." for the parent
|
"""The number of files in this directory, including the ".." for the parent
|
||||||
directory if this isn't the top directory on the SD card."""
|
directory if this isn't the top directory on the SD card."""
|
||||||
self.__get_files()
|
self.__get_files()
|
||||||
return len(self.files)
|
return len(self.files)
|
||||||
|
|
||||||
|
|
||||||
def __get_files(self):
|
def __get_files(self):
|
||||||
"""Return a list of the files in this directory.
|
"""Return a list of the files in this directory.
|
||||||
If this is not the top directory on the SD card, a ".." entry is the first element.
|
If this is not the top directory on the SD card, a
|
||||||
|
".." entry is the first element.
|
||||||
Any directories have a slash appended to their name."""
|
Any directories have a slash appended to their name."""
|
||||||
if len(self.files) == 0:
|
if len(self.files) == 0:
|
||||||
self.files = os.listdir(self.__path())
|
self.files = os.listdir(self.__path())
|
||||||
|
|
@ -113,48 +108,48 @@ class DirectoryNode(object):
|
||||||
if self.__is_dir(self.__make_path(name)):
|
if self.__is_dir(self.__make_path(name)):
|
||||||
self.files[index] = name + "/"
|
self.files[index] = name + "/"
|
||||||
|
|
||||||
|
|
||||||
def __update_display(self):
|
def __update_display(self):
|
||||||
"""Update the displayed list of files if required."""
|
"""Update the displayed list of files if required."""
|
||||||
if self.top_offset != self.old_top_offset:
|
if self.top_offset != self.old_top_offset:
|
||||||
self.__get_files()
|
self.__get_files()
|
||||||
self.display.fill(0)
|
self.display.fill(0)
|
||||||
for i in range(self.top_offset, min(self.top_offset + 4, self.__number_of_files())):
|
min_offset = min(self.top_offset + 4, self.__number_of_files())
|
||||||
|
|
||||||
|
for i in range(self.top_offset, min_offset):
|
||||||
self.display.text(self.files[i], 10, (i - self.top_offset) * 8)
|
self.display.text(self.files[i], 10, (i - self.top_offset) * 8)
|
||||||
self.display.show()
|
self.display.show()
|
||||||
self.old_top_offset = self.top_offset
|
self.old_top_offset = self.top_offset
|
||||||
|
|
||||||
|
|
||||||
def __update_selection(self):
|
def __update_selection(self):
|
||||||
"""Update the selected file lighlight if required."""
|
"""Update the selected file lighlight if required."""
|
||||||
if self.selected_offset != self.old_selected_offset:
|
if self.selected_offset != self.old_selected_offset:
|
||||||
if self.old_selected_offset > -1:
|
if self.old_selected_offset > -1:
|
||||||
self.display.text(">", 0, (self.old_selected_offset - self.top_offset) * 8, 0)
|
old_offset = (self.old_selected_offset - self.top_offset) * 8
|
||||||
self.display.text(">", 0, (self.selected_offset - self.top_offset) * 8, 1)
|
|
||||||
|
self.display.text(">", 0, old_offset, 0)
|
||||||
|
|
||||||
|
new_offset = (self.selected_offset - self.top_offset) * 8
|
||||||
|
self.display.text(">", 0, new_offset, 1)
|
||||||
self.display.show()
|
self.display.show()
|
||||||
self.old_selected_offset = self.selected_offset
|
self.old_selected_offset = self.selected_offset
|
||||||
|
|
||||||
|
|
||||||
def __is_directory_name(self, filename):
|
def __is_directory_name(self, filename):
|
||||||
"""Is a filename the name of a directory.
|
"""Is a filename the name of a directory.
|
||||||
:param string filename: the name of the file
|
:param string filename: the name of the file
|
||||||
"""
|
"""
|
||||||
return filename[-1] == '/'
|
return filename[-1] == '/'
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def selected_filename(self):
|
def selected_filename(self):
|
||||||
"""The name of the currently selected file in this directory."""
|
"""The name of the currently selected file in this directory."""
|
||||||
self.__get_files()
|
self.__get_files()
|
||||||
return self.files[self.selected_offset]
|
return self.files[self.selected_offset]
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def selected_filepath(self):
|
def selected_filepath(self):
|
||||||
"""The full path of the currently selected file in this directory."""
|
"""The full path of the currently selected file in this directory."""
|
||||||
return self.__make_path(self.selected_filename)
|
return self.__make_path(self.selected_filename)
|
||||||
|
|
||||||
|
|
||||||
def force_update(self):
|
def force_update(self):
|
||||||
"""Force an update of the file list and selected file highlight."""
|
"""Force an update of the file list and selected file highlight."""
|
||||||
self.old_selected_offset = -1
|
self.old_selected_offset = -1
|
||||||
|
|
@ -162,10 +157,9 @@ class DirectoryNode(object):
|
||||||
self.__update_display()
|
self.__update_display()
|
||||||
self.__update_selection()
|
self.__update_selection()
|
||||||
|
|
||||||
|
|
||||||
def down(self):
|
def down(self):
|
||||||
"""Move down in the file list if possible, adjusting the selected file indicator
|
"""Move down in the file list if possible, adjusting the selected file
|
||||||
and scrolling the display as required."""
|
indicator and scrolling the display as required."""
|
||||||
if self.selected_offset < self.__number_of_files() - 1:
|
if self.selected_offset < self.__number_of_files() - 1:
|
||||||
self.selected_offset += 1
|
self.selected_offset += 1
|
||||||
if self.selected_offset == self.top_offset + 4:
|
if self.selected_offset == self.top_offset + 4:
|
||||||
|
|
@ -173,7 +167,6 @@ class DirectoryNode(object):
|
||||||
self.__update_display()
|
self.__update_display()
|
||||||
self.__update_selection()
|
self.__update_selection()
|
||||||
|
|
||||||
|
|
||||||
def up(self):
|
def up(self):
|
||||||
"""Move up in the file list if possible, adjusting the selected file indicator
|
"""Move up in the file list if possible, adjusting the selected file indicator
|
||||||
and scrolling the display as required."""
|
and scrolling the display as required."""
|
||||||
|
|
@ -184,10 +177,10 @@ class DirectoryNode(object):
|
||||||
self.__update_display()
|
self.__update_display()
|
||||||
self.__update_selection()
|
self.__update_selection()
|
||||||
|
|
||||||
|
|
||||||
def click(self):
|
def click(self):
|
||||||
"""Handle a selection and return the new current directory.
|
"""Handle a selection and return the new current directory.
|
||||||
If the selected file is the parent, i.e. "..", return to the parent directory.
|
If the selected file is the parent, i.e. "..", return to the parent
|
||||||
|
directory.
|
||||||
If the selected file is a directory, go into it."""
|
If the selected file is a directory, go into it."""
|
||||||
if self.selected_filename == "..":
|
if self.selected_filename == "..":
|
||||||
if self.parent:
|
if self.parent:
|
||||||
|
|
@ -196,7 +189,8 @@ class DirectoryNode(object):
|
||||||
self.__cleanup()
|
self.__cleanup()
|
||||||
return p
|
return p
|
||||||
elif self.__is_directory_name(self.selected_filename):
|
elif self.__is_directory_name(self.selected_filename):
|
||||||
new_node = DirectoryNode(self.display, self, self.selected_filename)
|
new_node = DirectoryNode(
|
||||||
|
self.display, self, self.selected_filename)
|
||||||
new_node.force_update()
|
new_node.force_update()
|
||||||
return new_node
|
return new_node
|
||||||
return self
|
return self
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,8 @@ THE SOFTWARE.
|
||||||
Manage the emulator hardware.
|
Manage the emulator hardware.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import digitalio
|
|
||||||
import adafruit_mcp230xx
|
import adafruit_mcp230xx
|
||||||
|
import digitalio
|
||||||
|
|
||||||
# control pin values
|
# control pin values
|
||||||
|
|
||||||
|
|
@ -57,7 +57,7 @@ class Emulator(object):
|
||||||
|
|
||||||
def __init__(self, i2c):
|
def __init__(self, i2c):
|
||||||
self.mcp = adafruit_mcp230xx.MCP23017(i2c)
|
self.mcp = adafruit_mcp230xx.MCP23017(i2c)
|
||||||
self.mcp.iodir = 0x0000 # Make all pins outputs
|
self.mcp.iodir = 0x0000 # Make all pins outputs
|
||||||
|
|
||||||
# Configure the individual control pins
|
# Configure the individual control pins
|
||||||
|
|
||||||
|
|
@ -85,47 +85,40 @@ class Emulator(object):
|
||||||
self.led_pin.direction = digitalio.Direction.OUTPUT
|
self.led_pin.direction = digitalio.Direction.OUTPUT
|
||||||
self.led_pin.value = False
|
self.led_pin.value = False
|
||||||
|
|
||||||
|
|
||||||
def __pulse_write(self):
|
def __pulse_write(self):
|
||||||
self.write_pin.value = WRITE_ENABLED
|
self.write_pin.value = WRITE_ENABLED
|
||||||
self.write_pin.value = WRITE_DISABLED
|
self.write_pin.value = WRITE_DISABLED
|
||||||
|
|
||||||
|
|
||||||
def __deactivate_ram(self):
|
def __deactivate_ram(self):
|
||||||
self.chip_select_pin.value = CHIP_DISABLED
|
self.chip_select_pin.value = CHIP_DISABLED
|
||||||
|
|
||||||
|
|
||||||
def __activate_ram(self):
|
def __activate_ram(self):
|
||||||
self.chip_select_pin.value = CHIP_ENABLED
|
self.chip_select_pin.value = CHIP_ENABLED
|
||||||
|
|
||||||
|
|
||||||
def __reset_address_counter(self):
|
def __reset_address_counter(self):
|
||||||
self.clock_reset_pin.value = RESET_ACTIVE
|
self.clock_reset_pin.value = RESET_ACTIVE
|
||||||
self.clock_reset_pin.value = RESET_INACTIVE
|
self.clock_reset_pin.value = RESET_INACTIVE
|
||||||
|
|
||||||
|
|
||||||
def __advance_address_counter(self):
|
def __advance_address_counter(self):
|
||||||
self.address_clock_pin.value = CLOCK_ACTIVE
|
self.address_clock_pin.value = CLOCK_ACTIVE
|
||||||
self.address_clock_pin.value = CLOCK_INACTIVE
|
self.address_clock_pin.value = CLOCK_INACTIVE
|
||||||
|
|
||||||
|
|
||||||
def __output_on_port_a(self, data_byte):
|
def __output_on_port_a(self, data_byte):
|
||||||
"""A hack to get around the limitation of the 23017 library to use 8-bit ports"""
|
"""A hack to get around the limitation of the 23017
|
||||||
|
library to use 8-bit ports"""
|
||||||
self.mcp.gpio = (self.mcp.gpio & 0xFF00) | (data_byte & 0x00FF)
|
self.mcp.gpio = (self.mcp.gpio & 0xFF00) | (data_byte & 0x00FF)
|
||||||
|
|
||||||
|
|
||||||
def enter_program_mode(self):
|
def enter_program_mode(self):
|
||||||
"""Enter program mode, allowing loading of the emulator RAM."""
|
"""Enter program mode, allowing loading of the emulator RAM."""
|
||||||
self.mode_pin.value = PROGRAMMER_USE
|
self.mode_pin.value = PROGRAMMER_USE
|
||||||
self.led_pin.value = LED_OFF
|
self.led_pin.value = LED_OFF
|
||||||
|
|
||||||
|
|
||||||
def enter_emulate_mode(self):
|
def enter_emulate_mode(self):
|
||||||
"""Enter emulate mode, giving control of the emulator ram to the host."""
|
"""Enter emulate mode, giving control of the emulator
|
||||||
|
ram to the host."""
|
||||||
self.mode_pin.value = EMULATE_USE
|
self.mode_pin.value = EMULATE_USE
|
||||||
self.led_pin.value = LED_ON
|
self.led_pin.value = LED_ON
|
||||||
|
|
||||||
|
|
||||||
def load_ram(self, code):
|
def load_ram(self, code):
|
||||||
"""Load the emulator RAM. Automatically switched to program mode.
|
"""Load the emulator RAM. Automatically switched to program mode.
|
||||||
:param [byte] code: the list of bytes to load into the emulator RAM
|
:param [byte] code: the list of bytes to load into the emulator RAM
|
||||||
|
|
|
||||||
|
|
@ -29,18 +29,17 @@ Targeted for the SAMD51 boards.
|
||||||
by Dave Astels
|
by Dave Astels
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import digitalio
|
import adafruit_sdcard
|
||||||
|
import adafruit_ssd1306
|
||||||
import board
|
import board
|
||||||
import busio
|
import busio
|
||||||
import adafruit_ssd1306
|
import digitalio
|
||||||
import storage
|
import storage
|
||||||
import adafruit_sdcard
|
from debouncer import Debouncer
|
||||||
|
|
||||||
from directory_node import DirectoryNode
|
from directory_node import DirectoryNode
|
||||||
from emulator import Emulator
|
from emulator import Emulator
|
||||||
from debouncer import Debouncer
|
|
||||||
|
|
||||||
#--------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------
|
||||||
# Initialize Rotary encoder
|
# Initialize Rotary encoder
|
||||||
|
|
||||||
# Encoder button is a digital input with pullup on D2
|
# Encoder button is a digital input with pullup on D2
|
||||||
|
|
@ -55,7 +54,7 @@ rot_b = digitalio.DigitalInOut(board.D3)
|
||||||
rot_b.direction = digitalio.Direction.INPUT
|
rot_b.direction = digitalio.Direction.INPUT
|
||||||
rot_b.pull = digitalio.Pull.UP
|
rot_b.pull = digitalio.Pull.UP
|
||||||
|
|
||||||
#--------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------
|
||||||
# Initialize I2C and OLED
|
# Initialize I2C and OLED
|
||||||
|
|
||||||
i2c = busio.I2C(board.SCL, board.SDA)
|
i2c = busio.I2C(board.SCL, board.SDA)
|
||||||
|
|
@ -65,12 +64,12 @@ oled.fill(0)
|
||||||
oled.text("Initializing SD", 0, 10)
|
oled.text("Initializing SD", 0, 10)
|
||||||
oled.show()
|
oled.show()
|
||||||
|
|
||||||
#--------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------
|
||||||
# Initialize SD card
|
# Initialize SD card
|
||||||
|
|
||||||
#SD_CS = board.D10
|
# SD_CS = board.D10
|
||||||
# Connect to the card and mount the filesystem.
|
# Connect to the card and mount the filesystem.
|
||||||
spi = busio.SPI(board.D13, board.D11, board.D12) # SCK, MOSI, MISO
|
spi = busio.SPI(board.D13, board.D11, board.D12) # SCK, MOSI, MISO
|
||||||
cs = digitalio.DigitalInOut(board.D10)
|
cs = digitalio.DigitalInOut(board.D10)
|
||||||
sdcard = adafruit_sdcard.SDCard(spi, cs)
|
sdcard = adafruit_sdcard.SDCard(spi, cs)
|
||||||
vfs = storage.VfsFat(sdcard)
|
vfs = storage.VfsFat(sdcard)
|
||||||
|
|
@ -80,8 +79,7 @@ oled.fill(0)
|
||||||
oled.text("Done", 0, 10)
|
oled.text("Done", 0, 10)
|
||||||
oled.show()
|
oled.show()
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------------
|
||||||
#--------------------------------------------------------------------------------
|
|
||||||
# Initialize globals
|
# Initialize globals
|
||||||
|
|
||||||
encoder_counter = 0
|
encoder_counter = 0
|
||||||
|
|
@ -101,7 +99,7 @@ current_mode = PROGRAM_MODE
|
||||||
emulator = Emulator(i2c)
|
emulator = Emulator(i2c)
|
||||||
|
|
||||||
|
|
||||||
#--------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------
|
||||||
# Helper functions
|
# Helper functions
|
||||||
|
|
||||||
def is_binary_name(filename):
|
def is_binary_name(filename):
|
||||||
|
|
@ -138,7 +136,7 @@ def program():
|
||||||
current_dir.force_update()
|
current_dir.force_update()
|
||||||
|
|
||||||
|
|
||||||
#--------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------
|
||||||
# Main loop
|
# Main loop
|
||||||
|
|
||||||
current_dir = DirectoryNode(oled, name="/sd")
|
current_dir = DirectoryNode(oled, name="/sd")
|
||||||
|
|
@ -196,7 +194,7 @@ while True:
|
||||||
rotary_prev_state = rotary_curr_state
|
rotary_prev_state = rotary_curr_state
|
||||||
|
|
||||||
# Handle encoder rotation
|
# Handle encoder rotation
|
||||||
if current_mode == PROGRAM_MODE: #Ignore rotation if in EMULATE mode
|
if current_mode == PROGRAM_MODE: # Ignore rotation if in EMULATE mode
|
||||||
if encoder_direction == -1:
|
if encoder_direction == -1:
|
||||||
current_dir.up()
|
current_dir.up()
|
||||||
elif encoder_direction == 1:
|
elif encoder_direction == 1:
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,13 @@
|
||||||
|
|
||||||
# Use a jumper wire from D2 to GND to prevent injection while programming!
|
# Use a jumper wire from D2 to GND to prevent injection while programming!
|
||||||
|
|
||||||
from digitalio import DigitalInOut, Direction, Pull
|
|
||||||
import board
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
import board
|
||||||
from adafruit_hid.keyboard import Keyboard
|
from adafruit_hid.keyboard import Keyboard
|
||||||
from adafruit_hid.keycode import Keycode
|
|
||||||
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
|
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
|
||||||
|
from adafruit_hid.keycode import Keycode
|
||||||
|
from digitalio import DigitalInOut, Direction, Pull
|
||||||
|
|
||||||
####################################################################
|
####################################################################
|
||||||
# Select the target operating system for payload:
|
# Select the target operating system for payload:
|
||||||
|
|
@ -53,7 +54,10 @@ led.value = True
|
||||||
# Wait a moment
|
# Wait a moment
|
||||||
pause = 0.25
|
pause = 0.25
|
||||||
|
|
||||||
|
|
||||||
# The functions that follow are the various payloads to deliver
|
# The functions that follow are the various payloads to deliver
|
||||||
|
|
||||||
|
|
||||||
def launch_terminal():
|
def launch_terminal():
|
||||||
if operating_system is 0:
|
if operating_system is 0:
|
||||||
led.value = False
|
led.value = False
|
||||||
|
|
@ -105,7 +109,8 @@ def launch_terminal():
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
|
|
||||||
led.value = False
|
led.value = False
|
||||||
layout.write("echo \'Try to be more careful what you put in your USB port.\'")
|
layout.write(
|
||||||
|
"echo \'Try to be more careful what you put in your USB port.\'")
|
||||||
time.sleep(pause)
|
time.sleep(pause)
|
||||||
kbd.press(Keycode.ENTER)
|
kbd.press(Keycode.ENTER)
|
||||||
kbd.release_all()
|
kbd.release_all()
|
||||||
|
|
@ -130,7 +135,7 @@ def launch_terminal():
|
||||||
time.sleep(pause)
|
time.sleep(pause)
|
||||||
|
|
||||||
# type a message a few times
|
# type a message a few times
|
||||||
for i in range(3):
|
for _ in range(3):
|
||||||
layout.write("HELLO FRIEND")
|
layout.write("HELLO FRIEND")
|
||||||
# time.sleep(pause)
|
# time.sleep(pause)
|
||||||
kbd.press(Keycode.ENTER)
|
kbd.press(Keycode.ENTER)
|
||||||
|
|
@ -138,19 +143,34 @@ def launch_terminal():
|
||||||
# time.sleep(pause)
|
# time.sleep(pause)
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
|
|
||||||
layout.write(" _ _ _____ _ _ ___ _____ ____ ___ _____ _ _ ____")
|
layout.write(
|
||||||
|
" _ _ _____ _ _ ___ "
|
||||||
|
"_____ ____ ___ _____ _ _ ____"
|
||||||
|
)
|
||||||
kbd.press(Keycode.ENTER)
|
kbd.press(Keycode.ENTER)
|
||||||
kbd.release_all()
|
kbd.release_all()
|
||||||
layout.write("| | | | ____| | | | / _ \ | ___| _ \|_ _| ____| \ | | _ \ ")
|
layout.write(
|
||||||
|
"| | | | ____| | | | / _ \ | "
|
||||||
|
" ___| _ \|_ _| ____| \ | | _ \ "
|
||||||
|
)
|
||||||
kbd.press(Keycode.ENTER)
|
kbd.press(Keycode.ENTER)
|
||||||
kbd.release_all()
|
kbd.release_all()
|
||||||
layout.write("| |_| | _| | | | | | | | | | |_ | |_) || || _| | \| | | | |")
|
layout.write(
|
||||||
|
"| |_| | _| | | | | | | | | | |"
|
||||||
|
"_ | |_) || || _| | \| | | | |"
|
||||||
|
)
|
||||||
kbd.press(Keycode.ENTER)
|
kbd.press(Keycode.ENTER)
|
||||||
kbd.release_all()
|
kbd.release_all()
|
||||||
layout.write("| _ | |___| |___| |__| |_| | | _| | _ < | || |___| |\ | |_| |")
|
layout.write(
|
||||||
|
"| _ | |___| |___| |__| |_| | | "
|
||||||
|
" _| | _ < | || |___| |\ | |_| |"
|
||||||
|
)
|
||||||
kbd.press(Keycode.ENTER)
|
kbd.press(Keycode.ENTER)
|
||||||
kbd.release_all()
|
kbd.release_all()
|
||||||
layout.write("|_| |_|_____|_____|_____\___/ |_| |_| \_\___|_____|_| \_|____/ ")
|
layout.write(
|
||||||
|
"|_| |_|_____|_____|_____\___/ |_"
|
||||||
|
"| |_| \_\___|_____|_| \_|____/ "
|
||||||
|
)
|
||||||
kbd.press(Keycode.ENTER)
|
kbd.press(Keycode.ENTER)
|
||||||
kbd.release_all()
|
kbd.release_all()
|
||||||
|
|
||||||
|
|
@ -159,6 +179,7 @@ def launch_terminal():
|
||||||
kbd.press(Keycode.ENTER)
|
kbd.press(Keycode.ENTER)
|
||||||
kbd.release_all()
|
kbd.release_all()
|
||||||
|
|
||||||
|
|
||||||
def download_image():
|
def download_image():
|
||||||
led.value = False
|
led.value = False
|
||||||
# run this after running 'launch_terminal'
|
# run this after running 'launch_terminal'
|
||||||
|
|
@ -178,7 +199,14 @@ def download_image():
|
||||||
|
|
||||||
# this says where to save image, and where to get it
|
# this says where to save image, and where to get it
|
||||||
led.value = False
|
led.value = False
|
||||||
layout.write('curl -o ~/Desktop/hackimage.jpg https://cdn-learn.adafruit.com/assets/assets/000/051/840/original/hacks_foulFowl.jpg')
|
|
||||||
|
url = (
|
||||||
|
'https://cdn-learn.adafruit.com/assets/assets/000/051/840/'
|
||||||
|
'original/hacks_foulFowl.jpg'
|
||||||
|
)
|
||||||
|
layout.write(
|
||||||
|
'curl -o ~/Desktop/hackimage.jpg {}'.format(url)
|
||||||
|
)
|
||||||
time.sleep(pause)
|
time.sleep(pause)
|
||||||
kbd.press(Keycode.ENTER)
|
kbd.press(Keycode.ENTER)
|
||||||
led.value = True
|
led.value = True
|
||||||
|
|
@ -200,7 +228,12 @@ def replace_background():
|
||||||
led.value = False
|
led.value = False
|
||||||
# run this after download_image (which ran after launch_terminal)
|
# run this after download_image (which ran after launch_terminal)
|
||||||
# it uses actionscript to change the background
|
# it uses actionscript to change the background
|
||||||
layout.write('osascript -e \'tell application \"System Events\" to set picture of every desktop to (POSIX path of (path to home folder) & \"/Desktop/hackimage.jpg\" as POSIX file as alias)\'')
|
layout.write(
|
||||||
|
'osascript -e \'tell application \"System Events\" '
|
||||||
|
'to set picture of every desktop to (POSIX path of '
|
||||||
|
'(path to home folder) & \"/Desktop/hackimage.jpg\" '
|
||||||
|
'as POSIX file as alias)\''
|
||||||
|
)
|
||||||
time.sleep(pause)
|
time.sleep(pause)
|
||||||
kbd.press(Keycode.ENTER)
|
kbd.press(Keycode.ENTER)
|
||||||
kbd.release_all()
|
kbd.release_all()
|
||||||
|
|
@ -216,6 +249,7 @@ def replace_background():
|
||||||
led.value = True
|
led.value = True
|
||||||
time.sleep(3) # give it a moment to refresh dock and BG
|
time.sleep(3) # give it a moment to refresh dock and BG
|
||||||
|
|
||||||
|
|
||||||
def hide_everything():
|
def hide_everything():
|
||||||
led.value = False
|
led.value = False
|
||||||
# print("Hiding stuff... ")
|
# print("Hiding stuff... ")
|
||||||
|
|
@ -224,6 +258,7 @@ def hide_everything():
|
||||||
time.sleep(10)
|
time.sleep(10)
|
||||||
kbd.release_all()
|
kbd.release_all()
|
||||||
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
# check for presence of jumper from GND to D2
|
# check for presence of jumper from GND to D2
|
||||||
if buttons[0].value is False and payload_delivered is 0:
|
if buttons[0].value is False and payload_delivered is 0:
|
||||||
|
|
@ -235,8 +270,7 @@ while True:
|
||||||
led.value = False
|
led.value = False
|
||||||
payload_delivered = 1
|
payload_delivered = 1
|
||||||
|
|
||||||
|
if buttons[0].value is True and payload_delivered is 0: # run it
|
||||||
if buttons[0].value is True and payload_delivered is 0: #run it
|
|
||||||
led.value = True
|
led.value = True
|
||||||
print("Release the water fowl!") # for debugging in screen or putty
|
print("Release the water fowl!") # for debugging in screen or putty
|
||||||
for i in range(10): # blink 5 times
|
for i in range(10): # blink 5 times
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,10 @@
|
||||||
# for Adafruit Circuit Playground express
|
# for Adafruit Circuit Playground express
|
||||||
# with CircuitPython
|
# with CircuitPython
|
||||||
|
|
||||||
from adafruit_circuitplayground.express import cpx
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
from adafruit_circuitplayground.express import cpx
|
||||||
|
|
||||||
# Change this number to adjust touch sensitivity threshold, 0 is default
|
# Change this number to adjust touch sensitivity threshold, 0 is default
|
||||||
cpx.adjust_touch_threshold(600)
|
cpx.adjust_touch_threshold(600)
|
||||||
|
|
||||||
|
|
@ -40,11 +41,12 @@ step_pixel = [9, 8, 7, 6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
|
||||||
# step colors
|
# step colors
|
||||||
step_col = [WHITE, RED, YELLOW, GREEN, AQUA, BLUE, PURPLE, BLACK]
|
step_col = [WHITE, RED, YELLOW, GREEN, AQUA, BLUE, PURPLE, BLACK]
|
||||||
|
|
||||||
def prog_mode(i):
|
|
||||||
cpx.play_file(audio_files[i])
|
def prog_mode(index):
|
||||||
step_note[step] = i
|
cpx.play_file(audio_files[index])
|
||||||
|
step_note[step] = index
|
||||||
cpx.pixels[step_pixel[step]] = step_col[step_note[step]]
|
cpx.pixels[step_pixel[step]] = step_col[step_note[step]]
|
||||||
print("playing file " + audio_files[i])
|
print("playing file " + audio_files[index])
|
||||||
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
|
|
||||||
|
|
@ -2,45 +2,48 @@
|
||||||
# uses two 16 NeoPixel rings (RGBW)
|
# uses two 16 NeoPixel rings (RGBW)
|
||||||
# connected to Gemma M0 powered by LiPo battery
|
# connected to Gemma M0 powered by LiPo battery
|
||||||
|
|
||||||
import board
|
|
||||||
import neopixel
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
pixpinLeft = board.D1 #Data In attached to Gemma pin D1
|
import board
|
||||||
pixpinRight = board.D0 #Data In attached to Gemma pin D0
|
import neopixel
|
||||||
|
|
||||||
|
pixpinLeft = board.D1 # Data In attached to Gemma pin D1
|
||||||
|
pixpinRight = board.D0 # Data In attached to Gemma pin D0
|
||||||
numpix = 16
|
numpix = 16
|
||||||
|
|
||||||
#uncomment the lines below for RGB NeoPixels
|
# uncomment the lines below for RGB NeoPixels
|
||||||
stripLeft = neopixel.NeoPixel(pixpinLeft, numpix, bpp=3, brightness=.18,
|
stripLeft = neopixel.NeoPixel(pixpinLeft, numpix, bpp=3, brightness=.18,
|
||||||
auto_write=False)
|
auto_write=False)
|
||||||
stripRight = neopixel.NeoPixel(pixpinRight, numpix, bpp=3, brightness=.18,
|
stripRight = neopixel.NeoPixel(pixpinRight, numpix, bpp=3, brightness=.18,
|
||||||
auto_write=False)
|
auto_write=False)
|
||||||
#Use these lines for RGBW NeoPixels
|
|
||||||
#stripLeft = neopixel.NeoPixel(pixpinLeft, numpix, bpp=4, brightness=.18,
|
|
||||||
# auto_write=False)
|
|
||||||
#stripRight = neopixel.NeoPixel(pixpinRight, numpix, bpp=4, brightness=.18,
|
|
||||||
# auto_write=False)
|
|
||||||
|
|
||||||
|
|
||||||
|
# Use these lines for RGBW NeoPixels
|
||||||
|
# stripLeft = neopixel.NeoPixel(pixpinLeft, numpix, bpp=4, brightness=.18,
|
||||||
|
# auto_write=False)
|
||||||
|
# stripRight = neopixel.NeoPixel(pixpinRight, numpix, bpp=4, brightness=.18,
|
||||||
|
# auto_write=False)
|
||||||
|
|
||||||
|
|
||||||
def cog(pos):
|
def cog(pos):
|
||||||
# Input a value 0 to 255 to get a color value.
|
# Input a value 0 to 255 to get a color value.
|
||||||
# Note: switch the commented lines below if using RGB vs. RGBW NeoPixles
|
# Note: switch the commented lines below if using RGB vs. RGBW NeoPixles
|
||||||
if (pos < 8) or (pos > 250):
|
if (pos < 8) or (pos > 250):
|
||||||
#return (120, 0, 0, 0) #first color, red: for RGBW NeoPixels
|
# return (120, 0, 0, 0) #first color, red: for RGBW NeoPixels
|
||||||
return (120, 0, 0) #first color, red: for RGB NeoPixels
|
return (120, 0, 0) # first color, red: for RGB NeoPixels
|
||||||
if (pos < 85):
|
if pos < 85:
|
||||||
return (int(pos * 3), int(255 - (pos*3)), 0)
|
return (int(pos * 3), int(255 - (pos * 3)), 0)
|
||||||
#return (125, 35, 0, 0) #second color, brass: for RGBW NeoPixels
|
# return (125, 35, 0, 0) #second color, brass: for RGBW NeoPixels
|
||||||
return (125, 35, 0) #second color, brass: for RGB NeoPixels
|
# return (125, 35, 0) # second color, brass: for RGB NeoPixels
|
||||||
elif (pos < 170):
|
elif pos < 170:
|
||||||
pos -= 85
|
pos -= 85
|
||||||
#return (int(255 - pos*3), 0, int(pos*3), 0)#: for RGBW NeoPixels
|
# return (int(255 - pos*3), 0, int(pos*3), 0)#: for RGBW NeoPixels
|
||||||
return (int(255 - pos*3), 0, int(pos*3))#: for RGB NeoPixels
|
return (int(255 - pos * 3), 0, int(pos * 3)) # : for RGB NeoPixels
|
||||||
else:
|
else:
|
||||||
pos -= 170
|
pos -= 170
|
||||||
#return (0, int(pos*3), int(255 - pos*3), 0)#: for RGBW NeoPixels
|
# return (0, int(pos*3), int(255 - pos*3), 0)#: for RGBW NeoPixels
|
||||||
return (0, int(pos*3), int(255 - pos*3))#: for RGB NeoPixels
|
return (0, int(pos * 3), int(255 - pos * 3)) # : for RGB NeoPixels
|
||||||
|
|
||||||
|
|
||||||
def brass_cycle(wait, patternL, patternR):
|
def brass_cycle(wait, patternL, patternR):
|
||||||
# patterns do different things, try:
|
# patterns do different things, try:
|
||||||
|
|
@ -53,14 +56,15 @@ def brass_cycle(wait, patternL, patternR):
|
||||||
# 256 quarter turn
|
# 256 quarter turn
|
||||||
for j in range(255):
|
for j in range(255):
|
||||||
for i in range(len(stripLeft)):
|
for i in range(len(stripLeft)):
|
||||||
idxL = int ((i * patternL / len(stripLeft)) + j)
|
idxL = int((i * patternL / len(stripLeft)) + j)
|
||||||
stripLeft[i] = cog(idxL & 64) #sets the second (brass) color
|
stripLeft[i] = cog(idxL & 64) # sets the second (brass) color
|
||||||
idxR = int ((i * patternR / len(stripRight)) + j)
|
idxR = int((i * patternR / len(stripRight)) + j)
|
||||||
stripRight[i] = cog(idxR & 64) #sets the second (brass) color
|
stripRight[i] = cog(idxR & 64) # sets the second (brass) color
|
||||||
stripLeft.show()
|
stripLeft.show()
|
||||||
stripRight.show()
|
stripRight.show()
|
||||||
time.sleep(wait)
|
time.sleep(wait)
|
||||||
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
brass_cycle(0.01, 256, 24) # brass color cycle with 1ms delay per step
|
brass_cycle(0.01, 256, 24) # brass color cycle with 1ms delay per step
|
||||||
# patternL, patternR
|
# patternL, patternR
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
# Gemma M0 Password Vault
|
# Gemma M0 Password Vault
|
||||||
# press cap touch pads to enter strong passwords over USB
|
# press cap touch pads to enter strong passwords over USB
|
||||||
|
|
||||||
from digitalio import DigitalInOut, Direction
|
|
||||||
import touchio
|
|
||||||
import board
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
import board
|
||||||
|
import touchio
|
||||||
from adafruit_hid.keyboard import Keyboard
|
from adafruit_hid.keyboard import Keyboard
|
||||||
from adafruit_hid.keycode import Keycode
|
|
||||||
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
|
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
|
||||||
|
from digitalio import DigitalInOut, Direction
|
||||||
|
|
||||||
led = DigitalInOut(board.D13)
|
led = DigitalInOut(board.D13)
|
||||||
led.direction = Direction.OUTPUT
|
led.direction = Direction.OUTPUT
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,12 @@
|
||||||
# for fine tuning Software Defined Radio CubicSDR software
|
# for fine tuning Software Defined Radio CubicSDR software
|
||||||
# 10k pot hooked to 3v, A2, and D2 acting as GND
|
# 10k pot hooked to 3v, A2, and D2 acting as GND
|
||||||
|
|
||||||
from analogio import AnalogIn
|
|
||||||
import board
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
import board
|
||||||
from adafruit_hid.keyboard import Keyboard
|
from adafruit_hid.keyboard import Keyboard
|
||||||
from adafruit_hid.keycode import Keycode
|
from adafruit_hid.keycode import Keycode
|
||||||
|
from analogio import AnalogIn
|
||||||
from digitalio import DigitalInOut, Direction
|
from digitalio import DigitalInOut, Direction
|
||||||
|
|
||||||
d2_ground = DigitalInOut(board.D2)
|
d2_ground = DigitalInOut(board.D2)
|
||||||
|
|
@ -22,12 +23,15 @@ pot_min = 0.00
|
||||||
step = (pot_max - pot_min) / 10.0
|
step = (pot_max - pot_min) / 10.0
|
||||||
last_knob = 0
|
last_knob = 0
|
||||||
|
|
||||||
|
|
||||||
def steps(x):
|
def steps(x):
|
||||||
return round((x - pot_min) / step)
|
return round((x - pot_min) / step)
|
||||||
|
|
||||||
|
|
||||||
def getVoltage(pin):
|
def getVoltage(pin):
|
||||||
return (pin.value * 3.3) / 65536
|
return (pin.value * 3.3) / 65536
|
||||||
|
|
||||||
|
|
||||||
def spamKey(code):
|
def spamKey(code):
|
||||||
knobkeys = [Keycode.RIGHT_BRACKET, Keycode.RIGHT_BRACKET,
|
knobkeys = [Keycode.RIGHT_BRACKET, Keycode.RIGHT_BRACKET,
|
||||||
Keycode.RIGHT_BRACKET, Keycode.RIGHT_BRACKET,
|
Keycode.RIGHT_BRACKET, Keycode.RIGHT_BRACKET,
|
||||||
|
|
@ -35,16 +39,18 @@ def spamKey(code):
|
||||||
Keycode.LEFT_BRACKET, Keycode.LEFT_BRACKET,
|
Keycode.LEFT_BRACKET, Keycode.LEFT_BRACKET,
|
||||||
Keycode.LEFT_BRACKET, Keycode.LEFT_BRACKET,
|
Keycode.LEFT_BRACKET, Keycode.LEFT_BRACKET,
|
||||||
Keycode.LEFT_BRACKET]
|
Keycode.LEFT_BRACKET]
|
||||||
spamRate = [0.01, 0.05, 0.125, 0.25, 0.5, 0.5, 0.5, 0.25, 0.125, 0.05, 0.01]
|
spamRate = [0.01, 0.05, 0.125, 0.25, 0.5,
|
||||||
|
0.5, 0.5, 0.25, 0.125, 0.05, 0.01]
|
||||||
kbd = Keyboard()
|
kbd = Keyboard()
|
||||||
kbd.press(knobkeys[code]) # which keycode is entered
|
kbd.press(knobkeys[code]) # which keycode is entered
|
||||||
kbd.release_all()
|
kbd.release_all()
|
||||||
time.sleep(spamRate[code]) # how fast the key is spammed
|
time.sleep(spamRate[code]) # how fast the key is spammed
|
||||||
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
knob = (getVoltage(analog2in))
|
knob = (getVoltage(analog2in))
|
||||||
if steps(knob) is 5: # the center position is active
|
if steps(knob) == 5: # the center position is active
|
||||||
led.value = True
|
led.value = True
|
||||||
elif steps(knob) is not 5:
|
elif steps(knob) != 5:
|
||||||
led.value = False
|
led.value = False
|
||||||
spamKey(steps(knob))
|
spamKey(steps(knob))
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,29 @@
|
||||||
# Motion Sensor Alarm
|
# Motion Sensor Alarm
|
||||||
# uses Gemma M0, vibration sensor on A0/GND, & piezo on D0/GND
|
# uses Gemma M0, vibration sensor on A0/GND, & piezo on D0/GND
|
||||||
|
import time
|
||||||
import pulseio
|
import pulseio
|
||||||
from digitalio import DigitalInOut, Direction, Pull
|
|
||||||
from analogio import AnalogIn
|
from analogio import AnalogIn
|
||||||
import board
|
import board
|
||||||
import time
|
|
||||||
|
|
||||||
piezo = pulseio.PWMOut(board.D0, duty_cycle=0, frequency=440,
|
piezo = pulseio.PWMOut(board.D0, duty_cycle=0, frequency=440,
|
||||||
variable_frequency=True)
|
variable_frequency=True)
|
||||||
|
|
||||||
vibrationPin = AnalogIn(board.A0)
|
vibrationPin = AnalogIn(board.A0)
|
||||||
|
|
||||||
|
|
||||||
def get_voltage(pin):
|
def get_voltage(pin):
|
||||||
return (pin.value * 3.3) / 65536
|
return (pin.value * 3.3) / 65536
|
||||||
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
print((get_voltage(vibrationPin),))
|
print((get_voltage(vibrationPin),))
|
||||||
vibration = get_voltage(vibrationPin)
|
vibration = get_voltage(vibrationPin)
|
||||||
|
|
||||||
if vibration < 1: # the sensor has been tripped, you can adjust this value
|
if vibration < 1: # the sensor has been tripped, you can adjust this value
|
||||||
# for sensitivity
|
# for sensitivity
|
||||||
for f in (2620, 4400, 2620, 4400, 2620, 4400, 2620, 4400):
|
for f in (2620, 4400, 2620, 4400, 2620, 4400, 2620, 4400):
|
||||||
piezo.frequency = f
|
piezo.frequency = f
|
||||||
piezo.duty_cycle = 65536//2 # on 50%
|
piezo.duty_cycle = 65536 // 2 # on 50%
|
||||||
time.sleep(0.2) # on 1/5 second
|
time.sleep(0.2) # on 1/5 second
|
||||||
piezo.duty_cycle = 0 # off
|
piezo.duty_cycle = 0 # off
|
||||||
time.sleep(0.02) # pause
|
time.sleep(0.02) # pause
|
||||||
|
|
|
||||||
|
|
@ -1,47 +1,50 @@
|
||||||
|
import time
|
||||||
|
|
||||||
import board
|
import board
|
||||||
import neopixel
|
import neopixel
|
||||||
import time
|
|
||||||
try:
|
try:
|
||||||
import urandom as random # for v1.0 API support
|
import urandom as random # for v1.0 API support
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import random
|
import random
|
||||||
|
|
||||||
numpix = 36 # Number of NeoPixels
|
numpix = 36 # Number of NeoPixels
|
||||||
pixpin = board.D1 # Pin where NeoPixels are connected
|
pixpin = board.D1 # Pin where NeoPixels are connected
|
||||||
strip = neopixel.NeoPixel(pixpin, numpix, brightness=1.0)
|
strip = neopixel.NeoPixel(pixpin, numpix, brightness=1.0)
|
||||||
|
|
||||||
mode = 0 # Current animation effect
|
mode = 0 # Current animation effect
|
||||||
offset = 0 # Position of spinner animation
|
offset = 0 # Position of spinner animation
|
||||||
color = [160, 0, 160] # RGB color - purple
|
color = [160, 0, 160] # RGB color - purple
|
||||||
prevtime = time.monotonic() # Time of last animation mode switch
|
prevtime = time.monotonic() # Time of last animation mode switch
|
||||||
|
|
||||||
while True: # Loop forever...
|
while True: # Loop forever...
|
||||||
|
|
||||||
if mode == 0: # Random sparkles - lights just one LED at a time
|
if mode == 0: # Random sparkles - lights just one LED at a time
|
||||||
i = random.randint(0, numpix - 1) # Choose random pixel
|
i = random.randint(0, numpix - 1) # Choose random pixel
|
||||||
strip[i] = color # Set it to current color
|
strip[i] = color # Set it to current color
|
||||||
strip.write() # Refresh LED states
|
strip.write() # Refresh LED states
|
||||||
# Set same pixel to "off" color now but DON'T refresh...
|
# Set same pixel to "off" color now but DON'T refresh...
|
||||||
# it stays on for now...bot this and the next random
|
# it stays on for now...bot this and the next random
|
||||||
# pixel will be refreshed on the next pass.
|
# pixel will be refreshed on the next pass.
|
||||||
strip[i] = [0,0,0]
|
strip[i] = [0, 0, 0]
|
||||||
time.sleep(0.008) # 8 millisecond delay
|
time.sleep(0.008) # 8 millisecond delay
|
||||||
elif mode == 1: # Spinny wheel (4 LEDs on at a time)
|
elif mode == 1: # Spinny wheel (4 LEDs on at a time)
|
||||||
for i in range(numpix): # For each LED...
|
for i in range(numpix): # For each LED...
|
||||||
if ((offset + i) & 7) < 2: # 2 pixels out of 8...
|
if ((offset + i) & 7) < 2: # 2 pixels out of 8...
|
||||||
strip[i] = color # are set to current color
|
strip[i] = color # are set to current color
|
||||||
else:
|
else:
|
||||||
strip[i] = [0,0,0] # other pixels are off
|
strip[i] = [0, 0, 0] # other pixels are off
|
||||||
strip.write() # Refresh LED states
|
strip.write() # Refresh LED states
|
||||||
time.sleep(0.08) # 80 millisecond delay
|
time.sleep(0.08) # 80 millisecond delay
|
||||||
offset += 1 # Shift animation by 1 pixel on next frame
|
offset += 1 # Shift animation by 1 pixel on next frame
|
||||||
if offset >= 8: offset = 0
|
if offset >= 8:
|
||||||
# Additional animation modes could be added here!
|
offset = 0
|
||||||
|
# Additional animation modes could be added here!
|
||||||
|
|
||||||
t = time.monotonic() # Current time in seconds
|
t = time.monotonic() # Current time in seconds
|
||||||
if (t - prevtime) >= 8: # Every 8 seconds...
|
if (t - prevtime) >= 8: # Every 8 seconds...
|
||||||
mode += 1 # Advance to next mode
|
mode += 1 # Advance to next mode
|
||||||
if mode > 1: # End of modes?
|
if mode > 1: # End of modes?
|
||||||
mode = 0 # Start over from beginning
|
mode = 0 # Start over from beginning
|
||||||
strip.fill([0,0,0]) # Turn off all pixels
|
strip.fill([0, 0, 0]) # Turn off all pixels
|
||||||
prevtime = t # Record time of last mode change
|
prevtime = t # Record time of last mode change
|
||||||
|
|
|
||||||
|
|
@ -1,180 +1,186 @@
|
||||||
# Gemma "Firewalker Lite" sneakers
|
# Gemma "Firewalker Lite" sneakers
|
||||||
# - Uses the following Adafruit parts (X2 for two shoes):
|
# - Uses the following Adafruit parts (X2 for two shoes):
|
||||||
# * Gemma M0 3V microcontroller (#3501)
|
# * Gemma M0 3V microcontroller (#3501)
|
||||||
# * 150 mAh LiPoly battery (#1317) or larger
|
# * 150 mAh LiPoly battery (#1317) or larger
|
||||||
# * Medium vibration sensor switch (#2384)
|
# * Medium vibration sensor switch (#2384)
|
||||||
# * 60/m NeoPixel RGB LED strip (#1138 or #1461)
|
# * 60/m NeoPixel RGB LED strip (#1138 or #1461)
|
||||||
# * LiPoly charger such as #1304
|
# * LiPoly charger such as #1304
|
||||||
#
|
#
|
||||||
# - originally written by Phil Burgess for Gemma using Arduino
|
# - originally written by Phil Burgess for Gemma using Arduino
|
||||||
# * https://learn.adafruit.com/gemma-led-sneakers
|
# * https://learn.adafruit.com/gemma-led-sneakers
|
||||||
|
|
||||||
import board
|
import board
|
||||||
|
import digitalio
|
||||||
import neopixel
|
import neopixel
|
||||||
import time
|
|
||||||
import digitalio
|
|
||||||
try:
|
try:
|
||||||
import urandom as random
|
import urandom as random
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import random
|
import random
|
||||||
|
|
||||||
# Declare a NeoPixel object on led_pin with num_leds as pixels
|
# Declare a NeoPixel object on led_pin with num_leds as pixels
|
||||||
# No auto-write.
|
# No auto-write.
|
||||||
led_pin = board.D1 # Which pin your pixels are connected to
|
led_pin = board.D1 # Which pin your pixels are connected to
|
||||||
num_leds = 40 # How many LEDs you have
|
num_leds = 40 # How many LEDs you have
|
||||||
circumference = 40 # Shoe circumference, in pixels, may be > NUM_LEDS
|
circumference = 40 # Shoe circumference, in pixels, may be > NUM_LEDS
|
||||||
frames_per_second = 50 # Animation frames per second
|
frames_per_second = 50 # Animation frames per second
|
||||||
brightness = 0 # Current wave height
|
brightness = 0 # Current wave height
|
||||||
strip = neopixel.NeoPixel(led_pin, num_leds, brightness=1, auto_write=False)
|
strip = neopixel.NeoPixel(led_pin, num_leds, brightness=1, auto_write=False)
|
||||||
offset = 0
|
offset = 0
|
||||||
|
|
||||||
# vibration sensor
|
# vibration sensor
|
||||||
motion_pin = board.D0 # Pin where vibration switch is connected
|
motion_pin = board.D0 # Pin where vibration switch is connected
|
||||||
pin = digitalio.DigitalInOut(motion_pin)
|
pin = digitalio.DigitalInOut(motion_pin)
|
||||||
pin.direction = digitalio.Direction.INPUT
|
pin.direction = digitalio.Direction.INPUT
|
||||||
pin.pull = digitalio.Pull.UP
|
pin.pull = digitalio.Pull.UP
|
||||||
ramping_up = False
|
ramping_up = False
|
||||||
|
|
||||||
center = 0 # Center point of wave in fixed-point space (0 - 255)
|
center = 0 # Center point of wave in fixed-point space (0 - 255)
|
||||||
speed = 1 # Distance to move between frames (-128 - +127)
|
speed = 1 # Distance to move between frames (-128 - +127)
|
||||||
width = 2 # Width from peak to bottom of triangle wave (0 - 128)
|
width = 2 # Width from peak to bottom of triangle wave (0 - 128)
|
||||||
hue = 3 # Current wave hue (color) see comments later
|
hue = 3 # Current wave hue (color) see comments later
|
||||||
hue_target = 4 # Final hue we're aiming for
|
hue_target = 4 # Final hue we're aiming for
|
||||||
red = 5 # LED RGB color calculated from hue
|
red = 5 # LED RGB color calculated from hue
|
||||||
green = 6 # LED RGB color calculated from hue
|
green = 6 # LED RGB color calculated from hue
|
||||||
blue = 7 # LED RGB color calculated from hue
|
blue = 7 # LED RGB color calculated from hue
|
||||||
|
|
||||||
y = 0
|
y = 0
|
||||||
brightness = 0
|
brightness = 0
|
||||||
count = 0
|
count = 0
|
||||||
|
|
||||||
# Gemma can animate 3 of these on 40 LEDs at 50 FPS
|
# Gemma can animate 3 of these on 40 LEDs at 50 FPS
|
||||||
# More LEDs and/or more waves will need lower
|
# More LEDs and/or more waves will need lower
|
||||||
wave = [0] * 8, [0] * 8, [0] * 8
|
wave = [0] * 8, [0] * 8, [0] * 8
|
||||||
|
|
||||||
# Note that the speeds of each wave are different prime numbers.
|
# Note that the speeds of each wave are different prime numbers.
|
||||||
# This avoids repetition as the waves move around the
|
# This avoids repetition as the waves move around the
|
||||||
# perimeter...if they were even numbers or multiples of each
|
# perimeter...if they were even numbers or multiples of each
|
||||||
# other, there'd be obvious repetition in the pattern of motion...
|
# other, there'd be obvious repetition in the pattern of motion...
|
||||||
# beat frequencies.
|
# beat frequencies.
|
||||||
n_waves = len(wave)
|
n_waves = len(wave)
|
||||||
|
|
||||||
# 90 distinct hues (0-89) around color wheel
|
# 90 distinct hues (0-89) around color wheel
|
||||||
hue_table = [ 255, 255, 255, 255, 255, 255, 255, 255, 237, 203,
|
hue_table = [255, 255, 255, 255, 255, 255, 255, 255, 237, 203,
|
||||||
169, 135, 101, 67, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
169, 135, 101, 67, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 18, 52, 86, 120, 154, 188, 222,
|
0, 0, 0, 0, 0, 0, 18, 52, 86, 120, 154, 188, 222,
|
||||||
255, 255, 255, 255, 255, 255, 255, 255 ]
|
255, 255, 255, 255, 255, 255, 255, 255]
|
||||||
|
|
||||||
# Gamma-correction table
|
# Gamma-correction table
|
||||||
gammas = [
|
gammas = [
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
|
||||||
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
|
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
|
||||||
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
|
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
|
||||||
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
|
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
|
||||||
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
|
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
|
||||||
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
|
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
|
||||||
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
|
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
|
||||||
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
|
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
|
||||||
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
|
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
|
||||||
90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,
|
90, 92, 93, 95, 96, 98, 99, 101, 102, 104, 105, 107, 109, 110,
|
||||||
115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
|
112, 114, 115, 117, 119, 120, 122, 124, 126, 127, 129, 131, 133,
|
||||||
144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
|
135, 137, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158,
|
||||||
177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
|
160, 162, 164, 167, 169, 171, 173, 175, 177, 180, 182, 184, 186,
|
||||||
215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 ]
|
189, 191, 193, 196, 198, 200, 203, 205, 208, 210, 213, 215, 218,
|
||||||
|
220, 223, 225, 228, 231, 233, 236, 239, 241, 244, 247, 249, 252,
|
||||||
|
255
|
||||||
|
]
|
||||||
|
|
||||||
def h2rgb(hue):
|
|
||||||
# return value
|
|
||||||
ret = 0
|
|
||||||
|
|
||||||
hue %= 90
|
def h2rgb(colour_hue):
|
||||||
h = hue_table[hue >> 1]
|
colour_hue %= 90
|
||||||
|
h = hue_table[colour_hue >> 1]
|
||||||
|
|
||||||
if ( hue & 1 ):
|
if colour_hue & 1:
|
||||||
ret = h & 15
|
ret = h & 15
|
||||||
else:
|
else:
|
||||||
ret = ( h >> 4 )
|
ret = (h >> 4)
|
||||||
|
|
||||||
return ( ret * 17 )
|
return ret * 17
|
||||||
|
|
||||||
|
|
||||||
def wave_setup():
|
def wave_setup():
|
||||||
global wave
|
global wave
|
||||||
|
|
||||||
wave = [ [ 0, 3, 60, 0, 0, 0, 0, 0 ],
|
wave = [[0, 3, 60, 0, 0, 0, 0, 0],
|
||||||
[ 0, -5, 45, 0, 0, 0, 0, 0 ],
|
[0, -5, 45, 0, 0, 0, 0, 0],
|
||||||
[ 0, 7, 30, 0, 0, 0, 0, 0 ] ]
|
[0, 7, 30, 0, 0, 0, 0, 0]]
|
||||||
|
|
||||||
# assign random starting colors to waves
|
# assign random starting colors to waves
|
||||||
for w in range(n_waves):
|
for wave_index in range(n_waves):
|
||||||
wave[w][hue] = wave[w][hue_target] = 90 + random.randint(0,90)
|
current_wave = wave[wave_index]
|
||||||
wave[w][red] = h2rgb(wave[w][hue] - 30)
|
random_offset = random.randint(0, 90)
|
||||||
wave[w][green] = h2rgb(wave[w][hue])
|
|
||||||
wave[w][blue] = h2rgb(wave[w][hue] + 30)
|
current_wave[hue] = current_wave[hue_target] = 90 + random_offset
|
||||||
|
current_wave[red] = h2rgb(current_wave[hue] - 30)
|
||||||
|
current_wave[green] = h2rgb(current_wave[hue])
|
||||||
|
current_wave[blue] = h2rgb(current_wave[hue] + 30)
|
||||||
|
|
||||||
|
|
||||||
def vibration_detector():
|
def vibration_detector():
|
||||||
while ( True ):
|
while True:
|
||||||
if not pin.value:
|
if not pin.value:
|
||||||
return(True)
|
return True
|
||||||
|
|
||||||
while ( True ) :
|
|
||||||
|
while True:
|
||||||
|
|
||||||
# wait for vibration sensor to trigger
|
# wait for vibration sensor to trigger
|
||||||
if ( ramping_up == False ):
|
if not ramping_up:
|
||||||
ramping_up = vibration_detector()
|
ramping_up = vibration_detector()
|
||||||
wave_setup()
|
wave_setup()
|
||||||
|
|
||||||
# But it's not just a straight shot that it ramps up.
|
# But it's not just a straight shot that it ramps up.
|
||||||
# This is a low-pass filter...it makes the brightness
|
# This is a low-pass filter...it makes the brightness
|
||||||
# value decelerate as it approaches a target (200 in
|
# value decelerate as it approaches a target (200 in
|
||||||
# this case). 207 is used here because integers round
|
# this case). 207 is used here because integers round
|
||||||
# down on division and we'd never reach the target;
|
# down on division and we'd never reach the target;
|
||||||
# it's an ersatz ceil() function: ((199*7)+200+7)/8 = 200;
|
# it's an ersatz ceil() function: ((199*7)+200+7)/8 = 200;
|
||||||
brightness = int( ((brightness * 7) + 207) / 8 )
|
brightness = int(((brightness * 7) + 207) / 8)
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
if ( count == ( circumference + num_leds + 5) ):
|
if count == (circumference + num_leds + 5):
|
||||||
ramping_up = False
|
ramping_up = False
|
||||||
count = 0
|
count = 0
|
||||||
|
|
||||||
# Wave positions and colors are updated...
|
# Wave positions and colors are updated...
|
||||||
for w in range(n_waves):
|
for w in range(n_waves):
|
||||||
# Move wave; wraps around ends, is OK!
|
# Move wave; wraps around ends, is OK!
|
||||||
wave[w][center] += wave[w][speed]
|
wave[w][center] += wave[w][speed]
|
||||||
|
|
||||||
# Hue not currently changing?
|
# Hue not currently changing?
|
||||||
if ( wave[w][hue] == wave[w][hue_target] ):
|
if wave[w][hue] == wave[w][hue_target]:
|
||||||
|
|
||||||
# There's a tiny random chance of picking a new hue...
|
# There's a tiny random chance of picking a new hue...
|
||||||
if ( not random.randint(frames_per_second * 4, 255) ):
|
if not random.randint(frames_per_second * 4, 255):
|
||||||
# Within 1/3 color wheel
|
# Within 1/3 color wheel
|
||||||
wave[w][hue_target] = random.randint(wave[w][hue] - 30, wave[w][hue] + 30)
|
wave[w][hue_target] = random.randint(
|
||||||
|
wave[w][hue] - 30, wave[w][hue] + 30)
|
||||||
|
|
||||||
# This wave's hue is currently shifting...
|
# This wave's hue is currently shifting...
|
||||||
else:
|
else:
|
||||||
|
|
||||||
if ( wave[w][hue] < wave[w][hue_target] ):
|
if wave[w][hue] < wave[w][hue_target]:
|
||||||
wave[w][hue] += 1 # Move up or
|
wave[w][hue] += 1 # Move up or
|
||||||
else:
|
else:
|
||||||
wave[w][hue] -= 1 # down as needed
|
wave[w][hue] -= 1 # down as needed
|
||||||
|
|
||||||
# Reached destination?
|
# Reached destination?
|
||||||
if ( wave[w][hue] == wave[w][hue_target] ):
|
if wave[w][hue] == wave[w][hue_target]:
|
||||||
wave[w][hue] = 90 + wave[w][hue] % 90 # Clamp to 90-180 range
|
wave[w][hue] = 90 + wave[w][hue] % 90 # Clamp to 90-180 range
|
||||||
wave[w][hue_target] = wave[w][hue] # Copy to target
|
wave[w][hue_target] = wave[w][hue] # Copy to target
|
||||||
|
|
||||||
wave[w][red] = h2rgb( wave[w][hue] - 30 )
|
wave[w][red] = h2rgb(wave[w][hue] - 30)
|
||||||
wave[w][green] = h2rgb( wave[w][hue] )
|
wave[w][green] = h2rgb(wave[w][hue])
|
||||||
wave[w][blue] = h2rgb( wave[w][hue] + 30)
|
wave[w][blue] = h2rgb(wave[w][hue] + 30)
|
||||||
|
|
||||||
# Now render the LED strip using the current
|
# Now render the LED strip using the current
|
||||||
# brightness & wave states.
|
# brightness & wave states.
|
||||||
# Each LED in strip is visited just once...
|
# Each LED in strip is visited just once...
|
||||||
for i in range(num_leds):
|
for i in range(num_leds):
|
||||||
|
|
||||||
# Transform 'i' (LED number in pixel space) to the
|
# Transform 'i' (LED number in pixel space) to the
|
||||||
# equivalent point in 8-bit fixed-point space (0-255)
|
# equivalent point in 8-bit fixed-point space (0-255)
|
||||||
# "* 256" because that would be
|
# "* 256" because that would be
|
||||||
# the start of the (N+1)th pixel
|
# the start of the (N+1)th pixel
|
||||||
|
|
@ -182,72 +188,73 @@ while ( True ) :
|
||||||
x = (i * 256 + 127) / circumference
|
x = (i * 256 + 127) / circumference
|
||||||
|
|
||||||
# LED assumed off, but wave colors will add up here
|
# LED assumed off, but wave colors will add up here
|
||||||
r = g = b = 0
|
r = g = b = 0
|
||||||
|
|
||||||
# For each item in wave[] array...
|
# For each item in wave[] array...
|
||||||
for w in range(n_waves):
|
for w_index in range(n_waves):
|
||||||
# Calculate distance from pixel center to wave
|
# Calculate distance from pixel center to wave
|
||||||
# center point, using both signed and unsigned
|
# center point, using both signed and unsigned
|
||||||
# 8-bit integers...
|
# 8-bit integers...
|
||||||
d1 = int( abs(x - wave[w][center]) )
|
d1 = int(abs(x - wave[w_index][center]))
|
||||||
d2 = int( abs(x - wave[w][center]) )
|
d2 = int(abs(x - wave[w_index][center]))
|
||||||
|
|
||||||
# Then take the lesser of the two, resulting in
|
# Then take the lesser of the two, resulting in
|
||||||
# a distance (0-128)
|
# a distance (0-128)
|
||||||
# that 'wraps around' the ends of the strip as
|
# that 'wraps around' the ends of the strip as
|
||||||
# necessary...it's a contiguous ring, and waves
|
# necessary...it's a contiguous ring, and waves
|
||||||
# can move smoothly across the gap.
|
# can move smoothly across the gap.
|
||||||
if ( d2 < d1 ):
|
if d2 < d1:
|
||||||
d1 = d2 # d1 is pixel-to-wave-center distance
|
d1 = d2 # d1 is pixel-to-wave-center distance
|
||||||
|
|
||||||
# d2 distance, relative to wave width, is then
|
# d2 distance, relative to wave width, is then
|
||||||
# proportional to the wave's brightness at this
|
# proportional to the wave's brightness at this
|
||||||
# pixel (basic linear y=mx+b stuff).
|
# pixel (basic linear y=mx+b stuff).
|
||||||
# Is distance within wave's influence?
|
# Is distance within wave's influence?
|
||||||
# d2 is opposite; distance to wave's end
|
# d2 is opposite; distance to wave's end
|
||||||
if ( d1 < wave[w][width] ):
|
if d1 < wave[w_index][width]:
|
||||||
d2 = wave[w][width] - d1
|
d2 = wave[w_index][width] - d1
|
||||||
y = int ( brightness * d2 / wave[w][width] ) # 0 to 200
|
y = int(brightness * d2 / wave[w_index][width]) # 0 to 200
|
||||||
|
|
||||||
# y is a brightness scale value --
|
# y is a brightness scale value --
|
||||||
# proportional to, but not exactly equal
|
# proportional to, but not exactly equal
|
||||||
# to, the resulting RGB value.
|
# to, the resulting RGB value.
|
||||||
if ( y < 128 ): # Fade black to RGB color
|
if y < 128: # Fade black to RGB color
|
||||||
# In HSV colorspace, this would be
|
# In HSV colorspace, this would be
|
||||||
# tweaking 'value'
|
# tweaking 'value'
|
||||||
n = int(y * 2 + 1) # 1-256
|
n = int(y * 2 + 1) # 1-256
|
||||||
r += ( wave[w][red] * n ) >> 8 # More fixed-point math
|
r += (wave[w_index][red] * n) >> 8 # More fixed-point math
|
||||||
g += ( wave[w][green] * n ) >> 8 # Wave color is scaled by 'n'
|
# Wave color is scaled by 'n'
|
||||||
b += ( wave[w][blue] * n ) >> 8 # >>8 is equiv to /256
|
g += (wave[w_index][green] * n) >> 8
|
||||||
else: # Fade RGB color to white
|
b += (wave[w_index][blue] * n) >> 8 # >>8 is equiv to /256
|
||||||
# In HSV colorspace, this would be tweaking 'saturation'
|
else: # Fade RGB color to white
|
||||||
n = int( ( y - 128 ) * 2 ) # 0-255 affects white level
|
# In HSV colorspace, this tweaks 'saturation'
|
||||||
m = 256 * n
|
n = int((y - 128) * 2) # 0-255 affects white level
|
||||||
n = 256 - n # 1-256 affects RGB level
|
m = 256 * n
|
||||||
r += (m + wave[w][red] * n) >> 8
|
n = 256 - n # 1-256 affects RGB level
|
||||||
g += (m + wave[w][green] * n) >> 8
|
r += (m + wave[w_index][red] * n) >> 8
|
||||||
b += (m + wave[w][blue] * n) >> 8
|
g += (m + wave[w_index][green] * n) >> 8
|
||||||
|
b += (m + wave[w_index][blue] * n) >> 8
|
||||||
|
|
||||||
# r,g,b are 16-bit types that accumulate brightness
|
# r,g,b are 16-bit types that accumulate brightness
|
||||||
# from all waves that affect this pixel; may exceed
|
# from all waves that affect this pixel; may exceed
|
||||||
# 255. Now clip to 0-255 range:
|
# 255. Now clip to 0-255 range:
|
||||||
if ( r > 255 ):
|
if r > 255:
|
||||||
r = 255
|
r = 255
|
||||||
if ( g > 255 ):
|
if g > 255:
|
||||||
g = 255
|
g = 255
|
||||||
if ( b > 255 ):
|
if b > 255:
|
||||||
b = 255
|
b = 255
|
||||||
|
|
||||||
# Store resulting RGB value and we're done with
|
# Store resulting RGB value and we're done with
|
||||||
# this pixel!
|
# this pixel!
|
||||||
strip[i] = (r, g, b)
|
strip[i] = (r, g, b)
|
||||||
|
|
||||||
# Once rendering is complete, a second pass is made
|
# Once rendering is complete, a second pass is made
|
||||||
# through pixel data applying gamma correction, for
|
# through pixel data applying gamma correction, for
|
||||||
# more perceptually linear colors.
|
# more perceptually linear colors.
|
||||||
# https://learn.adafruit.com/led-tricks-gamma-correction
|
# https://learn.adafruit.com/led-tricks-gamma-correction
|
||||||
for j in range( num_leds ):
|
for j in range(num_leds):
|
||||||
( red_gamma, green_gamma, blue_gamma ) = strip[j]
|
(red_gamma, green_gamma, blue_gamma) = strip[j]
|
||||||
red_gamma = gammas[red_gamma]
|
red_gamma = gammas[red_gamma]
|
||||||
green_gamma = gammas[green_gamma]
|
green_gamma = gammas[green_gamma]
|
||||||
blue_gamma = gammas[blue_gamma]
|
blue_gamma = gammas[blue_gamma]
|
||||||
|
|
|
||||||
|
|
@ -1,67 +1,72 @@
|
||||||
# NeoPixel earrings example. Makes a nice blinky display with just a
|
# NeoPixel earrings example. Makes a nice blinky display with just a
|
||||||
# few LEDs on at any time...uses MUCH less juice than rainbow display!
|
# few LEDs on at any time...uses MUCH less juice than rainbow display!
|
||||||
|
|
||||||
|
import time
|
||||||
|
|
||||||
import board
|
import board
|
||||||
import neopixel
|
import neopixel
|
||||||
import time
|
|
||||||
try:
|
try:
|
||||||
import urandom as random # for v1.0 API support
|
import urandom as random # for v1.0 API support
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import random
|
import random
|
||||||
|
|
||||||
numpix = 16 # Number of NeoPixels (e.g. 16-pixel ring)
|
numpix = 16 # Number of NeoPixels (e.g. 16-pixel ring)
|
||||||
pixpin = board.D0 # Pin where NeoPixels are connected
|
pixpin = board.D0 # Pin where NeoPixels are connected
|
||||||
strip = neopixel.NeoPixel(pixpin, numpix, brightness=.3)
|
strip = neopixel.NeoPixel(pixpin, numpix, brightness=.3)
|
||||||
|
|
||||||
|
|
||||||
def wheel(pos):
|
def wheel(pos):
|
||||||
# Input a value 0 to 255 to get a color value.
|
# Input a value 0 to 255 to get a color value.
|
||||||
# The colours are a transition r - g - b - back to r.
|
# The colours are a transition r - g - b - back to r.
|
||||||
if (pos < 0) or (pos > 255):
|
if (pos < 0) or (pos > 255):
|
||||||
return [0, 0, 0]
|
return [0, 0, 0]
|
||||||
elif (pos < 85):
|
elif pos < 85:
|
||||||
return [int(pos * 3), int(255 - (pos * 3)), 0]
|
return [int(pos * 3), int(255 - (pos * 3)), 0]
|
||||||
elif (pos < 170):
|
elif pos < 170:
|
||||||
pos -= 85
|
pos -= 85
|
||||||
return [int(255 - pos * 3), 0, int(pos * 3)]
|
return [int(255 - pos * 3), 0, int(pos * 3)]
|
||||||
else:
|
else:
|
||||||
pos -= 170
|
pos -= 170
|
||||||
return [0, int(pos * 3), int(255 - pos * 3)]
|
return [0, int(pos * 3), int(255 - pos * 3)]
|
||||||
|
|
||||||
mode = 0 # Current animation effect
|
|
||||||
offset = 0 # Position of spinner animation
|
mode = 0 # Current animation effect
|
||||||
hue = 0 # Starting hue
|
offset = 0 # Position of spinner animation
|
||||||
color = wheel(hue & 255) # hue -> RGB color
|
hue = 0 # Starting hue
|
||||||
|
color = wheel(hue & 255) # hue -> RGB color
|
||||||
prevtime = time.monotonic() # Time of last animation mode switch
|
prevtime = time.monotonic() # Time of last animation mode switch
|
||||||
|
|
||||||
while True: # Loop forever...
|
while True: # Loop forever...
|
||||||
|
|
||||||
if mode == 0: # Random sparkles - lights just one LED at a time
|
if mode == 0: # Random sparkles - lights just one LED at a time
|
||||||
i = random.randint(0, numpix - 1) # Choose random pixel
|
i = random.randint(0, numpix - 1) # Choose random pixel
|
||||||
strip[i] = color # Set it to current color
|
strip[i] = color # Set it to current color
|
||||||
strip.write() # Refresh LED states
|
strip.write() # Refresh LED states
|
||||||
# Set same pixel to "off" color now but DON'T refresh...
|
# Set same pixel to "off" color now but DON'T refresh...
|
||||||
# it stays on for now...bot this and the next random
|
# it stays on for now...bot this and the next random
|
||||||
# pixel will be refreshed on the next pass.
|
# pixel will be refreshed on the next pass.
|
||||||
strip[i] = [0,0,0]
|
strip[i] = [0, 0, 0]
|
||||||
time.sleep(0.008) # 8 millisecond delay
|
time.sleep(0.008) # 8 millisecond delay
|
||||||
elif mode == 1: # Spinny wheel (4 LEDs on at a time)
|
elif mode == 1: # Spinny wheel (4 LEDs on at a time)
|
||||||
for i in range(numpix): # For each LED...
|
for i in range(numpix): # For each LED...
|
||||||
if ((offset + i) & 7) < 2: # 2 pixels out of 8...
|
if ((offset + i) & 7) < 2: # 2 pixels out of 8...
|
||||||
strip[i] = color # are set to current color
|
strip[i] = color # are set to current color
|
||||||
else:
|
else:
|
||||||
strip[i] = [0,0,0] # other pixels are off
|
strip[i] = [0, 0, 0] # other pixels are off
|
||||||
strip.write() # Refresh LED states
|
strip.write() # Refresh LED states
|
||||||
time.sleep(0.04) # 40 millisecond delay
|
time.sleep(0.04) # 40 millisecond delay
|
||||||
offset += 1 # Shift animation by 1 pixel on next frame
|
offset += 1 # Shift animation by 1 pixel on next frame
|
||||||
if offset >= 8: offset = 0
|
if offset >= 8:
|
||||||
# Additional animation modes could be added here!
|
offset = 0
|
||||||
|
# Additional animation modes could be added here!
|
||||||
|
|
||||||
t = time.monotonic() # Current time in seconds
|
t = time.monotonic() # Current time in seconds
|
||||||
if (t - prevtime) >= 8: # Every 8 seconds...
|
if (t - prevtime) >= 8: # Every 8 seconds...
|
||||||
mode += 1 # Advance to next mode
|
mode += 1 # Advance to next mode
|
||||||
if mode > 1: # End of modes?
|
if mode > 1: # End of modes?
|
||||||
mode = 0 # Start over from beginning
|
mode = 0 # Start over from beginning
|
||||||
hue += 80 # And change color
|
hue += 80 # And change color
|
||||||
color = wheel(hue & 255)
|
color = wheel(hue & 255)
|
||||||
strip.fill([0,0,0]) # Turn off all pixels
|
strip.fill([0, 0, 0]) # Turn off all pixels
|
||||||
prevtime = t # Record time of last mode change
|
prevtime = t # Record time of last mode change
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
"""Interactive light show using built-in LED and capacitive touch"""
|
"""Interactive light show using built-in LED and capacitive touch"""
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import adafruit_dotstar
|
import adafruit_dotstar
|
||||||
import touchio
|
|
||||||
import board
|
import board
|
||||||
|
import touchio
|
||||||
|
|
||||||
led = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1)
|
led = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1)
|
||||||
touch_A0 = touchio.TouchIn(board.A0)
|
touch_A0 = touchio.TouchIn(board.A0)
|
||||||
|
|
@ -33,10 +34,10 @@ def cycle_sequence(seq):
|
||||||
|
|
||||||
def rainbow_cycle(seq):
|
def rainbow_cycle(seq):
|
||||||
"""Rainbow cycle generator"""
|
"""Rainbow cycle generator"""
|
||||||
rainbow = cycle_sequence(seq)
|
rainbow_sequence = cycle_sequence(seq)
|
||||||
while True:
|
while True:
|
||||||
# pylint: disable=stop-iteration-return
|
# pylint: disable=stop-iteration-return
|
||||||
led[0] = (wheel(next(rainbow)))
|
led[0] = (wheel(next(rainbow_sequence)))
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -59,7 +60,6 @@ color_sequences = cycle_sequence(
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
cycle_speeds = cycle_sequence([0.1, 0.3, 0.5])
|
cycle_speeds = cycle_sequence([0.1, 0.3, 0.5])
|
||||||
|
|
||||||
brightness = brightness_cycle()
|
brightness = brightness_cycle()
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
"""Touch each pad to change red, green, and blue values on the LED"""
|
"""Touch each pad to change red, green, and blue values on the LED"""
|
||||||
import time
|
import time
|
||||||
import touchio
|
|
||||||
import adafruit_dotstar
|
import adafruit_dotstar
|
||||||
import board
|
import board
|
||||||
|
import touchio
|
||||||
|
|
||||||
led = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1)
|
led = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1)
|
||||||
touch_A0 = touchio.TouchIn(board.A0)
|
touch_A0 = touchio.TouchIn(board.A0)
|
||||||
|
|
|
||||||
|
|
@ -6,16 +6,17 @@
|
||||||
# Author: Collin Cunningham
|
# Author: Collin Cunningham
|
||||||
# License: MIT License (https://opensource.org/licenses/MIT)
|
# License: MIT License (https://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
from digitalio import DigitalInOut, Direction, Pull
|
|
||||||
import board
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
import board
|
||||||
import neopixel
|
import neopixel
|
||||||
from adafruit_hid.keyboard import Keyboard
|
from adafruit_hid.keyboard import Keyboard
|
||||||
from adafruit_hid.keycode import Keycode
|
|
||||||
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
|
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
|
||||||
|
from adafruit_hid.keycode import Keycode
|
||||||
|
from digitalio import DigitalInOut, Direction, Pull
|
||||||
|
|
||||||
pixels = neopixel.NeoPixel(board.NEOPIXEL, 10, brightness=.2)
|
pixels = neopixel.NeoPixel(board.NEOPIXEL, 10, brightness=.2)
|
||||||
pixels.fill((0,0,0))
|
pixels.fill((0, 0, 0))
|
||||||
pixels.show()
|
pixels.show()
|
||||||
|
|
||||||
# The pins connected to each switch/button
|
# The pins connected to each switch/button
|
||||||
|
|
@ -56,18 +57,21 @@ statusled.direction = Direction.OUTPUT
|
||||||
|
|
||||||
print("Waiting for button presses")
|
print("Waiting for button presses")
|
||||||
|
|
||||||
def pressbutton(i):
|
|
||||||
l = leds[i] # find the switch LED
|
def pressbutton(index):
|
||||||
k = buttonkeys[i] # get the corresp. keycode/str
|
switch_led = leds[index] # find the switch LED
|
||||||
l.value = True # turn on LED
|
k = buttonkeys[index] # get the corresp. keycode/str
|
||||||
kbd.press(k) # send keycode
|
switch_led.value = True # turn on LED
|
||||||
|
kbd.press(k) # send keycode
|
||||||
def releasebutton(i):
|
|
||||||
l = leds[i] # find the switch LED
|
|
||||||
k = buttonkeys[i] # get the corresp. keycode/str
|
def releasebutton(index):
|
||||||
l.value = False # turn on LED
|
switch_led = leds[index] # find the switch LED
|
||||||
kbd.release(k) # send keycode
|
k = buttonkeys[index] # get the corresp. keycode/str
|
||||||
|
switch_led.value = False # turn on LED
|
||||||
|
kbd.release(k) # send keycode
|
||||||
|
|
||||||
|
|
||||||
def lightneopixels():
|
def lightneopixels():
|
||||||
vals = [0, 0, 0]
|
vals = [0, 0, 0]
|
||||||
# if switch 0 pressed, show blue
|
# if switch 0 pressed, show blue
|
||||||
|
|
@ -82,30 +86,30 @@ def lightneopixels():
|
||||||
vals[0] = 255
|
vals[0] = 255
|
||||||
# if all pressed, show white
|
# if all pressed, show white
|
||||||
if buttonspressed[0] and buttonspressed[1] and buttonspressed[2]:
|
if buttonspressed[0] and buttonspressed[1] and buttonspressed[2]:
|
||||||
vals = [255,255,255]
|
vals = [255, 255, 255]
|
||||||
# if 0 & 1 pressed, show green
|
# if 0 & 1 pressed, show green
|
||||||
if buttonspressed[0] and buttonspressed[1] and not buttonspressed[2]:
|
if buttonspressed[0] and buttonspressed[1] and not buttonspressed[2]:
|
||||||
vals = [0,255,0]
|
vals = [0, 255, 0]
|
||||||
pixels.fill((vals[0],vals[1],vals[2]))
|
pixels.fill((vals[0], vals[1], vals[2]))
|
||||||
pixels.show()
|
pixels.show()
|
||||||
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
# check each button
|
# check each button
|
||||||
for button in buttons:
|
for button in buttons:
|
||||||
i = buttons.index(button)
|
i = buttons.index(button)
|
||||||
if button.value == False: # button is pressed?
|
if button.value is False: # button is pressed?
|
||||||
buttonspressed[i] = True # save pressed button
|
buttonspressed[i] = True # save pressed button
|
||||||
if buttonspressedlast[i] == False: # was button not pressed last time?
|
# was button not pressed last time?
|
||||||
|
if buttonspressedlast[i] is False:
|
||||||
print("Pressed #%d" % i)
|
print("Pressed #%d" % i)
|
||||||
pressbutton(i)
|
pressbutton(i)
|
||||||
else:
|
else:
|
||||||
buttonspressed[i] = False # button was not pressed
|
buttonspressed[i] = False # button was not pressed
|
||||||
if buttonspressedlast[i] == True: # was button pressed last time?
|
if buttonspressedlast[i] is True: # was button pressed last time?
|
||||||
print("Released #%d" % i)
|
print("Released #%d" % i)
|
||||||
releasebutton(i)
|
releasebutton(i)
|
||||||
lightneopixels()
|
lightneopixels()
|
||||||
# save pressed buttons as pressed last
|
# save pressed buttons as pressed last
|
||||||
buttonspressedlast = list(buttonspressed)
|
buttonspressedlast = list(buttonspressed)
|
||||||
time.sleep(0.01)
|
time.sleep(0.01)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from adafruit_circuitplayground.express import cpx
|
from adafruit_circuitplayground.express import cpx
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from adafruit_circuitplayground.express import cpx
|
from adafruit_circuitplayground.express import cpx
|
||||||
|
|
||||||
blink_speed = 0.5
|
blink_speed = 0.5
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from adafruit_circuitplayground.express import cpx
|
from adafruit_circuitplayground.express import cpx
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,24 @@
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from adafruit_circuitplayground.express import cpx
|
from adafruit_circuitplayground.express import cpx
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=redefined-outer-name
|
# pylint: disable=redefined-outer-name
|
||||||
|
|
||||||
|
|
||||||
def upright(x, y, z):
|
def upright(x, y, z):
|
||||||
return abs(x) < accel_threshold and abs(y) < accel_threshold and abs(9.8 - z) < accel_threshold
|
x_up = abs(x) < accel_threshold
|
||||||
|
y_up = abs(y) < accel_threshold
|
||||||
|
z_up = abs(9.8 - z) < accel_threshold
|
||||||
|
return x_up and y_up and z_up
|
||||||
|
|
||||||
|
|
||||||
def left_side(x, y, z):
|
def left_side(x, y, z):
|
||||||
return abs(9.8 - x) < accel_threshold and abs(y) < accel_threshold and abs(z) < accel_threshold
|
x_side = abs(9.8 - x) < accel_threshold
|
||||||
|
y_side = abs(y) < accel_threshold
|
||||||
|
z_side = abs(z) < accel_threshold
|
||||||
|
|
||||||
|
return x_side and y_side and z_side
|
||||||
|
|
||||||
|
|
||||||
state = None
|
state = None
|
||||||
|
|
|
||||||
|
|
@ -13,18 +13,18 @@ last_command = None
|
||||||
brightness_up = 95 # Up arrow
|
brightness_up = 95 # Up arrow
|
||||||
brightness_down = 79 # Down arrow
|
brightness_down = 79 # Down arrow
|
||||||
|
|
||||||
command_to_color = { # button = color
|
command_to_color = { # button = color
|
||||||
247: (255, 0, 0), # 1 = red
|
247: (255, 0, 0), # 1 = red
|
||||||
119: (255, 40, 0), # 2 = orange
|
119: (255, 40, 0), # 2 = orange
|
||||||
183: (255, 150, 0), # 3 = yellow
|
183: (255, 150, 0), # 3 = yellow
|
||||||
215: (0, 255, 0), # 4 = green
|
215: (0, 255, 0), # 4 = green
|
||||||
87: (0, 255, 120), # 5 = teal
|
87: (0, 255, 120), # 5 = teal
|
||||||
151: (0, 255, 255), # 6 = cyan
|
151: (0, 255, 255), # 6 = cyan
|
||||||
231: (0, 0, 255), # 7 = blue
|
231: (0, 0, 255), # 7 = blue
|
||||||
103: (180, 0, 255), # 8 = purple
|
103: (180, 0, 255), # 8 = purple
|
||||||
167: (255, 0, 20), # 9 = magenta
|
167: (255, 0, 20), # 9 = magenta
|
||||||
207: (255, 255, 255), # 0 = white
|
207: (255, 255, 255), # 0 = white
|
||||||
127: (0, 0, 0), # Play/Pause = off
|
127: (0, 0, 0), # Play/Pause = off
|
||||||
}
|
}
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from adafruit_circuitplayground.express import cpx
|
from adafruit_circuitplayground.express import cpx
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=stop-iteration-return
|
# pylint: disable=stop-iteration-return
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -9,12 +12,12 @@ def wheel(pos):
|
||||||
if pos < 0 or pos > 255:
|
if pos < 0 or pos > 255:
|
||||||
return 0, 0, 0
|
return 0, 0, 0
|
||||||
if pos < 85:
|
if pos < 85:
|
||||||
return int(255 - pos*3), int(pos*3), 0
|
return int(255 - pos * 3), int(pos * 3), 0
|
||||||
if pos < 170:
|
if pos < 170:
|
||||||
pos -= 85
|
pos -= 85
|
||||||
return 0, int(255 - pos*3), int(pos*3)
|
return 0, int(255 - pos * 3), int(pos * 3)
|
||||||
pos -= 170
|
pos -= 170
|
||||||
return int(pos * 3), 0, int(255 - (pos*3))
|
return int(pos * 3), 0, int(255 - (pos * 3))
|
||||||
|
|
||||||
|
|
||||||
def cycle_sequence(seq):
|
def cycle_sequence(seq):
|
||||||
|
|
@ -32,13 +35,13 @@ def rainbow_lamp(seq):
|
||||||
|
|
||||||
color_sequences = cycle_sequence([
|
color_sequences = cycle_sequence([
|
||||||
range(256), # rainbow_cycle
|
range(256), # rainbow_cycle
|
||||||
[0], # red
|
[0], # red
|
||||||
[10], # orange
|
[10], # orange
|
||||||
[30], # yellow
|
[30], # yellow
|
||||||
[85], # green
|
[85], # green
|
||||||
[137], # cyan
|
[137], # cyan
|
||||||
[170], # blue
|
[170], # blue
|
||||||
[213], # purple
|
[213], # purple
|
||||||
[0, 10, 30, 85, 137, 170, 213], # party mode
|
[0, 10, 30, 85, 137, 170, 213], # party mode
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from adafruit_circuitplayground.express import cpx
|
from adafruit_circuitplayground.express import cpx
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -8,25 +9,33 @@ def wheel(pos):
|
||||||
if pos < 0 or pos > 255:
|
if pos < 0 or pos > 255:
|
||||||
return 0, 0, 0
|
return 0, 0, 0
|
||||||
if pos < 85:
|
if pos < 85:
|
||||||
return int(255 - pos*3), int(pos*3), 0
|
return int(255 - pos * 3), int(pos * 3), 0
|
||||||
if pos < 170:
|
if pos < 170:
|
||||||
pos -= 85
|
pos -= 85
|
||||||
return 0, int(255 - pos*3), int(pos*3)
|
return 0, int(255 - pos * 3), int(pos * 3)
|
||||||
pos -= 170
|
pos -= 170
|
||||||
return int(pos * 3), 0, int(255 - (pos*3))
|
return int(pos * 3), 0, int(255 - (pos * 3))
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=redefined-outer-name
|
# pylint: disable=redefined-outer-name
|
||||||
def upright(x, y, z):
|
def upright(x, y, z):
|
||||||
return abs(x) < accel_threshold and abs(y) < accel_threshold and abs(9.8 - z) < accel_threshold
|
return abs(x) < accel_threshold \
|
||||||
|
and abs(y) < accel_threshold \
|
||||||
|
and abs(9.8 - z) < accel_threshold
|
||||||
|
|
||||||
|
|
||||||
def right_side(x, y, z):
|
def right_side(x, y, z):
|
||||||
return abs(-9.8 - x) < accel_threshold and abs(y) < accel_threshold and abs(z) < accel_threshold
|
return abs(-9.8 - x) < accel_threshold \
|
||||||
|
and abs(y) < accel_threshold \
|
||||||
|
and abs(z) < accel_threshold
|
||||||
|
|
||||||
|
|
||||||
def left_side(x, y, z):
|
def left_side(x, y, z):
|
||||||
return abs(9.8 - x) < accel_threshold and abs(y) < accel_threshold and abs(z) < accel_threshold
|
return abs(9.8 - x) < accel_threshold \
|
||||||
|
and abs(y) < accel_threshold \
|
||||||
|
and abs(z) < accel_threshold
|
||||||
|
|
||||||
|
|
||||||
# pylint: enable=redefined-outer-name
|
# pylint: enable=redefined-outer-name
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -54,13 +63,13 @@ def brightness_lamp():
|
||||||
|
|
||||||
color_sequences = cycle_sequence([
|
color_sequences = cycle_sequence([
|
||||||
range(256), # rainbow_cycle
|
range(256), # rainbow_cycle
|
||||||
[0], # red
|
[0], # red
|
||||||
[10], # orange
|
[10], # orange
|
||||||
[30], # yellow
|
[30], # yellow
|
||||||
[85], # green
|
[85], # green
|
||||||
[137], # cyan
|
[137], # cyan
|
||||||
[170], # blue
|
[170], # blue
|
||||||
[213], # purple
|
[213], # purple
|
||||||
[0, 10, 30, 85, 137, 170, 213], # party mode
|
[0, 10, 30, 85, 137, 170, 213], # party mode
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
from adafruit_circuitplayground.express import cpx
|
from adafruit_circuitplayground.express import cpx
|
||||||
|
|
||||||
touchpad_to_color = {
|
touchpad_to_color = {
|
||||||
"touch_A1": (255, 0, 0), # red
|
"touch_A1": (255, 0, 0), # red
|
||||||
"touch_A2": (255, 40, 0), # orange
|
"touch_A2": (255, 40, 0), # orange
|
||||||
"touch_A3": (255, 150, 0), # yellow
|
"touch_A3": (255, 150, 0), # yellow
|
||||||
"touch_A4": (0, 255, 0), # green
|
"touch_A4": (0, 255, 0), # green
|
||||||
"touch_A5": (0, 0, 255), # blue
|
"touch_A5": (0, 0, 255), # blue
|
||||||
"touch_A6": (180, 0, 255), # purple
|
"touch_A6": (180, 0, 255), # purple
|
||||||
"touch_A7": (0, 0, 0), # off
|
"touch_A7": (0, 0, 0), # off
|
||||||
}
|
}
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,16 @@ from adafruit_circuitplayground.express import cpx
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
if cpx.touch_A1:
|
if cpx.touch_A1:
|
||||||
cpx.pixels.fill((255, 0, 0)) # red
|
cpx.pixels.fill((255, 0, 0)) # red
|
||||||
elif cpx.touch_A2:
|
elif cpx.touch_A2:
|
||||||
cpx.pixels.fill((255, 40, 0)) # orange
|
cpx.pixels.fill((255, 40, 0)) # orange
|
||||||
elif cpx.touch_A3:
|
elif cpx.touch_A3:
|
||||||
cpx.pixels.fill((255, 150, 0)) # yellow
|
cpx.pixels.fill((255, 150, 0)) # yellow
|
||||||
elif cpx.touch_A4:
|
elif cpx.touch_A4:
|
||||||
cpx.pixels.fill((0, 255, 0)) # green
|
cpx.pixels.fill((0, 255, 0)) # green
|
||||||
elif cpx.touch_A5:
|
elif cpx.touch_A5:
|
||||||
cpx.pixels.fill((0, 0, 255)) # blue
|
cpx.pixels.fill((0, 0, 255)) # blue
|
||||||
elif cpx.touch_A6:
|
elif cpx.touch_A6:
|
||||||
cpx.pixels.fill((180, 0, 255)) # purple
|
cpx.pixels.fill((180, 0, 255)) # purple
|
||||||
elif cpx.touch_A7:
|
elif cpx.touch_A7:
|
||||||
cpx.pixels.fill((0, 0, 0)) # off
|
cpx.pixels.fill((0, 0, 0)) # off
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
from digitalio import DigitalInOut, Direction, Pull
|
|
||||||
import board
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
import board
|
||||||
|
from digitalio import DigitalInOut, Direction, Pull
|
||||||
|
|
||||||
button = DigitalInOut(board.D1)
|
button = DigitalInOut(board.D1)
|
||||||
button.direction = Direction.INPUT
|
button.direction = Direction.INPUT
|
||||||
button.pull = Pull.UP
|
button.pull = Pull.UP
|
||||||
|
|
@ -11,8 +12,8 @@ led.direction = Direction.OUTPUT
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
if button.value:
|
if button.value:
|
||||||
led.value = True # check if the pushbutton is pressed.
|
led.value = True # check if the pushbutton is pressed.
|
||||||
else:
|
else:
|
||||||
led.value = False # turn LED off
|
led.value = False # turn LED off
|
||||||
|
|
||||||
time.sleep(0.01) # debounce delay
|
time.sleep(0.01) # debounce delay
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,18 @@
|
||||||
# connected to GND, 3.3V, and pin A1
|
# connected to GND, 3.3V, and pin A1
|
||||||
# and prints the results to the REPL
|
# and prints the results to the REPL
|
||||||
|
|
||||||
from analogio import AnalogIn
|
|
||||||
import board
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
import board
|
||||||
|
from analogio import AnalogIn
|
||||||
|
|
||||||
analogin = AnalogIn(board.A1)
|
analogin = AnalogIn(board.A1)
|
||||||
|
|
||||||
def getVoltage(pin): # helper
|
|
||||||
|
def getVoltage(pin): # helper
|
||||||
return (pin.value * 3.3) / 65536
|
return (pin.value * 3.3) / 65536
|
||||||
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
print("Analog Voltage: %f" % getVoltage(analogin))
|
print("Analog Voltage: %f" % getVoltage(analogin))
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
from digitalio import DigitalInOut, Direction, Pull
|
|
||||||
import audioio
|
import audioio
|
||||||
import board
|
import board
|
||||||
|
from digitalio import DigitalInOut, Direction, Pull
|
||||||
|
|
||||||
# enable the speaker
|
# enable the speaker
|
||||||
spkrenable = DigitalInOut(board.SPEAKER_ENABLE)
|
spkrenable = DigitalInOut(board.SPEAKER_ENABLE)
|
||||||
|
|
@ -19,8 +19,9 @@ buttonB.pull = Pull.DOWN
|
||||||
# The two files assigned to buttons A & B
|
# The two files assigned to buttons A & B
|
||||||
audiofiles = ["rimshot.wav", "laugh.wav"]
|
audiofiles = ["rimshot.wav", "laugh.wav"]
|
||||||
|
|
||||||
|
|
||||||
def play_file(filename):
|
def play_file(filename):
|
||||||
print("playing file "+filename)
|
print("playing file " + filename)
|
||||||
f = open(filename, "rb")
|
f = open(filename, "rb")
|
||||||
a = audioio.AudioOut(board.A0, f)
|
a = audioio.AudioOut(board.A0, f)
|
||||||
a.play()
|
a.play()
|
||||||
|
|
@ -28,6 +29,7 @@ def play_file(filename):
|
||||||
pass
|
pass
|
||||||
print("finished")
|
print("finished")
|
||||||
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
if buttonA.value:
|
if buttonA.value:
|
||||||
play_file(audiofiles[0])
|
play_file(audiofiles[0])
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
from digitalio import DigitalInOut, Direction
|
import array
|
||||||
|
import math
|
||||||
|
import time
|
||||||
|
|
||||||
import audioio
|
import audioio
|
||||||
import board
|
import board
|
||||||
import array
|
from digitalio import DigitalInOut, Direction
|
||||||
import time
|
|
||||||
import math
|
|
||||||
|
|
||||||
FREQUENCY = 440 # 440 Hz middle 'A'
|
FREQUENCY = 440 # 440 Hz middle 'A'
|
||||||
SAMPLERATE = 8000 # 8000 samples/second, recommended!
|
SAMPLERATE = 8000 # 8000 samples/second, recommended!
|
||||||
|
|
||||||
# Generate one period of sine wav.
|
# Generate one period of sine wav.
|
||||||
|
|
@ -22,5 +23,5 @@ spkrenable.value = True
|
||||||
sample = audioio.AudioOut(board.SPEAKER, sine_wave)
|
sample = audioio.AudioOut(board.SPEAKER, sine_wave)
|
||||||
sample.frequency = SAMPLERATE
|
sample.frequency = SAMPLERATE
|
||||||
sample.play(loop=True) # keep playing the sample over and over
|
sample.play(loop=True) # keep playing the sample over and over
|
||||||
time.sleep(1) # until...
|
time.sleep(1) # until...
|
||||||
sample.stop() # we tell the board to stop
|
sample.stop() # we tell the board to stop
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
# CircuitPlaygroundExpress_Blinky
|
# CircuitPlaygroundExpress_Blinky
|
||||||
|
|
||||||
import digitalio
|
|
||||||
import board
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
led = digitalio.DigitalInOut(board.D13) #defines the variable 'led'
|
import board
|
||||||
led.direction = digitalio.Direction.OUTPUT #set the pin as output
|
import digitalio
|
||||||
|
|
||||||
while True: #code below this point loops over and over
|
led = digitalio.DigitalInOut(board.D13) # defines the variable 'led'
|
||||||
led.value = True #turn on the LED
|
led.direction = digitalio.Direction.OUTPUT # set the pin as output
|
||||||
time.sleep(0.5) #pause
|
|
||||||
led.value = False #turn off the LED
|
while True: # code below this point loops over and over
|
||||||
time.sleep(0.5) #pause
|
led.value = True # turn on the LED
|
||||||
|
time.sleep(0.5) # pause
|
||||||
|
led.value = False # turn off the LED
|
||||||
|
time.sleep(0.5) # pause
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue