Merge branch 'pylint'

This commit is contained in:
Craig Richardson 2018-05-15 16:49:39 +01:00
commit 00d491c4e3
192 changed files with 3579 additions and 2889 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
*~
Hue_Controller/secrets.h
.idea

View file

@ -1,17 +1,18 @@
# 3D_Printed_Guardian_Sword
# https://learn.adafruit.com/breath-of-the-wild-guardian-sword-led-3d-printed
import board
import neopixel
import time
pin = board.D4 # DIGITAL IO pin for NeoPixel OUTPUT from GEMMA
pixel_count = 93 # number of neopixels
delayval = .01 # 10 ms delay
import board
import neopixel
APIXELS = 14 # number of first orange pixels
BPIXELS = 84 # number of blue pixels
CPIXELS = 93 # second orange pixels
pin = board.D4 # DIGITAL IO pin for NeoPixel OUTPUT from GEMMA
pixel_count = 93 # number of neopixels
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
pixels = neopixel.NeoPixel(pin, pixel_count, brightness=1, auto_write=False)

View file

@ -26,42 +26,47 @@
# Written by Paul Badger 2007
# Modified fromhere code by Greg Shakar
# Ported to Circuit Python by Mikey Sklar
import time
import board
import neopixel
from analogio import AnalogIn
n_pixels = 16 # Number of pixels you are using
mic_pin = AnalogIn(board.A1) # Microphone is attached to this analog pin
led_pin = board.D1 # NeoPixel LED strand is connected to this pin
sample_window = .1 # Sample window for average level
peak_hang = 24 # Time of pause before peak dot falls
peak_fall = 4 # Rate of falling peak dot
input_floor = 10 # Lower range of analogRead input
input_ceiling = 300 # Max range of analogRead input, the lower
# the value the more sensitive (1023 = max)
n_pixels = 16 # Number of pixels you are using
mic_pin = AnalogIn(board.A1) # Microphone is attached to this analog pin
led_pin = board.D1 # NeoPixel LED strand is connected to this pin
sample_window = .1 # Sample window for average level
peak_hang = 24 # Time of pause before peak dot falls
peak_fall = 4 # Rate of falling peak dot
input_floor = 10 # Lower range of analogRead input
# Max range of analogRead input, the lower the value the more sensitive
# (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
dotcount = 0 # Frame counter for peak dot
dothangcount = 0 # Frame counter for holding peak dot
dotcount = 0 # Frame counter for peak dot
dothangcount = 0 # Frame counter for holding peak dot
strip = neopixel.NeoPixel(led_pin, n_pixels, brightness=1, auto_write=False)
def wheel(pos):
# Input a value 0 to 255 to get a color value.
# The colours are a transition r - g - b - back to r.
if pos < 0 or pos > 255:
return (0, 0, 0)
if pos < 85:
return (int(pos * 3), int(255 - (pos*3)), 0)
return (int(pos * 3), int(255 - (pos * 3)), 0)
elif pos < 170:
pos -= 85
return (int(255 - pos*3), 0, int(pos*3))
return (int(255 - pos * 3), 0, int(pos * 3))
else:
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):
# 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.
return int(rightMin + (valueScaled * rightSpan))
def fscale(originalmin, originalmax, newbegin, newend, inputvalue, curve):
originalrange = 0
newrange = 0
zerorefcurval = 0
normalizedcurval = 0
rangedvalue = 0
invflag = 0
# condition curve parameter
@ -94,7 +95,8 @@ def fscale(originalmin, originalmax, newbegin, newend, inputvalue, curve):
# this seems more intuitive
# postive numbers give more weight to high end on output
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
if inputvalue < originalmin:
@ -113,7 +115,8 @@ def fscale(originalmin, originalmax, newbegin, newend, inputvalue, curve):
invflag = 1
zerorefcurval = inputvalue - originalmin
normalizedcurval = zerorefcurval / originalrange # normalize to 0 - 1 float
# normalize to 0 - 1 float
normalizedcurval = zerorefcurval / originalrange
# Check for originalMin > originalMax
# -the math for all other cases
@ -122,44 +125,44 @@ def fscale(originalmin, originalmax, newbegin, newend, inputvalue, curve):
return 0
if invflag == 0:
rangedvalue = (pow(normalizedcurval, curve) * newrange) + newbegin
else: # invert the ranges
rangedvalue = newbegin - (pow(normalizedcurval, curve) * newrange)
rangedvalue = (pow(normalizedcurval, curve) * newrange) + newbegin
else: # invert the ranges
rangedvalue = newbegin - (pow(normalizedcurval, curve) * newrange)
return rangedvalue
def drawLine(fromhere, to):
fromheretemp = 0
if fromhere > to:
fromheretemp = fromhere
fromhere = to
to = fromheretemp
for n in range(fromhere, to):
strip[n] = (0, 0, 0)
for index in range(fromhere, to):
strip[index] = (0, 0, 0)
while True:
time_start = time.monotonic() # current time used for sample window
peaktopeak = 0 # peak-to-peak level
time_start = time.monotonic() # current time used for sample window
peaktopeak = 0 # peak-to-peak level
signalmax = 0
signalmin = 1023
c = 0
y = 0
# 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:
signalmax = sample # save just the max levels
signalmax = sample # save just the max levels
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
@ -171,10 +174,10 @@ while True:
c = fscale(input_floor, input_ceiling, (n_pixels - 1), 0, peaktopeak, 2)
if c < peak:
peak = c # keep dot on top
dothangcount = 0 # make the dot hang before falling
peak = c # keep dot on top
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))
# Set the peak dot to match the rainbow gradient
@ -183,9 +186,9 @@ while True:
strip.write()
# Frame based peak dot animation
if dothangcount > peak_hang: # Peak pause length
dotcount = dotcount + 1
if dotcount >= peak_fall: # Fall rate
if dothangcount > peak_hang: # Peak pause length
dotcount += 1
if dotcount >= peak_fall: # Fall rate
peak += 1
dotcount = 0
else:

View file

@ -1,26 +1,28 @@
import time
import board
import neopixel
try:
import urandom as random # for v1.0 API support
except ImportError:
import random
numpix = 24 # Number of NeoPixels
numpix = 24 # Number of NeoPixels
pixpin = board.D0 # Pin where NeoPixels are connected
strip = neopixel.NeoPixel(pixpin, numpix, brightness=0.3)
mode = 0 # Current animation effect
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
while True: # Loop forever...
if mode == 0: # Random sparkles - lights just one LED at a time
i = random.randint(0, numpix - 1) # Choose random pixel
strip[i] = color # Set it to current color
strip.write() # Refresh LED states
strip[i] = color # Set it to current color
strip.write() # Refresh LED states
# Set same pixel to "off" color now but DON'T refresh...
# it stays on for now...bot this and the next random
# 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).
for i in range(numpix): # For each LED...
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:
strip[i] = [0, 0, 0] # other pixels are off
strip.write() # Refresh LED states
time.sleep(0.04) # 40 millisecond delay
offset += 1 # Shift animation by 1 pixel on next frame
if offset >= 8:
offset = 0
# Additional animation modes could be added here!
strip.write() # Refresh LED states
time.sleep(0.04) # 40 millisecond delay
offset += 1 # Shift animation by 1 pixel on next frame
if offset >= 8:
offset = 0
# Additional animation modes could be added here!
t = time.monotonic() # Current time in seconds
if (t - prevtime) >= 8: # Every 8 seconds...
mode += 1 # Advance to next mode
if mode > 1: # End of modes?
mode = 0 # Start over from beginning
# Rotate color R->G->B
color = [color[2], color[0], color[1]]
t = time.monotonic() # Current time in seconds
if (t - prevtime) >= 8: # Every 8 seconds...
mode += 1 # Advance to next mode
if mode > 1: # End of modes?
mode = 0 # Start over from beginning
# Rotate color R->G->B
color = [color[2], color[0], color[1]]
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

View file

@ -9,6 +9,7 @@
# major bug, you don't need tochange anything here
#
import time
import board
import neopixel
@ -19,39 +20,43 @@ except ImportError:
from analogio import AnalogIn
# available actions
ACT_NOP = 0x00 # all leds off, do nothing
ACT_SIMPLE_RING = 0x01 # all leds on
ACT_CYCLING_RING_ACLK = 0x02 # anti clockwise cycling colors
ACT_CYCLING_RING_CLKW = 0x04 # clockwise cycling colors
ACT_WHEEL_ACLK = 0x08 # anti clockwise spinning wheel
ACT_WHEEL_CLKW = 0x10 # clockwise spinning wheel
ACT_SPARKLING_RING = 0x20 # sparkling effect
ACT_NOP = 0x00 # all leds off, do nothing
ACT_SIMPLE_RING = 0x01 # all leds on
ACT_CYCLING_RING_ACLK = 0x02 # anti clockwise cycling colors
ACT_CYCLING_RING_CLKW = 0x04 # clockwise cycling colors
ACT_WHEEL_ACLK = 0x08 # anti clockwise spinning wheel
ACT_WHEEL_CLKW = 0x10 # clockwise spinning wheel
ACT_SPARKLING_RING = 0x20 # sparkling effect
numpix = 16 # total number of NeoPixels
pixel_output = board.D0 # pin where NeoPixels are connected
analog_input = board.A0 # needed to seed the random generator
strip = neopixel.NeoPixel(pixel_output, numpix, brightness=.3, auto_write=False)
numpix = 16 # total number of NeoPixels
pixel_output = board.D0 # pin where NeoPixels are connected
analog_input = board.A0 # needed to seed the random generator
strip = neopixel.NeoPixel(pixel_output, numpix,
brightness=.3, auto_write=False)
# available color generation methods
COL_RANDOM = 0x40 # colors will be generated randomly
COL_SPECTRUM = 0x80 # colors will be set as cyclic spectral wipe
COL_RANDOM = 0x40 # colors will be generated randomly
COL_SPECTRUM = 0x80 # colors will be set as cyclic spectral wipe
# specifiyng the action list
action_duration = 0 # the action's overall duration in milliseconds (be careful not
# to use values > 2^16-1 - roughly one minute :-)
# the action's overall duration in milliseconds (be careful not
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
# loop in milliseconds - thus, controls the action speed (be
# careful not to use values > 2^16-1 - roughly one minute :-)
# the duration of each action step rsp. the delay of the main
action_step_duration = 2
# 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
# rsp. color. 1 means the increment is 0,1,2,3,..., 10 means
# the increment is 0,10,20,... don't use values > 255, and note
# that even values > 127 wouldn't make much sense...
color_granularity = 3 # controls the increment of the R, G, and B
# portions of the rsp. color. 1 means the increment is 0,1,2,3,...,
# 10 means the increment is 0,10,20,... don't use values > 255, and
# 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
color = 0
@ -75,60 +80,87 @@ spectrum_part = 0
# this array variable must be called theactionlist !!!
#
# valid actions are:
# ACT_NOP simply do nothing and switch everything off
# ACT_SIMPLE_RING all leds on
# ACT_CYCLING_RING_ACLK anti clockwise cycling colors
# ACT_CYCLING_RING_CLKW clockwise cycling colors acording
# ACT_WHEEL_ACLK anti clockwise spinning wheel
# ACT_WHEEL_CLKW clockwise spinning wheel
# ACT_SPARKLING_RING sparkling effect
# ACT_NOP simply do nothing and switch everything off
# ACT_SIMPLE_RING all leds on
# ACT_CYCLING_RING_ACLK anti clockwise cycling colors
# ACT_CYCLING_RING_CLKW clockwise cycling colors acording
# ACT_WHEEL_ACLK anti clockwise spinning wheel
# ACT_WHEEL_CLKW clockwise spinning wheel
# ACT_SPARKLING_RING sparkling effect
#
# valid color options are:
# COL_RANDOM colors will be selected randomly, which might
# be not very sufficient due to well known
# limitations of the random generation algorithm
# COL_SPECTRUM colors will be set as cyclic spectral wipe
# R -> G -> B -> R -> G -> B -> R -> ...
# COL_RANDOM colors will be selected randomly, which might
# be not very sufficient due to well known
# limitations of the random generation algorithm
# COL_SPECTRUM colors will be set as cyclic spectral wipe
# R -> G -> B -> R -> G -> B -> R -> ...
# action action name & action step color color change
# duration color generation method duration granularity interval
# action action name & action step color color change
# duration color generation method duration granularity interval
theactionlist = [
[5, ACT_SPARKLING_RING | COL_RANDOM, 0.01, 25, 1 ],
[2, ACT_CYCLING_RING_CLKW | COL_RANDOM, 0.02, 1, 0.005 ],
[5, ACT_SPARKLING_RING | COL_RANDOM, 0.01, 25, 1 ],
[2, ACT_CYCLING_RING_ACLK | COL_RANDOM, 0.02, 1, 0.005 ],
[5, ACT_SPARKLING_RING | COL_RANDOM, 0.01, 25, 1 ],
[2.5, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.25, 20, 0.020 ],
[1, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.50, 1, 0.020 ],
[.750, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.075, 1, 0.020 ],
[.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.100, 1, 0.020 ],
[.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.125, 1, 0.020 ],
[.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.150, 1, 0.050 ],
[.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.175, 1, 0.100 ],
[.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.200, 1, 0.200 ],
[.750, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.225, 1, 0.250 ],
[1, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.250, 1, 0.350 ],
[30, ACT_SIMPLE_RING | COL_SPECTRUM, 0.050, 1, 0.010 ],
[2.5, ACT_WHEEL_ACLK | COL_SPECTRUM, 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]
[5, ACT_SPARKLING_RING | COL_RANDOM, 0.01, 25, 1],
[2, ACT_CYCLING_RING_CLKW | COL_RANDOM,
0.02, 1, 0.005],
[5, ACT_SPARKLING_RING | COL_RANDOM, 0.01, 25, 1],
[2, ACT_CYCLING_RING_ACLK | COL_RANDOM,
0.02, 1, 0.005],
[5, ACT_SPARKLING_RING | COL_RANDOM, 0.01, 25, 1],
[2.5, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
0.25, 20, 0.020],
[1, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
0.50, 1, 0.020],
[.750, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
0.075, 1, 0.020],
[.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
0.100, 1, 0.020],
[.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
0.125, 1, 0.020],
[.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
0.150, 1, 0.050],
[.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
0.175, 1, 0.100],
[.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
0.200, 1, 0.200],
[.750, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
0.225, 1, 0.250],
[1, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
0.250, 1, 0.350],
[30, ACT_SIMPLE_RING | COL_SPECTRUM,
0.050, 1, 0.010],
[2.5, ACT_WHEEL_ACLK | COL_SPECTRUM,
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():
global spectrum_part, color_idx, curr_color_granularity, color
# spectral wipe from green to red
if spectrum_part == 2:
color = (color_idx, 0, 255-color_idx)
@ -153,23 +185,25 @@ def nextspectrumcolor():
spectrum_part = 1
color_idx = 0
def nextrandomcolor():
global color
# granularity = 1 --> [0 .. 255] * 1 --> 0,1,2,3 ... 255
# granularity = 10 --> [0 .. 25] * 10 --> 0,10,20,30 ... 250
# 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_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_blue = random.randint(0, int (256 / curr_color_granularity))
random_blue = random.randint(0, int(256 / curr_color_granularity))
random_blue *= curr_color_granularity
color = (random_red, random_green, random_blue)
def nextcolor():
# save some RAM for more animation actions
if curr_color_gen & COL_RANDOM:
@ -177,8 +211,8 @@ def nextcolor():
else:
nextspectrumcolor()
def setup():
def setup():
# fingers corssed, the seeding makes sense to really get random colors...
apin = AnalogIn(analog_input)
random.seed(apin.value)
@ -188,18 +222,21 @@ def setup():
nextcolor()
strip.write()
setup()
while True: # Loop forever...
# do we need to load the next action?
if (time.monotonic() - action_timer) > curr_action_duration:
curr_action_duration = theactionlist[curr_action_idx][action_duration]
curr_action = theactionlist[curr_action_idx][action_and_color_gen] & 0x3F
curr_action_step_duration = theactionlist[curr_action_idx][action_step_duration]
curr_color_gen = theactionlist[curr_action_idx][action_and_color_gen] & 0xC0
curr_color_granularity = theactionlist[curr_action_idx][color_granularity]
curr_color_interval = theactionlist[curr_action_idx][color_interval]
current_action = theactionlist[curr_action_idx]
curr_action_duration = current_action[action_duration]
curr_action = current_action[action_and_color_gen] & 0x3F
curr_action_step_duration = current_action[action_step_duration]
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
# take care to rotate the action list!
@ -216,6 +253,8 @@ while True: # Loop forever...
if curr_action:
is_act_cycling = (ACT_CYCLING_RING_ACLK or ACT_CYCLING_RING_CLKW)
if curr_action == ACT_NOP:
# rather trivial even tho this will be repeated as long as the
# NOP continues - i could have prevented it from repeating
@ -229,7 +268,7 @@ while True: # Loop forever...
for i in range(0, numpix):
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
if curr_action == ACT_CYCLING_RING_ACLK:
idx += 1
@ -242,7 +281,7 @@ while True: # Loop forever...
# set the new color, if there is one
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
# the current offset
for idx in range(0, numpix):

View file

@ -1,7 +1,8 @@
import time
from digitalio import DigitalInOut, Direction
import board
import neopixel
from digitalio import DigitalInOut, Direction
pixpin = board.D1
numpix = 8
@ -11,6 +12,7 @@ led.direction = Direction.OUTPUT
strip = neopixel.NeoPixel(pixpin, numpix, brightness=1, auto_write=True)
def wheel(pos):
# Input a value 0 to 255 to get a color value.
# 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)
elif pos < 170:
pos -= 85
return (int(255 - pos*3), 0, int(pos*3))
return (int(255 - pos * 3), 0, int(pos * 3))
else:
pos -= 170
return (0, int(pos*3), int(255 - pos*3))
return (0, int(pos * 3), int(255 - pos * 3))
def rainbow_cycle(wait):
for j in range(255*5):
for j in range(255 * 5):
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)
time.sleep(wait)
def rainbow(wait):
for j in range(255):
for i in range(len(strip)):
idx = int (i+j)
idx = int(i + j)
strip[i] = wheel(idx & 255)
time.sleep(wait)
while True:
rainbow_cycle(0.05)

View file

@ -1,4 +1,5 @@
import time
import board
import pulseio
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 = DigitalInOut(board.D2)
digital_leds.direction = Direction.OUTPUT
brightness = 0 # how bright the LED is
fade_amount = 1285 # 2% steping of 2^16
counter = 0 # counter to keep track of cycles
brightness = 0 # how bright the LED is
fade_amount = 1285 # 2% steping of 2^16
counter = 0 # counter to keep track of cycles
while True:

View file

@ -1,24 +1,23 @@
import adafruit_fancyled.adafruit_fancyled as fancy
import board
import neopixel
import time
from digitalio import DigitalInOut, Direction, Pull
import adafruit_fancyled.adafruit_fancyled as fancy
from digitalio import DigitalInOut, Direction, Pull
led_pin = board.D1 # which pin your pixels are connected to
num_leds = 78 # how many LEDs you have
brightness = 1.0 # 0-1, higher number is brighter
saturation = 255 # 0-255, 0 is pure white, 255 is fully saturated color
steps = 0.01 # how wide the bands of color are.
offset = 0 # cummulative steps
fadeup = True # start with fading up - increase steps until offset reaches 1
index = 8 # midway color selection
blend = True # color blending between palette indices
led_pin = board.D1 # which pin your pixels are connected to
num_leds = 78 # how many LEDs you have
brightness = 1.0 # 0-1, higher number is brighter
saturation = 255 # 0-255, 0 is pure white, 255 is fully saturated color
steps = 0.01 # how wide the bands of color are.
offset = 0 # cummulative steps
fadeup = True # start with fading up - increase steps until offset reaches 1
index = 8 # midway color selection
blend = True # color blending between palette indices
# 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
# No auto-write.
# No auto-write.
# Set brightness to max.
# We will be using FancyLED's brightness control.
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.pull = Pull.UP
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:
# * The first (5) palettes here are mixing between 2-elements
# * The last (3) palettes use a format identical to the FastLED Arduino Library
# see FastLED - colorpalettes.cpp
forest = [ fancy.CRGB( 0, 255, 0 ), # green
fancy.CRGB( 255, 255, 0) ] # yellow
forest = [fancy.CRGB(0, 255, 0), # green
fancy.CRGB(255, 255, 0)] # yellow
ocean = [ fancy.CRGB( 0, 0, 255 ), # blue
fancy.CRGB( 0, 255, 0 ) ] # green
ocean = [fancy.CRGB(0, 0, 255), # blue
fancy.CRGB(0, 255, 0)] # green
purple = [ fancy.CRGB( 160, 32, 240 ), # purple
fancy.CRGB( 238, 130, 238 ) ] # violet
purple = [fancy.CRGB(160, 32, 240), # purple
fancy.CRGB(238, 130, 238)] # violet
all_colors = [ fancy.CRGB( 0, 0, 0 ), # black
fancy.CRGB( 255, 255, 255 ) ] # white
all_colors = [fancy.CRGB(0, 0, 0), # black
fancy.CRGB(255, 255, 255)] # white
washed_out = [ fancy.CRGB( 0, 0, 0 ), # black
fancy.CRGB( 255, 0, 255 ) ] # purple
washed_out = [fancy.CRGB(0, 0, 0), # black
fancy.CRGB(255, 0, 255)] # purple
rainbow = [ 0xFF0000, 0xD52A00, 0xAB5500, 0xAB7F00,
0xABAB00, 0x56D500, 0x00FF00, 0x00D52A,
0x00AB55, 0x0056AA, 0x0000FF, 0x2A00D5,
0x5500AB, 0x7F0081, 0xAB0055, 0xD5002B ]
rainbow = [0xFF0000, 0xD52A00, 0xAB5500, 0xAB7F00,
0xABAB00, 0x56D500, 0x00FF00, 0x00D52A,
0x00AB55, 0x0056AA, 0x0000FF, 0x2A00D5,
0x5500AB, 0x7F0081, 0xAB0055, 0xD5002B]
rainbow_stripe= [ 0xFF0000, 0x000000, 0xAB5500, 0x000000,
0xABAB00, 0x000000, 0x00FF00, 0x000000,
0x00AB55, 0x000000, 0x0000FF, 0x000000,
0x5500AB, 0x000000, 0xAB0055, 0x000000 ]
rainbow_stripe = [0xFF0000, 0x000000, 0xAB5500, 0x000000,
0xABAB00, 0x000000, 0x00FF00, 0x000000,
0x00AB55, 0x000000, 0x0000FF, 0x000000,
0x5500AB, 0x000000, 0xAB0055, 0x000000]
heat_colors = [ 0x330000, 0x660000, 0x990000, 0xCC0000, 0xFF0000,
0xFF3300, 0xFF6600, 0xFF9900, 0xFFCC00, 0xFFFF00,
0xFFFF33, 0xFFFF66, 0xFFFF99, 0xFFFFCC ]
heat_colors = [0x330000, 0x660000, 0x990000, 0xCC0000, 0xFF0000,
0xFF3300, 0xFF6600, 0xFF9900, 0xFFCC00, 0xFFFF00,
0xFFFF33, 0xFFFF66, 0xFFFF99, 0xFFFFCC]
def wheel(pos):
# Input a value 0 to 255 to get a color value.
# The colours are a transition r - g - b - back to r.
if (pos < 0) or (pos > 255):
return (0, 0, 0)
if (pos < 85):
return (int(pos * 3), int(255 - (pos*3)), 0)
elif (pos < 170):
if pos < 85:
return (int(pos * 3), int(255 - (pos * 3)), 0)
elif pos < 170:
pos -= 85
return (int(255 - pos*3), 0, int(pos*3))
return (int(255 - pos * 3), 0, int(pos * 3))
else:
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):
# this remaps a value from original (left) range to new (right) range
# this remaps a value fromhere original (left) range to new (right) range
# Figure out how 'wide' each range is
leftSpan = leftMax - leftMin
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.
return int(rightMin + (valueScaled * rightSpan))
def shortkeypress(color_palette):
def shortkeypress(color_palette):
color_palette += 1
if ( color_palette > 6):
if color_palette > 6:
color_palette = 1
return ( color_palette )
return color_palette
while True:
while True:
# check for button press
currkeystate = button.value
# button press, move to next pattern
if ( ( prevkeystate == False ) and ( currkeystate == True ) ):
if (prevkeystate is not True) and currkeystate:
ledmode = shortkeypress(ledmode)
# save button press state
prevkeystate = currkeystate
# Fire Colors [ HEAT ]
if ( ledmode == 1 ):
if ledmode == 1:
palette = heat_colors
# Forest
elif ( ledmode == 2 ):
elif ledmode == 2:
palette = forest
# Ocean
elif ( ledmode == 3 ):
elif ledmode == 3:
palette = ocean
# Purple Lovers
elif ( ledmode == 4 ):
elif ledmode == 4:
palette = purple
# All the colors!
elif ( ledmode == 5 ):
elif ledmode == 5:
palette = rainbow
# Rainbow stripes
elif ( ledmode == 6 ):
elif ledmode == 6:
palette = rainbow_stripe
# All the colors except the greens, washed out
elif ( ledmode == 7 ):
elif ledmode == 7:
palette = washed_out
for i in range(num_leds):
color = fancy.palette_lookup(palette, offset + i / num_leds)
color = fancy.gamma_adjust(color, brightness=brightness)
strip[i] = color.pack()
strip.show()
if ( fadeup ):
if fadeup:
offset += steps
if ( offset >= 1 ):
if offset >= 1:
fadeup = False
else:
else:
offset -= steps
if ( offset <= 0 ):
if offset <= 0:
fadeup = True

View file

@ -1,9 +1,10 @@
# Annoy-O-Matic Sound Prank Device
# choose from a variety of sounds and timings to drive your victim bonkers
import pulseio
import board
import time
import board
import pulseio
piezo = pulseio.PWMOut(board.D0, duty_cycle=0, frequency=440,
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):
for r in range(repeat):
for _ in range(repeat):
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
piezo.duty_cycle = 0 # off
time.sleep(rest)
time.sleep(interval) # wait time until next beep
def annoy_doorbell(interval):
piezo.frequency = 740
piezo.duty_cycle = 65536//2
piezo.duty_cycle = 65536 // 2
time.sleep(0.85)
piezo.duty_cycle = 0
time.sleep(0.05)
piezo.frequency = 588
piezo.duty_cycle = 65536//2
piezo.duty_cycle = 65536 // 2
time.sleep(1.25)
piezo.duty_cycle = 0
time.sleep(interval)
def annoy_ringtone(ringtone, tempo, interval):
# ringtone 1: Nokia
# 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
# set up time signature
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
half_note = whole_note / 2
dotted_half_note = half_note * 1.5
# half_note = whole_note / 2
# dotted_half_note = half_note * 1.5
quarter_note = whole_note / 4
dotted_quarter_note = quarter_note * 1.5
# dotted_quarter_note = quarter_note * 1.5
eighth_note = whole_note / 8
dotted_eighth_note = eighth_note * 1.5
sixteenth_note = whole_note / 16
# set up note values
A2 = 110
As2 = 117 # 's' stands for sharp: A#2
Bb2 = 117
B2 = 123
# A2 = 110
# As2 = 117 # 's' stands for sharp: A#2
# Bb2 = 117
# B2 = 123
C3 = 131
Cs3 = 139
Db3 = 139
D3 = 147
Ds3 = 156
Eb3 = 156
E3 = 165
F3 = 175
Fs3 = 185
Gb3 = 185
G3 = 196
Gs3 = 208
Ab3 = 208
# C3 = 131
# Cs3 = 139
# Db3 = 139
# D3 = 147
# Ds3 = 156
# Eb3 = 156
# E3 = 165
# F3 = 175
# Fs3 = 185
# Gb3 = 185
# G3 = 196
# Gs3 = 208
# Ab3 = 208
A3 = 220
As3 = 233
Bb3 = 233
# As3 = 233
# Bb3 = 233
B3 = 247
C4 = 262
# C4 = 262
Cs4 = 277
Db4 = 277
# Db4 = 277
D4 = 294
Ds4 = 311
Eb4 = 311
# Ds4 = 311
# Eb4 = 311
E4 = 330
F4 = 349
# F4 = 349
Fs4 = 370
Gb4 = 370
# Gb4 = 370
G4 = 392
Gs4 = 415
Ab4 = 415
A4 = 440
As4 = 466
Bb4 = 466
# Gs4 = 415
# Ab4 = 415
# A4 = 440
# As4 = 466
# Bb4 = 466
B4 = 494
C5 = 523
# C5 = 523
Cs5 = 554
Db5 = 554
# Db5 = 554
D5 = 587
Ds5 = 622
Eb5 = 622
# Ds5 = 622
# Eb5 = 622
E5 = 659
F5 = 698
# F5 = 698
Fs5 = 740
Gb5 = 740
G5 = 784
# Gb5 = 740
# G5 = 784
Gs5 = 831
Ab5 = 831
# Ab5 = 831
A5 = 880
As5 = 932
Bb5 = 932
# As5 = 932
# Bb5 = 932
B5 = 987
# here's another way to express the note pitch, double the previous octave
C6 = C5 * 2
# C6 = C5 * 2
Cs6 = Cs5 * 2
Db6 = Db5 * 2
D6 = D5 * 2
Ds6 = Ds5 * 2
Eb6 = Eb5 * 2
# Db6 = Db5 * 2
D6 = D5 * 2
# Ds6 = Ds5 * 2
# Eb6 = Eb5 * 2
E6 = E5 * 2
F6 = F5 * 2
Fs6 = Fs5 * 2
Gb6 = Gb5 * 2
G6 = G5 * 2
Gs6 = Gs5 * 2
Ab6 = Ab5 * 2
A6 = A5 * 2
As6 = As5 * 2
Bb6 = Bb5 * 2
B6 = B5 * 2
# F6 = F5 * 2
# Fs6 = Fs5 * 2
# Gb6 = Gb5 * 2
# G6 = G5 * 2
# Gs6 = Gs5 * 2
# Ab6 = Ab5 * 2
# A6 = A5 * 2
# As6 = As5 * 2
# Bb6 = Bb5 * 2
# B6 = B5 * 2
if ringtone == 1:
# Nokia
@ -162,7 +165,7 @@ def annoy_ringtone(ringtone, tempo, interval):
for n in range(len(nokia_ringtone)):
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
piezo.duty_cycle = 0 # off
time.sleep(0.01)
@ -178,64 +181,67 @@ def annoy_ringtone(ringtone, tempo, interval):
for n in range(len(iPhone_ringtone)):
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
piezo.duty_cycle = 0 # off
time.sleep(0.01)
if ringtone == 3:
# Rickroll
rick_ringtone = [[A3, sixteenth_note], [B3, sixteenth_note],
[D4, sixteenth_note], [B3, sixteenth_note],
[Fs4, dotted_eighth_note], [Fs4, sixteenth_note],
[Fs4, eighth_note], [E4, eighth_note],
[E4, quarter_note],
[A3, sixteenth_note], [B3, sixteenth_note],
[Cs4, sixteenth_note], [A3, sixteenth_note],
[E4, dotted_eighth_note], [E4, sixteenth_note],
[E4, eighth_note], [D4, eighth_note],
[D4, sixteenth_note], [Cs4, sixteenth_note],
[B3, eighth_note]]
rick_ringtone = [[A3, sixteenth_note], [B3, sixteenth_note],
[D4, sixteenth_note], [B3, sixteenth_note],
[Fs4, dotted_eighth_note], [Fs4, sixteenth_note],
[Fs4, eighth_note], [E4, eighth_note],
[E4, quarter_note],
[A3, sixteenth_note], [B3, sixteenth_note],
[Cs4, sixteenth_note], [A3, sixteenth_note],
[E4, dotted_eighth_note], [E4, sixteenth_note],
[E4, eighth_note], [D4, eighth_note],
[D4, sixteenth_note], [Cs4, sixteenth_note],
[B3, eighth_note]]
for n in range(len(rick_ringtone)):
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
piezo.duty_cycle = 0 # off
time.sleep(0.035)
time.sleep(interval)
def annoy_crickets(repeat, interval):
for i in range(repeat):
for r in range(6):
for _ in range(repeat):
for _ in range(6):
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
piezo.duty_cycle = 0 # off
time.sleep(0.05)
time.sleep(0.2)
time.sleep(interval) # wait time until next beep
def annoy_teen_tone(interval):
piezo.frequency = 17400
piezo.duty_cycle = 65536//2 # on 50%
piezo.duty_cycle = 65536 // 2 # on 50%
time.sleep(10)
piezo.duty_cycle = 0
time.sleep(interval)
while True:
if annoy_mode is 1:
if annoy_mode == 1:
annoy_beep(frequency, length, repeat, rest, interval)
elif annoy_mode is 2:
elif annoy_mode == 2:
annoy_doorbell(interval)
elif annoy_mode is 3:
elif annoy_mode == 3:
annoy_ringtone(ringtone, ringtone_tempo, interval)
elif annoy_mode is 4:
elif annoy_mode == 4:
annoy_crickets(repeat, interval)
elif annoy_mode is 5:
elif annoy_mode == 5:
annoy_teen_tone(interval)
elif annoy_mode is 6:
elif annoy_mode == 6:
annoy_beep(5000, 0.2, 2, 0.05, 3)
annoy_doorbell(3)
annoy_ringtone(1, 0.9, 3)

View file

@ -1,8 +1,9 @@
import digitalio
from board import *
import time
import digitalio
from adafruit_hid.keyboard import Keyboard
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

View file

@ -1,8 +1,8 @@
import time
import board
import busio
import adafruit_CCS811
import board
import busio
import neopixel
# i2c interface for the gas sensor
@ -13,11 +13,11 @@ ccs = adafruit_CCS811.CCS811(i2c_bus)
# 1 - Temperature - Circuit Playground Built-In LEDs
# 2 - Total Volatile Organic Compounds [strip]
# 3 - Co2 Output - NeoPixel [strip]
num_leds = 8
num_leds = 8
temperature_pix = neopixel.NeoPixel(board.NEOPIXEL, num_leds, 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)
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
while not ccs.data_ready:
@ -25,63 +25,76 @@ while not ccs.data_ready:
temp = ccs.temperature
ccs.temp_offset = temp - 25.0
# clear all LEDs for breathing effect
# clear all LEDs for breathing effect
def clear_pix(delay):
for i in range(0, num_leds):
temperature_pix[i] = (0,0,0)
co2_pix[i] = (0,0,0,0)
tvoc_pix[i] = (0,0,0,0)
temperature_pix[i] = (0, 0, 0)
co2_pix[i] = (0, 0, 0, 0)
tvoc_pix[i] = (0, 0, 0, 0)
time.sleep(delay)
# Show Carbon Dioxide on a NeoPixel Strip
def co2_led_meter():
co2_floor = 400
co2_ceiling = 8192
# 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_leds = int( (ccs.eCO2 - co2_floor ) / co2_led_steps)
co2_leds = int((ccs.eCO2 - co2_floor) / co2_led_steps)
# Insert Colors
for i in range(0, (co2_leds - 1) ):
co2_pix[i] = (255,0,255,0)
for i in range(0, (co2_leds - 1)):
co2_pix[i] = (255, 0, 255, 0)
time.sleep(led_draw)
# Show Total Volatile Organic Compounds on a NeoPixel Strip
def tvoc_led_meter():
tvoc_floor = 0
tvoc_ceiling = 1187
# 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_leds = int(ccs.TVOC / tvoc_led_steps)
# Insert Colors
for i in range(0, (tvoc_leds - 1) ):
tvoc_pix[i] = (0,0,255,0)
for i in range(0, (tvoc_leds - 1)):
tvoc_pix[i] = (0, 0, 255, 0)
time.sleep(led_draw)
# Show Temperature on Circuit Playground built-in NeoPixels
def temp_led_meter():
temp_floor = 23
temp_ceiling = 36
# 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_leds = int( (ccs.temperature - temp_floor ) / temp_led_steps)
temp_leds = int((ccs.temperature - temp_floor) / temp_led_steps)
# Insert Colors
for i in range(0, (temp_leds - 1) ):
temperature_pix[i] = (255,255,0)
for i in range(0, (temp_leds - 1)):
temperature_pix[i] = (255, 255, 0)
time.sleep(led_draw)
while True:
# print to console
# - co2
# - total voltatile organic compounds
# - total voltatile organic compounds
# - temperature in celsius
print("CO2: ", ccs.eCO2, " TVOC:", ccs.TVOC, " temp:", ccs.temperature)

View file

@ -1,7 +1,8 @@
import time
import adafruit_sgp30
import board
import busio
import adafruit_sgp30
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_breath_result = 0
def warmup_message():
warmup_time = 20
def warmup_message():
warmup_time = 20
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("Warming Up [%d seconds]..." % warmup_time)
while ( warmup_counter <= 20 ):
while warmup_counter <= 20:
print('.', end='')
time.sleep(1)
warmup_counter += 1
def get_breath_reading():
breath_time = 30 # seconds to record breath reading
breath_counter = 0 # one second count up to breath_time value
breath_saves = [0] * ( breath_time + 1 ) # initialize list with empty values
def get_breath_reading():
breath_time = 30 # seconds to record breath reading
# one second count up to breath_time value
breath_counter = 0
# initialize list with empty values
breath_saves = [0] * (breath_time + 1)
print()
print("We will collect breath samples for 30 seconds.")
@ -40,27 +44,31 @@ def get_breath_reading():
input(" *** Press a key when ready. *** ")
print()
while ( breath_counter <= breath_time ):
co2eq, tvoc = sgp30.iaq_measure()
while breath_counter <= breath_time:
_, tvoc = sgp30.iaq_measure()
breath_saves[breath_counter] = tvoc
print(tvoc, ', ', end='')
time.sleep(1)
breath_counter += 1
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
def show_results(highest_breath_result):
def show_results(breath_result):
print()
print()
print("peak VOC reading:", highest_breath_result)
print("peak VOC reading:", breath_result)
print()
input("Press any key to test again")
print()
# main
while True:
warmup_message()

View file

@ -1,9 +1,10 @@
# Chilled Drinkibot
from digitalio import DigitalInOut, Direction, Pull
import board
import time
import board
from digitalio import DigitalInOut, Direction, Pull
led = DigitalInOut(board.D2) # Button LED
led.direction = Direction.OUTPUT
@ -17,7 +18,6 @@ chiller.direction = Direction.OUTPUT
pump = DigitalInOut(board.D4) # Pin to control the pump
pump.direction = Direction.OUTPUT
chillTime = 5 # How many _minutes_ of cooling
pumpTime = 35 # How many seconds of pumping
@ -26,18 +26,18 @@ while True:
# we could also just do "led.value = not button.value" !
if button.value:
print('not')
led.value = False # turn OFF LED
led.value = False # turn OFF LED
chiller.value = False # turn OFF chiller
pump.value = False # turn OFF pump
pump.value = False # turn OFF pump
else:
print('pressed')
led.value = True # turn ON LED
chiller.value = True # turn ON chiller
led.value = True # turn ON LED
chiller.value = True # turn ON chiller
time.sleep(chillTime * 60) # wait chiller time (in seconds)
chiller.value = False # turn OFF chiller
pump.value = True # turn ON pump
time.sleep(pumpTime) # wait pump time
pump.value = False # turn OFF pump
led.value = False # turn OFF LED
pump.value = True # turn ON pump
time.sleep(pumpTime) # wait pump time
pump.value = False # turn OFF pump
led.value = False # turn OFF LED
time.sleep(0.01) # debounce delay

View file

@ -1,23 +1,23 @@
import time
import machine
import adafruit_ssd1306
import bitbangio as io
import board
import network
import ntptime
import uhashlib
import ubinascii
import board
import bitbangio as io
import adafruit_ssd1306
import uhashlib
totp = [("Discord ", 'JBSWY3DPEHPK3PXP'), # https://github.com/pyotp/pyotp exmple
# https://github.com/pyotp/pyotp example
totp = [("Discord ", 'JBSWY3DPEHPK3PXP'),
("Gmail ", 'abcdefghijklmnopqrstuvwxyz234567'),
("Accounts", 'asfdkwefoaiwejfa323nfjkl')]
ssid = 'my_wifi_ssid'
ssid = 'my_wifi_ssid'
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!
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)
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.show()
time.sleep(0.25)
EPOCH_DELTA = 946684800 # seconds between year 2000 and year 1970
SECS_DAY = 86400
@ -52,6 +52,7 @@ def HMAC(k, m):
outer_message = KEY_OUTER + SHA1(inner_message).digest()
return SHA1(outer_message)
if TEST:
KEY = b'abcd'
MESSAGE = b'efgh'
@ -59,13 +60,16 @@ if TEST:
print("HMAC test: ", ubinascii.hexlify(HMAC(KEY, MESSAGE).digest()))
# should be e5dbcf9263188f9fce90df572afeb39b66b27198
# Base32 decoder, since base64 lib wouldnt fit
def base32_decode(encoded):
missing_padding = len(encoded) % 8
if missing_padding != 0:
encoded += '=' * (8 - missing_padding)
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 = []
for chunk in chunks:
@ -88,17 +92,21 @@ def base32_decode(encoded):
# great! we have enough to extract a byte
if bits >= 8:
bits -= 8
byte = bitbuff >> bits # grab top 8 bits
bitbuff &= ~(0xFF << bits) # and clear them
out.append(byte) # store what we got
byte = bitbuff >> bits # grab top 8 bits
bitbuff &= ~(0xFF << bits) # and clear them
out.append(byte) # store what we got
return out
if TEST:
print("===========================================")
print("Base32 test: ", bytes(base32_decode("IFSGCZTSOVUXIIJB")))
# should be "Adafruit!!"
# Turns an integer into a padded-with-0x0 bytestr
def int_to_bytestring(i, padding=8):
result = []
while i != 0:
@ -107,12 +115,18 @@ def int_to_bytestring(i, padding=8):
result = [0] * (padding - len(result)) + result
return bytes(result)
# HMAC -> OTP generator, pretty much same as
# 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')
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
code = ((hmac_hash[offset] & 0x7f) << 24 |
(hmac_hash[offset + 1] & 0xff) << 16 |
@ -121,9 +135,10 @@ def generate_otp(input, secret, digits=6):
str_code = str(code % 10 ** digits)
while len(str_code) < digits:
str_code = '0' + str_code
return str_code
print("===========================================")
# Set up networking
@ -152,7 +167,7 @@ t = None
while not t:
try:
t = ntptime.time()
except:
except Exception:
pass
time.sleep(0.1)
@ -168,23 +183,23 @@ print("Unix time: ", t)
mono_time = int(time.monotonic())
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):
# 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)
# Clear the screen
oled.fill(0)
y = 0
# We can do up to 3 per line on the Feather OLED
for name,secret in totp:
otp = generate_otp(unix_time//30, secret)
print(name + " OTP output: ", otp) # serial debugging output
oled.text(name + ": "+ str(otp), 0, y) # display name & OTP 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
oled.framebuf.line(0,31, 128 - (unix_time % 30)*4,31, True)
for name, secret in totp:
otp = generate_otp(unix_time // 30, secret)
print(name + " OTP output: ", otp) # serial debugging output
oled.text(name + ": " + str(otp), 0, y) # display name & OTP on OLED
y += 10 # Go to next line on OLED
# 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.show()
# We'll update every 1/4 second, we can hash very fast so its no biggie!
countdown -= 0.25

View file

@ -1,8 +1,9 @@
# CircuitPython AnalogIn Demo
import time
from analogio import AnalogIn
import board
from analogio import AnalogIn
analog_in = AnalogIn(board.A1)

View file

@ -1,7 +1,7 @@
# CircuitPython IO demo - analog output
from analogio import AnalogOut
import board
from analogio import AnalogOut
analog_out = AnalogOut(board.A0)

View file

@ -1,4 +1,5 @@
import time
import board
import touchio

View file

@ -2,6 +2,7 @@
# Example does NOT work with Trinket M0!
import time
import board
import touchio

View file

@ -1,19 +1,20 @@
# CircuitPython IO demo #1 - General Purpose I/O
import time
from digitalio import DigitalInOut, Direction, Pull
import board
from digitalio import DigitalInOut, Direction, Pull
led = DigitalInOut(board.D13)
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.D7) # For Circuit Playground Express
switch.direction = Direction.INPUT
switch.pull = Pull.UP
while True:
# We could also just do "led.value = not switch.value"!
if switch.value:

View file

@ -1,11 +1,13 @@
# CircuitPython demo - Dotstar
import time
import board
import adafruit_dotstar
import board
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):
@ -103,7 +105,8 @@ MAGENTA = (255, 0, 20)
WHITE = (255, 255, 255)
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(ORANGE, 0.5)
color_fill(GREEN, 0.5)
@ -114,12 +117,15 @@ while True:
color_fill(MAGENTA, 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)
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)
rainbow_cycle(0) # Increase this number to slow down the rainbow animation.
# Increase this number to slow down the rainbow animation.
rainbow_cycle(0)

View file

@ -1,11 +1,12 @@
# CircuitPython demo - Keyboard emulator
import time
import digitalio
import board
import digitalio
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
from adafruit_hid.keycode import Keycode
# A simple neat keyboard demo in CircuitPython

View file

@ -1,4 +1,5 @@
import time
import analogio
import board
import digitalio
@ -21,7 +22,8 @@ def get_voltage(pin):
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)

View file

@ -1,8 +1,9 @@
# CircuitPython demo - I2C scan
import time
import board
import busio
import time
i2c = busio.I2C(board.SCL, board.SDA)
@ -10,5 +11,6 @@ while not i2c.try_lock():
pass
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)

View file

@ -1,9 +1,10 @@
# CircuitPython Demo - I2C sensor
import time
import adafruit_tsl2561
import board
import busio
import adafruit_tsl2561
import time
i2c = busio.I2C(board.SCL, board.SDA)
@ -11,7 +12,8 @@ i2c = busio.I2C(board.SCL, board.SDA)
while not i2c.try_lock():
pass
# 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.
i2c.unlock()

View file

@ -1,11 +1,12 @@
import time
import board
import neopixel
import adafruit_dotstar
import board
# For Trinket M0, Gemma M0, and ItsyBitsy M0 Express
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.brightness = 0.3

View file

@ -1,11 +1,14 @@
import time
import board
import neopixel
import adafruit_dotstar
import board
# For Trinket M0, Gemma M0, and ItsyBitsy M0 Express
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)
@ -15,12 +18,12 @@ def wheel(pos):
if pos < 0 or pos > 255:
return 0, 0, 0
if pos < 85:
return int(255 - pos*3), int(pos*3), 0
return int(255 - pos * 3), int(pos * 3), 0
if pos < 170:
pos -= 85
return 0, int(255 - pos*3), int(pos*3)
return 0, int(255 - pos * 3), int(pos * 3)
pos -= 170
return int(pos * 3), 0, int(255 - (pos*3))
return int(pos * 3), 0, int(255 - (pos * 3))
led.brightness = 0.3

View file

@ -1,7 +1,8 @@
import time
import board
import digitalio
import microcontroller
import time
led = digitalio.DigitalInOut(board.D13)
led.switch_to_output()

View file

@ -1,5 +1,5 @@
import digitalio
import board
import digitalio
import storage
# For Gemma M0, Trinket M0, Metro M0 Express, ItsyBitsy M0 Express

View file

@ -1,13 +1,15 @@
# CircuitPython demo - NeoPixel
import time
import board
import neopixel
pixel_pin = board.A1
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):
@ -51,7 +53,8 @@ PURPLE = (180, 0, 255)
while True:
pixels.fill(RED)
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.show()
time.sleep(1)

View file

@ -1,6 +1,7 @@
# CircuitPython demo - NeoPixel RGBW
import time
import board
import neopixel
@ -8,7 +9,8 @@ pixel_pin = board.A1
num_pixels = 8
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):
@ -52,7 +54,8 @@ PURPLE = (180, 0, 255, 0)
while True:
pixels.fill(RED)
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.show()
time.sleep(1)

View file

@ -1,6 +1,7 @@
import time
import pulseio
import board
import pulseio
led = pulseio.PWMOut(board.D13, frequency=5000, duty_cycle=0)

View file

@ -1,17 +1,21 @@
import time
import pulseio
import board
import pulseio
# 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:
# 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:
for f in (262, 294, 330, 349, 392, 440, 494, 523):
piezo.frequency = f
piezo.duty_cycle = 65536 // 2 # On 50%
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.5)

View file

@ -1,4 +1,5 @@
import time
import board
import simpleio
@ -8,5 +9,5 @@ while True:
simpleio.tone(board.A2, f, 0.25) # on for 1/4 second
# For the Metro M4 Express:
# 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)

View file

@ -1,6 +1,7 @@
import time
import simpleio
import board
import simpleio
# For the M0 boards:
servo = simpleio.Servo(board.A2)

View file

@ -1,8 +1,8 @@
# CircuitPython Demo - USB/Serial echo
import digitalio
import board
import busio
import digitalio
led = digitalio.DigitalInOut(board.D13)
led.direction = digitalio.Direction.OUTPUT
@ -16,7 +16,8 @@ while True:
if data is not None:
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="")
led.value = False

View file

@ -9,5 +9,5 @@ for pin_name in dir(board):
print("PWM on:", pin_name) # Prints the valid, PWM-capable pins!
except ValueError: # This is the error returned when the pin is invalid.
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.

View file

@ -2,7 +2,7 @@ import board
import busio
def is_hardware_SPI(clock_pin, data_pin):
def is_hardware_spi(clock_pin, data_pin):
try:
p = busio.SPI(clock_pin, data_pin)
p.deinit()
@ -11,7 +11,8 @@ def is_hardware_SPI(clock_pin, data_pin):
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!")
else:
print("This pin combination isn't hardware SPI.")

View file

@ -2,7 +2,7 @@ import board
import busio
def is_hardware_UART(tx, rx):
def is_hardware_uart(tx, rx):
try:
p = busio.UART(tx, rx)
p.deinit()
@ -32,7 +32,7 @@ for tx_pin in get_unique_pins():
if rx_pin is tx_pin:
continue
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)
else:
pass

View file

@ -1,2 +1 @@
print('Hello, World!')

View file

@ -1,9 +1,11 @@
import sys
import adafruit_sdcard
import board
import busio
import digitalio
import board
import storage
import sys
# Connect to the card and mount the filesystem.
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
cs = digitalio.DigitalInOut(board.SD_CS)

View file

@ -1,9 +1,11 @@
import sys
import adafruit_sdcard
import board
import busio
import digitalio
import board
import storage
import sys
# Connect to the card and mount the filesystem.
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
cs = digitalio.DigitalInOut(board.SD_CS)

View file

@ -1,10 +1,11 @@
# Dotstar painter! Can handle up to ~2300 pixel size image (e.g. 36 x 64)
import board
import digitalio
import time
import gc
import time
import board
import busio
import digitalio
FILENAME = "blinka.bmp"
IMAGE_DELAY = 0.2
@ -23,6 +24,7 @@ databuf = bytearray(0)
led = digitalio.DigitalInOut(board.D13)
led.switch_to_output()
def read_le(s):
# as of this writting, int.from_bytes does not have LE support, DIY!
result = 0
@ -32,32 +34,33 @@ def read_le(s):
shift += 8
return result
class BMPError(Exception):
pass
try:
with open("/"+FILENAME, "rb") as f:
with open("/" + FILENAME, "rb") as f:
print("File opened")
if f.read(2) != b'BM': # check signature
raise BMPError("Not BitMap file")
bmpFileSize = read_le(f.read(4))
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))
bmpWidth = read_le(f.read(4))
bmpHeight = read_le(f.read(4))
flip = True
print("Size: %d\nImage offset: %d\nHeader size: %d" %
(bmpFileSize, bmpImageoffset, headerSize))
print("Width: %d\nHeight: %d" % (bmpWidth, bmpHeight))
if read_le(f.read(2)) != 1:
raise BMPError("Not singleplane")
bmpDepth = read_le(f.read(2)) # bits per pixel
raise BMPError("Not singleplane")
bmpDepth = read_le(f.read(2)) # bits per pixel
print("Bit depth: %d" % (bmpDepth))
if bmpDepth != 24:
raise BMPError("Not 24-bit")
@ -66,36 +69,38 @@ try:
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...
if(flip): # Bitmap is stored bottom-to-top order (normal BMP)
for row in range(bmpHeight): # For each scanline...
if flip: # Bitmap is stored bottom-to-top order (normal BMP)
pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize
else: # Bitmap is stored top-to-bottom
pos = bmpImageoffset + row * rowSize;
#print ("seek to %d" % pos)
else: # Bitmap is stored top-to-bottom
pos = bmpImageoffset + row * rowSize
# print ("seek to %d" % pos)
f.seek(pos)
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!
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'
idx += 1
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
except OSError as e:
if e.args[0] == 28:
halt("OS Error 28", 0.25)
raise OSError("OS Error 28 0.25")
else:
halt("OS Error ", 0.5)
raise OSError("OS Error 0.5")
except BMPError as e:
print("Failed to parse BMP: "+e.args[0])
print("Failed to parse BMP: " + e.args[0])
gc.collect()
print(gc.mem_free())
@ -105,13 +110,13 @@ while True:
index = 0
for col in range(bmpWidth):
row = databuf[index:index+bmpHeight*4]
dotstar.write(bytearray([0x00, 0x00, 0x00, 0x00] ))
row = databuf[index:index + bmpHeight * 4]
dotstar.write(bytearray([0x00, 0x00, 0x00, 0x00]))
dotstar.write(row)
dotstar.write(bytearray([0x00, 0x00, 0x00, 0x00]))
index += bmpHeight * 4
time.sleep(PIXEL_DELAY)
# clear it out
dotstar.write(bytearray([0x00, 0x00, 0x00, 0x00]))
for r in range(bmpHeight * 5):

View file

@ -1,8 +1,9 @@
# CircuitPython AnalogIn Demo
import time
from analogio import AnalogIn
import board
from analogio import AnalogIn
analog_in = AnalogIn(board.A1)

View file

@ -1,7 +1,7 @@
# CircuitPython IO demo - analog output
from analogio import AnalogOut
import board
from analogio import AnalogOut
analog_out = AnalogOut(board.A0)

View file

@ -1,4 +1,5 @@
import time
import board
import touchio

View file

@ -2,6 +2,7 @@
# Example does NOT work with Trinket M0!
import time
import board
import touchio

View file

@ -1,19 +1,20 @@
# CircuitPython IO demo #1 - General Purpose I/O
import time
from digitalio import DigitalInOut, Direction, Pull
import board
from digitalio import DigitalInOut, Direction, Pull
led = DigitalInOut(board.D13)
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.D7) # For Circuit Playground Express
switch.direction = Direction.INPUT
switch.pull = Pull.UP
while True:
# We could also just do "led.value = not switch.value"!
if switch.value:

View file

@ -1,11 +1,13 @@
# CircuitPython demo - Dotstar
import time
import board
import adafruit_dotstar
import board
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):
@ -103,7 +105,8 @@ MAGENTA = (255, 0, 20)
WHITE = (255, 255, 255)
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(ORANGE, 0.5)
color_fill(GREEN, 0.5)
@ -114,12 +117,15 @@ while True:
color_fill(MAGENTA, 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)
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)
rainbow_cycle(0) # Increase this number to slow down the rainbow animation.
# Increase this number to slow down the rainbow animation.
rainbow_cycle(0)

View file

@ -1,7 +1,7 @@
import time
import board
import neopixel
import adafruit_dotstar
import board
# For Trinket M0, Gemma M0, and ItsyBitsy M0 Express
led = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1)

View file

@ -1,10 +1,12 @@
import time
import board
import neopixel
import adafruit_dotstar
import board
# For Trinket M0, Gemma M0, and ItsyBitsy M0 Express
led = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1)
# For Feather M0 Express, Metro M0 Express, and Circuit Playground Express
# led = neopixel.NeoPixel(board.NEOPIXEL, 1)
@ -15,12 +17,12 @@ def wheel(pos):
if pos < 0 or pos > 255:
return 0, 0, 0
if pos < 85:
return int(255 - pos*3), int(pos*3), 0
return int(255 - pos * 3), int(pos * 3), 0
if pos < 170:
pos -= 85
return 0, int(255 - pos*3), int(pos*3)
return 0, int(255 - pos * 3), int(pos * 3)
pos -= 170
return int(pos * 3), 0, int(255 - (pos*3))
return int(pos * 3), 0, int(255 - (pos * 3))
led.brightness = 0.3

View file

@ -1,13 +1,15 @@
# CircuitPython demo - NeoPixel
import time
import board
import neopixel
pixel_pin = board.A1
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):
@ -51,7 +53,8 @@ PURPLE = (180, 0, 255)
while True:
pixels.fill(RED)
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.show()
time.sleep(1)

View file

@ -1,6 +1,7 @@
# CircuitPython demo - NeoPixel RGBW
import time
import board
import neopixel
@ -8,7 +9,8 @@ pixel_pin = board.A1
num_pixels = 8
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):
@ -52,7 +54,8 @@ PURPLE = (180, 0, 255, 0)
while True:
pixels.fill(RED)
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.show()
time.sleep(1)

View file

@ -1,6 +1,7 @@
import time
import pulseio
import board
import pulseio
led = pulseio.PWMOut(board.D13, frequency=5000, duty_cycle=0)

View file

@ -1,14 +1,16 @@
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:
for f in (262, 294, 330, 349, 392, 440, 494, 523):
piezo.frequency = f
piezo.duty_cycle = 65536 // 2 # On 50%
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.5)

View file

@ -1,9 +1,10 @@
import time
import board
import simpleio
while True:
for f in (262, 294, 330, 349, 392, 440, 494, 523):
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)

View file

@ -1,6 +1,7 @@
import time
import simpleio
import board
import simpleio
servo = simpleio.Servo(board.A2)

View file

@ -1,8 +1,8 @@
# CircuitPython Demo - USB/Serial echo
import digitalio
import board
import busio
import digitalio
led = digitalio.DigitalInOut(board.D13)
led.direction = digitalio.Direction.OUTPUT
@ -16,7 +16,8 @@ while True:
if data is not None:
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="")
led.value = False

View file

@ -9,5 +9,5 @@ for pin_name in dir(board):
print("PWM on:", pin_name) # Prints the valid, PWM-capable pins!
except ValueError: # This is the error returned when the pin is invalid.
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.

View file

@ -11,7 +11,8 @@ def is_hardware_SPI(clock_pin, data_pin):
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!")
else:
print("This pin combination isn't hardware SPI.")

View file

@ -1,10 +1,11 @@
import board
import array
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.direction = Direction.INPUT
switch.pull = Pull.UP
@ -12,14 +13,14 @@ switch.pull = Pull.UP
led = DigitalInOut(board.D13)
led.direction = Direction.OUTPUT
############## Speaker as haptic feedback
# Speaker as haptic feedback
spkr_en = DigitalInOut(board.SPEAKER_ENABLE)
spkr_en.direction = Direction.OUTPUT
spkr_en.value = True
spkr = DigitalInOut(board.SPEAKER)
spkr.direction = Direction.OUTPUT
############## Allow any button to trigger activity!
# Allow any button to trigger activity!
button_a = DigitalInOut(board.BUTTON_A)
button_a.direction = Direction.INPUT
button_a.pull = Pull.DOWN
@ -27,8 +28,8 @@ button_b = DigitalInOut(board.BUTTON_B)
button_b.direction = Direction.INPUT
button_b.pull = Pull.DOWN
pwm = pulseio.PWMOut(board.REMOTEOUT, frequency=38000, duty_cycle=2 ** 15, variable_frequency=True)
pwm = pulseio.PWMOut(board.REMOTEOUT, frequency=38000,
duty_cycle=2 ** 15, variable_frequency=True)
pulse = pulseio.PulseOut(pwm)
while True:
@ -36,7 +37,7 @@ while True:
while not (button_a.value or button_b.value):
pass
time.sleep(0.5) # Give a half second before starting
# gooooo!
f = open("/codes.txt", "r")
for line in f:
@ -50,7 +51,7 @@ while True:
try:
repeat = code['repeat']
delay = code['repeat_delay']
except KeyError: # by default, repeat once only!
except KeyError: # by default, repeat once only!
repeat = 1
delay = 0
# The table holds the on/off pairs
@ -65,9 +66,9 @@ while True:
for i in range(repeat):
pulse.send(array.array('H', pulses))
time.sleep(delay)
led.value = False
spkr.value = False
time.sleep(code['delay'])
f.close()

View file

@ -1,24 +1,26 @@
# Gemma M0 version of TVBgone!
import board
import array
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))
# Button to see output debug
led = DigitalInOut(board.D13)
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)
time.sleep(0.5) # Give a half second before starting
# gooooo!
f = open("/codes.txt", "r")
for line in f:
@ -30,7 +32,7 @@ for line in f:
try:
repeat = code['repeat']
delay = code['repeat_delay']
except KeyError: # by default, repeat once only!
except KeyError: # by default, repeat once only!
repeat = 1
delay = 0
# The table holds the on/off pairs
@ -46,5 +48,5 @@ for line in f:
time.sleep(delay)
led.value = False
time.sleep(code['delay'])
f.close()

View file

@ -4,20 +4,21 @@
# Photocell voltage divider center wire to GPIO #2 (analog 1)
# and output tone to GPIO #0 (digital 0)
import board
import analogio
import time
import analogio
import board
import neopixel
import simpleio
# Initialize input/output pins
photocell_pin = board.A1 # cds photocell connected to this ANALOG pin
speaker_pin = board.D0 # speaker is connected to this DIGITAL pin
pixpin = board.D1 # pin where NeoPixels are connected
numpix = 10 # number of neopixels`
darkness_min = (2**16 / 2) # more dark than light > 32k out of 64k
photocell_pin = board.A1 # cds photocell connected to this ANALOG pin
speaker_pin = board.D0 # speaker is connected to this DIGITAL pin
pixpin = board.D1 # pin where NeoPixels are connected
numpix = 10 # number of neopixels`
darkness_min = (2 ** 16 / 2) # more dark than light > 32k out of 64k
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
toned = 294
@ -26,66 +27,68 @@ tonec = 262
toneC = 130
toneg = 392
def alien():
strip[8] = (255, 255, 0) # yellow front
strip[3] = (255, 255, 0) # yellow back
simpleio.tone(speaker_pin, toned, 1) # play tone for 1 second
def alien():
strip[8] = (255, 255, 0) # yellow front
strip[3] = (255, 255, 0) # yellow back
simpleio.tone(speaker_pin, toned, 1) # play tone for 1 second
time.sleep(.025)
strip[8] = (0, 0, 0) # clear front
strip[3] = (0, 0, 0) # clear back
strip[8] = (0, 0, 0) # clear front
strip[3] = (0, 0, 0) # clear back
time.sleep(.025)
strip[7] = (255, 0, 255) # pink front
strip[2] = (255, 0, 255) # pink back
simpleio.tone(speaker_pin, tonee, 1) # play tone for 1 second
strip[7] = (255, 0, 255) # pink front
strip[2] = (255, 0, 255) # pink back
simpleio.tone(speaker_pin, tonee, 1) # play tone for 1 second
time.sleep(.025)
strip[7] = (0, 0, 0) # clear front
strip[2] = (0, 0, 0) # clear back
strip[7] = (0, 0, 0) # clear front
strip[2] = (0, 0, 0) # clear back
time.sleep(.025)
strip[4] = (128, 255, 0) # green front
strip[9] = (128, 255, 0) # green back
simpleio.tone(speaker_pin, tonec, 1) # play tone for 1 second
strip[4] = (128, 255, 0) # green front
strip[9] = (128, 255, 0) # green back
simpleio.tone(speaker_pin, tonec, 1) # play tone for 1 second
time.sleep(.025)
strip[4] = (0, 0, 0) # clear front
strip[9] = (0, 0, 0) # clear back
strip[4] = (0, 0, 0) # clear front
strip[9] = (0, 0, 0) # clear back
time.sleep(.025)
strip[5] = (0, 0, 255) # blue front
strip[0] = (0, 0, 255) # blue back
simpleio.tone(speaker_pin, toneC, 1) # play tone for 1 second
strip[5] = (0, 0, 255) # blue front
strip[0] = (0, 0, 255) # blue back
simpleio.tone(speaker_pin, toneC, 1) # play tone for 1 second
time.sleep(.075)
strip[5] = (0, 0, 0) # clear front
strip[0] = (0, 0, 0) # clear back
strip[5] = (0, 0, 0) # clear front
strip[0] = (0, 0, 0) # clear back
time.sleep(.1)
strip[6] = (255, 0, 0) # red front
strip[1] = (255, 0, 0) # red back
simpleio.tone(speaker_pin, toneg, 1) # play tone for 1 second
strip[6] = (255, 0, 0) # red front
strip[1] = (255, 0, 0) # red back
simpleio.tone(speaker_pin, toneg, 1) # play tone for 1 second
time.sleep(.1)
strip[6] = (0, 0, 0) # clear front
strip[1] = (0, 0, 0) # clear back
strip[6] = (0, 0, 0) # clear front
strip[1] = (0, 0, 0) # clear back
time.sleep(.1)
# 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)
if ( photocell.value > darkness_min ):
alien() # close Encounters Loop
if photocell.value > darkness_min:
alien() # close Encounters Loop

View file

@ -2,22 +2,26 @@
# for Adafruit Circuit Playground express
# with CircuitPython
from adafruit_circuitplayground.express import cpx
import time
import board
import simpleio
from adafruit_circuitplayground.express import cpx
# plug red servo wire to VOUT, brown to GND, yellow to A3
servo = simpleio.Servo(board.A3)
cpx.pixels.brightness = 0.05 # set brightness value
def unlock_servo():
servo.angle = 180
def lock_servo():
servo.angle = 90
correct_combo = ['B', 'D', 'C'] # this is where to set the combo
entered_combo = [] # this will be used to store attempts
current_dial_position = 'X'
@ -74,7 +78,8 @@ while True:
if cpx.button_a: # this means the button has been pressed
# grab the current_dial_position value and add to the list
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)
cpx.play_tone(320, 0.3) # beep
time.sleep(1) # slow down button checks

View file

@ -1,11 +1,12 @@
# 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 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)
ss = Seesaw(i2c)
@ -14,22 +15,22 @@ print("Bubble machine!")
SERVOS = True
DCMOTORS = True
#################### Create 4 Servos
# Create 4 Servos
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.frequency = 50
pwm.frequency = 50
_servo = servo.Servo(pwm)
_servo.angle = 90 # starting angle, middle
_servo.angle = 90 # starting angle, middle
servos.append(_servo)
#################### Create 2 DC motors
# Create 2 DC motors
motors = []
if DCMOTORS:
for ss_pin in ((18, 19), (22, 23)):
pwm0 = PWMOut(ss, ss_pin[0])
pwm1 = PWMOut(ss, ss_pin[1])
for ss_pin in ((18, 19), (22, 23)):
pwm0 = PWMOut(ss, ss_pin[0])
pwm1 = PWMOut(ss, ss_pin[1])
_motor = motor.DCMotor(pwm0, pwm1)
motors.append(_motor)
@ -45,4 +46,4 @@ while True:
motors[0].throttle = 0
print("servo up")
servos[0].angle = 0
time.sleep(1)
time.sleep(1)

View file

@ -1,65 +1,68 @@
# 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 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)
ss = Seesaw(i2c)
print("Feynbot demo!")
#################### 1 Servo
# 1 Servo
pwm = PWMOut(ss, 17)
pwm.frequency = 50
myservo = servo.Servo(pwm)
myservo.angle = 180 # starting angle, highest
myservo.angle = 180 # starting angle, highest
#################### 2 Drivers
# 2 Drivers
drives = []
for ss_pin in (13, 12):
_pwm = PWMOut(ss, ss_pin)
_pwm.frequency = 1000
drives.append(_pwm)
#################### Audio files
# Audio files
wavfiles = ["01.wav", "02.wav", "03.wav", "04.wav", "05.wav"]
a = audioio.AudioOut(board.A0)
# Start playing the file (in the background)
def play_file(wavfile):
f = open(wavfile, "rb")
wav = audioio.WaveFile(f)
a.play(wav)
# Tap the solenoids back and forth
def bongo(t):
for _ in range(t):
drives[0].duty_cycle = 0xFFFF
time.sleep(0.1)
drives[0].duty_cycle = 0
time.sleep(0.1)
drives[1].duty_cycle = 0xFFFF
time.sleep(0.1)
drives[1].duty_cycle = 0
time.sleep(0.1)
drives[0].duty_cycle = 0xFFFF
time.sleep(0.1)
drives[0].duty_cycle = 0
time.sleep(0.1)
drives[1].duty_cycle = 0xFFFF
time.sleep(0.1)
drives[1].duty_cycle = 0
time.sleep(0.1)
# Move mouth back and forth
def talk(t):
for _ in range(t):
myservo.angle = 150
time.sleep(0.1)
myservo.angle = 180
time.sleep(0.1)
myservo.angle = 150
time.sleep(0.1)
myservo.angle = 180
time.sleep(0.1)
filenum = 0 # counter to play all files
filenum = 0 # counter to play all files
while True:
gc.collect()
@ -73,13 +76,13 @@ while True:
play_file(wavfiles[filenum])
# and move the mouth while it does
while a.playing:
talk(1)
talk(1)
# Done being insightful, take a break
time.sleep(1)
# If we went thru all the files, JAM OUT!
filenum += 1
filenum += 1
if filenum >= len(wavfiles):
bongo(20)
filenum = 0
bongo(20)
filenum = 0

View file

@ -25,8 +25,10 @@
# 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:
# - Adafruit CircuitPython DotStar: https://github.com/adafruit/Adafruit_CircuitPython_DotStar
# - Adafruit CircuitPython FancyLED: https://github.com/adafruit/Adafruit_CircuitPython_FancyLED
# - Adafruit CircuitPython DotStar:
# 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
# and files within it on your board for this code to work! If you run into
@ -38,51 +40,49 @@
import math
import time
import adafruit_dotstar
import adafruit_fancyled.adafruit_fancyled as fancy
import board
import digitalio
import touchio
import adafruit_dotstar
import adafruit_fancyled.adafruit_fancyled as fancy
# Variables that control the code. Try changing these to modify speed, color,
# etc.
START_DELAY = 5.0 # How many seconds to wait after power up before
# jumping into the animation and initializing the
# touch input. This gives you time to take move your
# fingers off the flower so the capacitive touch
# sensing is better calibrated. During the delay
# the small red LED on the board will flash.
START_DELAY = 5.0 # How many seconds to wait after power up before
# jumping into the animation and initializing the
# touch input. This gives you time to take move your
# fingers off the flower so the capacitive touch
# sensing is better calibrated. During the delay
# the small red LED on the board will flash.
TOUCH_PIN = board.D0 # The board pin to listen for touches and trigger the
# heart beat animation. You can change this to any
# other pin like board.D2 or board.D1. Make sure not
# to touch this pin as the board powers on or the
# capacitive sensing will get confused (just reset
# the board and try again).
TOUCH_PIN = board.D0 # The board pin to listen for touches and trigger the
# heart beat animation. You can change this to any
# other pin like board.D2 or board.D1. Make sure not
# to touch this pin as the board powers on or the
# capacitive sensing will get confused (just reset
# the board and try again).
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.
# For example 0.5 would be half brightness.
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.
# For example 0.5 would be half brightness.
RAINBOW_PERIOD_S = 18.0 # How many seconds it takes for the default rainbow
# cycle animation to perform a full cycle. Increase
# this to slow down the animation or decrease to speed
# it up.
RAINBOW_PERIOD_S = 18.0 # How many seconds it takes for the default rainbow
# cycle animation to perform a full cycle. Increase
# this to slow down the animation or decrease to speed
# it up.
HEARTBEAT_BPM = 60.0 # Heartbeat animation beats per minute. Increase to
# speed up the heartbeat, and decrease to slow down.
HEARTBEAT_BPM = 60.0 # Heartbeat animation beats per minute. Increase to
# speed up the heartbeat, and decrease to slow down.
HEARTBEAT_HUE = 300.0 # The color hue to use when animating the heartbeat
# animation. Pick a value in the range of 0 to 359
# degrees, see the hue spectrum here:
# https://en.wikipedia.org/wiki/Hue
# A value of 300 is a nice pink color.
HEARTBEAT_HUE = 300.0 # The color hue to use when animating the heartbeat
# animation. Pick a value in the range of 0 to 359
# degrees, see the hue spectrum here:
# https://en.wikipedia.org/wiki/Hue
# A value of 300 is a nice pink color.
# First initialize the DotStar LED and turn it off.
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.
red_led = digitalio.DigitalInOut(board.L)
@ -103,24 +103,29 @@ while time.monotonic() - start <= START_DELAY:
touch = touchio.TouchIn(TOUCH_PIN)
# 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.
beat_period = 60.0/HEARTBEAT_BPM
beat_quarter_period = beat_period/4.0 # Quarter period controls the speed of
# the heartbeat drop-off (using an
# exponential decay function).
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).
beat_period = 60.0 / HEARTBEAT_BPM
beat_quarter_period = beat_period / 4.0 # Quarter period controls the speed of
# the heartbeat drop-off (using an
# exponential decay function).
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).
# 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
# 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
# function).
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:
while True:
@ -139,8 +144,8 @@ while True:
# out of phase so one occurs a little bit after the other.
t0 = current % beat_period
t1 = (current + beat_phase) % beat_period
x0 = math.pow(math.e, -t0/beat_quarter_period)
x1 = math.pow(math.e, -t1/beat_quarter_period)
x0 = math.pow(math.e, -t0 / beat_quarter_period)
x1 = math.pow(math.e, -t1 / beat_quarter_period)
# After calculating both exponential decay values pick the biggest one
# as the secondary one will occur after the first. Scale each by
# 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
# (i.e. no interpolation is necessary).
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()
else:
# The touch input is not being touched (touch.value is False) so
# compute the hue with a smooth cycle over time.
# 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.
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
# 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)

View file

@ -34,40 +34,39 @@ import busio
import digitalio
import touchio
# Variables that control the code. Try changing these to modify speed, color,
# etc.
START_DELAY = 5.0 # How many seconds to wait after power up before
# jumping into the animation and initializing the
# touch input. This gives you time to take move your
# fingers off the flower so the capacitive touch
# sensing is better calibrated. During the delay
# the small red LED on the board will flash.
START_DELAY = 5.0 # How many seconds to wait after power up before
# jumping into the animation and initializing the
# touch input. This gives you time to take move your
# fingers off the flower so the capacitive touch
# sensing is better calibrated. During the delay
# the small red LED on the board will flash.
TOUCH_PIN = board.D0 # The board pin to listen for touches and trigger the
# heart beat animation. You can change this to any
# other pin like board.D2 or board.D1. Make sure not
# to touch this pin as the board powers on or the
# capacitive sensing will get confused (just reset
# the board and try again).
TOUCH_PIN = board.D0 # The board pin to listen for touches and trigger the
# heart beat animation. You can change this to any
# other pin like board.D2 or board.D1. Make sure not
# to touch this pin as the board powers on or the
# capacitive sensing will get confused (just reset
# the board and try again).
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.
# For example 0.5 would be half brightness.
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.
# For example 0.5 would be half brightness.
RAINBOW_PERIOD_S = 18.0 # How many seconds it takes for the default rainbow
# cycle animation to perform a full cycle. Increase
# this to slow down the animation or decrease to speed
# it up.
RAINBOW_PERIOD_S = 18.0 # How many seconds it takes for the default rainbow
# cycle animation to perform a full cycle. Increase
# this to slow down the animation or decrease to speed
# it up.
HEARTBEAT_BPM = 60.0 # Heartbeat animation beats per minute. Increase to
# speed up the heartbeat, and decrease to slow down.
HEARTBEAT_BPM = 60.0 # Heartbeat animation beats per minute. Increase to
# speed up the heartbeat, and decrease to slow down.
HEARTBEAT_HUE = 300.0 # The color hue to use when animating the heartbeat
# animation. Pick a value in the range of 0 to 359
# degrees, see the hue spectrum here:
# https://en.wikipedia.org/wiki/Hue
# A value of 300 is a nice pink color.
HEARTBEAT_HUE = 300.0 # The color hue to use when animating the heartbeat
# animation. Pick a value in the range of 0 to 359
# degrees, see the hue spectrum here:
# https://en.wikipedia.org/wiki/Hue
# A value of 300 is a nice pink color.
# First initialize the DotStar LED and turn it off.
# 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).
dotstar_data = bytearray([0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
0xFF])
# Define a function to simplify setting dotstar color.
def dotstar_color(rgb_color):
# 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
@ -93,6 +96,8 @@ def dotstar_color(rgb_color):
dotstar_spi.write(dotstar_data)
finally:
dotstar_spi.unlock()
# Call the function above to turn off the dotstar initially (set it to all 0).
dotstar_color((0, 0, 0))
@ -115,23 +120,24 @@ while time.monotonic() - start <= START_DELAY:
touch = touchio.TouchIn(TOUCH_PIN)
# 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.
beat_period = 60.0/HEARTBEAT_BPM
beat_quarter_period = beat_period/4.0 # Quarter period controls the speed of
# the heartbeat drop-off (using an
# exponential decay function).
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).
beat_period = 60.0 / HEARTBEAT_BPM
beat_quarter_period = beat_period / 4.0 # Quarter period controls the speed of
# the heartbeat drop-off (using an
# exponential decay function).
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).
# Define a gamma correction lookup table to make colors more accurate.
# See this guide for more background on gamma correction:
# https://learn.adafruit.com/led-tricks-gamma-correction/
gamma8 = bytearray(256)
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
# 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
# table above to get the most accurate color. Adapted from C/C++ code here:
# https://www.cs.rit.edu/~ncs/color/t_convert.html
def HSV_to_RGB(h, s, v):
r = 0
g = 0
b = 0
if s == 0.0:
r = v
g = v
b = v
else:
h /= 60.0 # sector 0 to 5
h /= 60.0 # sector 0 to 5
i = int(math.floor(h))
f = h - i # factorial part of h
f = h - i # factorial part of h
p = v * (1.0 - s)
q = v * (1.0 - s * f)
t = v * (1.0 - s * (1.0 - f))
@ -179,18 +184,22 @@ def HSV_to_RGB(h, s, v):
r = v
g = p
b = q
r = gamma8[int(255.0*r)]
g = gamma8[int(255.0*g)]
b = gamma8[int(255.0*b)]
r = gamma8[int(255.0 * r)]
g = gamma8[int(255.0 * g)]
b = gamma8[int(255.0 * b)]
return (r, g, b)
# 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
# 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
# function).
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:
while True:
@ -209,8 +218,8 @@ while True:
# out of phase so one occurs a little bit after the other.
t0 = current % beat_period
t1 = (current + beat_phase) % beat_period
x0 = math.pow(math.e, -t0/beat_quarter_period)
x1 = math.pow(math.e, -t1/beat_quarter_period)
x0 = math.pow(math.e, -t0 / beat_quarter_period)
x1 = math.pow(math.e, -t1 / beat_quarter_period)
# After calculating both exponential decay values pick the biggest one
# as the secondary one will occur after the first. Scale each by
# 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.
# 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.
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
# 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)

View file

@ -1,12 +1,13 @@
from digitalio import DigitalInOut, Direction
import board
import neopixel
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
numpix = 16
@ -17,74 +18,85 @@ led.direction = Direction.OUTPUT
strip = neopixel.NeoPixel(pixpin, numpix, brightness=.2, auto_write=True)
colors = [
[ 232, 100, 255 ], # Purple
[ 200, 200, 20 ], # Yellow
[ 30, 200, 200 ], # Blue
[232, 100, 255], # Purple
[200, 200, 20], # Yellow
[30, 200, 200], # Blue
]
# Fill the dots one after the other with a color
def colorWipe(color, wait):
for j in range(len(strip)):
strip[j] = (color)
time.sleep(wait)
def rainbow(wait):
for j in range(255):
for i in range(len(strip)):
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)
idx = int(i + j)
strip[i] = wheel(idx & 255)
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.
# The colours are a transition r - g - b - back to r.
def wheel(pos):
# Input a value 0 to 255 to get a color value.
# The colours are a transition r - g - b - back to r.
if (pos < 0) or (pos > 255):
return (0, 0, 0)
if (pos < 85):
return (int(pos * 3), int(255 - (pos*3)), 0)
elif (pos < 170):
if pos < 85:
return (int(pos * 3), int(255 - (pos * 3)), 0)
elif pos < 170:
pos -= 85
return (int(255 - pos*3), 0, int(pos*3))
return (int(255 - pos * 3), 0, int(pos * 3))
else:
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
j = random.randint(0, numpix - 1) # Choose random pixel
strip[j] = colors[c] # Set pixel to color
for i in range(1, 5):
strip.brightness = i / 5.0 # Ramp up brightness
time.sleep(wait)
for i in range(1, 5):
strip.brightness = i / 5.0 # Ramp up brightness
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)
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:
flash_random(.01, 8) # first number is 'wait' delay, shorter num == shorter twinkle
flash_random(.01, 5) # second number is how many neopixels to simultaneously light up
# first number is 'wait' delay, shorter num == shorter twinkle
flash_random(.01, 8)
# second number is how many neopixels to simultaneously light up
flash_random(.01, 5)
flash_random(.01, 11)
colorWipe( (232, 100, 255), .1 )
colorWipe( (200, 200, 20), .1 )
colorWipe( (30, 200, 200), .1)
colorWipe((232, 100, 255), .1)
colorWipe((200, 200, 20), .1)
colorWipe((30, 200, 200), .1)
rainbow_cycle(0.05)

View file

@ -1,9 +1,10 @@
import time
import adafruit_sdcard
import adafruit_am2320
import adafruit_sdcard
import analogio
import board
import busio
import analogio
import digitalio
import storage
@ -41,8 +42,10 @@ while True:
print("Humidity:", humidity)
print("VBat voltage: {:.2f}".format(battery_voltage))
print()
sdc.write("{}, {}, {}, {:.2f}\n".format(int(time_stamp), temperature,
humidity, battery_voltage))
sdc.write("{}, {}, {}, {:.2f}\n".format(
int(time_stamp), temperature,
humidity, battery_voltage)
)
time.sleep(3)
except OSError:
pass

View file

@ -29,36 +29,38 @@ Explainatory comments are used verbatim from that code.
import math
import random
import adafruit_dotstar
import adafruit_lsm303
import board
import busio
import adafruit_lsm303
import adafruit_dotstar
N_GRAINS = 10 # Number of grains of sand
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
MAX_FPS = 45 # Maximum redraw rate, frames/second
GRAIN_COLOR = (0, 0, 16)
MAX_X = WIDTH * 256 - 1
MAX_Y = HEIGHT * 256 - 1
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):
"""Initialize grain position and velocity."""
x = 0
y = 0
vx = 0
vy = 0
self.x = 0
self.y = 0
self.vx = 0
self.vy = 0
grains = [Grain() for _ in range(N_GRAINS)]
i2c = busio.I2C(board.SCL, board.SDA)
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
newidx = 0
@ -68,19 +70,23 @@ newy = 0
occupied_bits = [False for _ in range(WIDTH * HEIGHT)]
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 y: row value
"""
return (y >> 8) * WIDTH + (x >> 8)
return (y >> 8) * WIDTH + (x >> 8)
def already_present(limit, x, y):
"""Check if a pixel is already used.
:param int limit: the index into the grain array of the grain being assigned a pixel
Only grains already allocated need to be checks against.
:param int limit: the index into the grain array of
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 y: proposed row valuse for the new grain
"""
@ -89,6 +95,7 @@ def already_present(limit, x, y):
return True
return False
for g in grains:
placed = False
while not placed:
@ -109,20 +116,20 @@ while True:
# Read accelerometer...
f_x, f_y, f_z = sensor.raw_acceleration
ax = f_x >> 8 # Transform accelerometer axes
ay = f_y >> 8 # to grain coordinate space
az = abs(f_z) >> 11 # Random motion factor
az = 1 if (az >= 3) else (4 - az) # Clip & invert
ax -= az # Subtract motion factor from X, Y
ax = f_x >> 8 # Transform accelerometer axes
ay = f_y >> 8 # to grain coordinate space
az = abs(f_z) >> 11 # Random motion factor
az = 1 if (az >= 3) else (4 - az) # Clip & invert
ax -= az # Subtract motion factor from X, Y
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...
v2 = 0 # Velocity squared
v = 0.0 # Absolute velociy
v2 = 0 # Velocity squared
v = 0.0 # Absolute velociy
for g in grains:
g.vx += ax + random.randint(0, az2) # A little randomness makes
g.vy += ay + random.randint(0, az2) # tall stacks topple better!
g.vx += ax + random.randint(0, az2) # A little randomness makes
g.vy += ay + random.randint(0, az2) # tall stacks topple better!
# Terminal velocity (in any direction) is 256 units -- equal to
# 1 pixel -- which keeps moving grains from passing through each other
@ -131,10 +138,10 @@ while True:
# diagonal movement isn't faster
v2 = g.vx * g.vx + g.vy * g.vy
if v2 > 65536: # If v^2 > 65536, then v > 256
v = math.floor(math.sqrt(v2)) # Velocity vector magnitude
g.vx = (g.vx // v) << 8 # Maintain heading
g.vy = (g.vy // v) << 8 # Limit magnitude
if v2 > 65536: # If v^2 > 65536, then v > 256
v = math.floor(math.sqrt(v2)) # Velocity vector magnitude
g.vx = (g.vx // v) << 8 # Maintain heading
g.vy = (g.vy // v) << 8 # Limit magnitude
# ...then update position of each grain, one at a time, checking for
# 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.)
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
if newx > MAX_X: # If grain would go out of bounds
newx = MAX_X # keep it inside, and
g.vx //= -2 # give a slight bounce off the wall
if newx > MAX_X: # If grain would go out of bounds
newx = MAX_X # keep it inside, and
g.vx //= -2 # give a slight bounce off the wall
elif newx < 0:
newx = 0
g.vx //= -2
@ -163,56 +170,66 @@ while True:
newy = 0
g.vy //= -2
oldidx = index_of_xy(g.x, g.y) # prior pixel
newidx = index_of_xy(newx, newy) # new pixel
if oldidx != newidx and occupied_bits[newidx]: # If grain is moving to a new pixel...
# but if that pixel is already occupied...
delta = abs(newidx - oldidx) # What direction when blocked?
if delta == 1: # 1 pixel left or right
newx = g.x # cancel x motion
g.vx //= -2 # and bounce X velocity (Y is ok)
newidx = oldidx # no pixel change
elif delta == WIDTH: # 1 pixel up or down
newy = g.y # cancel Y motion
g.vy //= -2 # and bounce Y velocity (X is ok)
newidx = oldidx # no pixel change
else: # Diagonal intersection is more tricky...
# 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
oldidx = index_of_xy(g.x, g.y) # prior pixel
newidx = index_of_xy(newx, newy) # new pixel
# If grain is moving to a new pixel...
if oldidx != newidx and occupied_bits[newidx]:
# but if that pixel is already occupied...
# What direction when blocked?
delta = abs(newidx - oldidx)
if delta == 1: # 1 pixel left or right
newx = g.x # cancel x motion
# and bounce X velocity (Y is ok)
g.vx //= -2
newidx = oldidx # no pixel change
elif delta == WIDTH: # 1 pixel up or down
newy = g.y # cancel Y motion
# and bounce Y velocity (X is ok)
g.vy //= -2
newidx = oldidx # no pixel change
else: # Diagonal intersection is more tricky...
# 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)
if not occupied_bits[newidx]: # that pixel is free, take it! But...
newy = g.y # cancel Y motion
g.vy //= -2 # and bounce Y velocity
else: # X pixel is taken, so try Y...
# that pixel is free, take it! But...
if not occupied_bits[newidx]:
newy = g.y # cancel Y motion
g.vy //= -2 # and bounce Y velocity
else: # X pixel is taken, so try Y...
newidx = index_of_xy(g.x, newy)
if not occupied_bits[newidx]: # Pixel is free, take it, but first...
newx = g.x # Cancel X motion
g.vx //= -2 # Bounce X velocity
else: # both spots are occupied
newx = g.x # Cancel X & Y motion
# Pixel is free, take it, but first...
if not occupied_bits[newidx]:
newx = g.x # Cancel X motion
g.vx //= -2 # Bounce X velocity
else: # both spots are occupied
newx = g.x # Cancel X & Y motion
newy = g.y
g.vx //= -2 # Bounce X & Y velocity
g.vx //= -2 # Bounce X & Y velocity
g.vy //= -2
newidx = oldidx # Not moving
else: # y axis is faster. start there
newidx = oldidx # Not moving
else: # y axis is faster. start there
newidx = index_of_xy(g.x, newy)
if not occupied_bits[newidx]: # Pixel's free! Take it! But...
newx = g.x # Cancel X motion
g.vx //= -2 # Bounce X velocity
else: # Y pixel is taken, so try X...
# Pixel's free! Take it! But...
if not occupied_bits[newidx]:
newx = g.x # Cancel X motion
g.vx //= -2 # Bounce X velocity
else: # Y pixel is taken, so try X...
newidx = index_of_xy(newx, g.y)
if not occupied_bits[newidx]: # Pixel is free, take it, but first...
newy = g.y # cancel Y motion
g.vy //= -2 # and bounce Y velocity
else: # both spots are occupied
newx = g.x # Cancel X & Y motion
# Pixel is free, take it, but first...
if not occupied_bits[newidx]:
newy = g.y # cancel Y motion
g.vy //= -2 # and bounce Y velocity
else: # both spots are occupied
newx = g.x # Cancel X & Y motion
newy = g.y
g.vx //= -2 # Bounce X & Y velocity
g.vx //= -2 # Bounce X & Y velocity
g.vy //= -2
newidx = oldidx # Not moving
newidx = oldidx # Not moving
occupied_bits[oldidx] = False
occupied_bits[newidx] = True
g.x = newx

View file

@ -26,8 +26,10 @@ Debounce an input pin.
"""
import time
import digitalio
class Debouncer(object):
"""Debounce an input pin"""
@ -35,45 +37,43 @@ class Debouncer(object):
UNSTABLE_STATE = 0x02
CHANGED_STATE = 0x04
def __init__(self, pin, mode=None, interval=0.010):
"""Make am instance.
: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 interval: bounce threshold in seconds (default is 0.010, i.e. 10 milliseconds)
:param int mode: digitalio.Pull.UP or .DOWN (default is no
pull up/down)
:param int interval: bounce threshold in seconds (default is 0.010,
i.e. 10 milliseconds)
"""
self.state = 0x00
self.pin = digitalio.DigitalInOut(pin)
self.pin.direction = digitalio.Direction.INPUT
if mode != None:
if mode is not None:
self.pin.pull = mode
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
if interval is None:
self.interval = 0.010
else:
self.interval = interval
def __set_state(self, bits):
self.state |= bits
def __unset_state(self, bits):
self.state &= ~bits
def __toggle_state(self, bits):
self.state ^= bits
def __get_state(self, bits):
return (self.state & bits) != 0
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)
current_state = self.pin.value
if current_state != self.__get_state(Debouncer.UNSTABLE_STATE):
@ -81,25 +81,27 @@ class Debouncer(object):
self.__toggle_state(Debouncer.UNSTABLE_STATE)
else:
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.__toggle_state(Debouncer.DEBOUNCED_STATE)
self.__set_state(Debouncer.CHANGED_STATE)
@property
def value(self):
"""Return the current debounced value of the input."""
return self.__get_state(Debouncer.DEBOUNCED_STATE)
@property
def rose(self):
"""Return whether the debounced input went from low to high at the most recent update."""
return self.__get_state(self.DEBOUNCED_STATE) and self.__get_state(self.CHANGED_STATE)
"""Return whether the debounced input went from low to high at
the most recent update."""
return self.__get_state(self.DEBOUNCED_STATE) \
and self.__get_state(self.CHANGED_STATE)
@property
def fell(self):
"""Return whether the debounced input went from high to low at the most recent update."""
return (not self.__get_state(self.DEBOUNCED_STATE)) and self.__get_state(self.CHANGED_STATE)
"""Return whether the debounced input went from high to low at
the most recent update."""
return (not self.__get_state(self.DEBOUNCED_STATE)) \
and self.__get_state(self.CHANGED_STATE)

View file

@ -28,6 +28,7 @@ Manage a directory in the file system.
import os
class DirectoryNode(object):
"""Display and navigate the SD card contents"""
@ -46,7 +47,6 @@ class DirectoryNode(object):
self.selected_offset = 0
self.old_selected_offset = -1
def __cleanup(self):
"""Dereference things for speedy gc."""
self.display = None
@ -55,7 +55,6 @@ class DirectoryNode(object):
self.files = None
return self
def __is_dir(self, path):
"""Determine whether a path identifies a machine code bin file.
:param string path: path of the file to check
@ -68,7 +67,6 @@ class DirectoryNode(object):
except OSError:
return False
def __sanitize(self, name):
"""Nondestructively strip off a trailing slash, if any, and return the result.
:param string name: the filename
@ -77,7 +75,6 @@ class DirectoryNode(object):
return name[:-1]
return name
def __path(self):
"""Return the result of recursively follow the parent links, building a full
path to this directory."""
@ -85,24 +82,22 @@ class DirectoryNode(object):
return self.parent.__path() + os.sep + self.__sanitize(self.name)
return self.__sanitize(self.name)
def __make_path(self, filename):
"""Return a full path to the specified file in this directory.
:param string filename: the name of the file in this directory
"""
return self.__path() + os.sep + filename
def __number_of_files(self):
"""The number of files in this directory, including the ".." for the parent
directory if this isn't the top directory on the SD card."""
self.__get_files()
return len(self.files)
def __get_files(self):
"""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."""
if len(self.files) == 0:
self.files = os.listdir(self.__path())
@ -113,48 +108,48 @@ class DirectoryNode(object):
if self.__is_dir(self.__make_path(name)):
self.files[index] = name + "/"
def __update_display(self):
"""Update the displayed list of files if required."""
if self.top_offset != self.old_top_offset:
self.__get_files()
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.show()
self.old_top_offset = self.top_offset
def __update_selection(self):
"""Update the selected file lighlight if required."""
if self.selected_offset != self.old_selected_offset:
if self.old_selected_offset > -1:
self.display.text(">", 0, (self.old_selected_offset - self.top_offset) * 8, 0)
self.display.text(">", 0, (self.selected_offset - self.top_offset) * 8, 1)
old_offset = (self.old_selected_offset - self.top_offset) * 8
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.old_selected_offset = self.selected_offset
def __is_directory_name(self, filename):
"""Is a filename the name of a directory.
:param string filename: the name of the file
"""
return filename[-1] == '/'
@property
def selected_filename(self):
"""The name of the currently selected file in this directory."""
self.__get_files()
return self.files[self.selected_offset]
@property
def selected_filepath(self):
"""The full path of the currently selected file in this directory."""
return self.__make_path(self.selected_filename)
def force_update(self):
"""Force an update of the file list and selected file highlight."""
self.old_selected_offset = -1
@ -162,10 +157,9 @@ class DirectoryNode(object):
self.__update_display()
self.__update_selection()
def down(self):
"""Move down in the file list if possible, adjusting the selected file indicator
and scrolling the display as required."""
"""Move down in the file list if possible, adjusting the selected file
indicator and scrolling the display as required."""
if self.selected_offset < self.__number_of_files() - 1:
self.selected_offset += 1
if self.selected_offset == self.top_offset + 4:
@ -173,7 +167,6 @@ class DirectoryNode(object):
self.__update_display()
self.__update_selection()
def up(self):
"""Move up in the file list if possible, adjusting the selected file indicator
and scrolling the display as required."""
@ -184,10 +177,10 @@ class DirectoryNode(object):
self.__update_display()
self.__update_selection()
def click(self):
"""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 self.selected_filename == "..":
if self.parent:
@ -196,7 +189,8 @@ class DirectoryNode(object):
self.__cleanup()
return p
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()
return new_node
return self

View file

@ -25,8 +25,8 @@ THE SOFTWARE.
Manage the emulator hardware.
"""
import digitalio
import adafruit_mcp230xx
import digitalio
# control pin values
@ -57,7 +57,7 @@ class Emulator(object):
def __init__(self, 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
@ -85,47 +85,40 @@ class Emulator(object):
self.led_pin.direction = digitalio.Direction.OUTPUT
self.led_pin.value = False
def __pulse_write(self):
self.write_pin.value = WRITE_ENABLED
self.write_pin.value = WRITE_DISABLED
def __deactivate_ram(self):
self.chip_select_pin.value = CHIP_DISABLED
def __activate_ram(self):
self.chip_select_pin.value = CHIP_ENABLED
def __reset_address_counter(self):
self.clock_reset_pin.value = RESET_ACTIVE
self.clock_reset_pin.value = RESET_INACTIVE
def __advance_address_counter(self):
self.address_clock_pin.value = CLOCK_ACTIVE
self.address_clock_pin.value = CLOCK_INACTIVE
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)
def enter_program_mode(self):
"""Enter program mode, allowing loading of the emulator RAM."""
self.mode_pin.value = PROGRAMMER_USE
self.led_pin.value = LED_OFF
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.led_pin.value = LED_ON
def load_ram(self, code):
"""Load the emulator RAM. Automatically switched to program mode.
:param [byte] code: the list of bytes to load into the emulator RAM

View file

@ -29,18 +29,17 @@ Targeted for the SAMD51 boards.
by Dave Astels
"""
import digitalio
import adafruit_sdcard
import adafruit_ssd1306
import board
import busio
import adafruit_ssd1306
import digitalio
import storage
import adafruit_sdcard
from debouncer import Debouncer
from directory_node import DirectoryNode
from emulator import Emulator
from debouncer import Debouncer
#--------------------------------------------------------------------------------
# --------------------------------------------------------------------------------
# Initialize Rotary encoder
# 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.pull = digitalio.Pull.UP
#--------------------------------------------------------------------------------
# --------------------------------------------------------------------------------
# Initialize I2C and OLED
i2c = busio.I2C(board.SCL, board.SDA)
@ -65,12 +64,12 @@ oled.fill(0)
oled.text("Initializing SD", 0, 10)
oled.show()
#--------------------------------------------------------------------------------
# --------------------------------------------------------------------------------
# Initialize SD card
#SD_CS = board.D10
# SD_CS = board.D10
# 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)
sdcard = adafruit_sdcard.SDCard(spi, cs)
vfs = storage.VfsFat(sdcard)
@ -80,8 +79,7 @@ oled.fill(0)
oled.text("Done", 0, 10)
oled.show()
#--------------------------------------------------------------------------------
# --------------------------------------------------------------------------------
# Initialize globals
encoder_counter = 0
@ -101,7 +99,7 @@ current_mode = PROGRAM_MODE
emulator = Emulator(i2c)
#--------------------------------------------------------------------------------
# --------------------------------------------------------------------------------
# Helper functions
def is_binary_name(filename):
@ -138,7 +136,7 @@ def program():
current_dir.force_update()
#--------------------------------------------------------------------------------
# --------------------------------------------------------------------------------
# Main loop
current_dir = DirectoryNode(oled, name="/sd")
@ -196,7 +194,7 @@ while True:
rotary_prev_state = rotary_curr_state
# 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:
current_dir.up()
elif encoder_direction == 1:

View file

@ -6,12 +6,13 @@
# Use a jumper wire from D2 to GND to prevent injection while programming!
from digitalio import DigitalInOut, Direction, Pull
import board
import time
import board
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
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:
@ -53,7 +54,10 @@ led.value = True
# Wait a moment
pause = 0.25
# The functions that follow are the various payloads to deliver
def launch_terminal():
if operating_system is 0:
led.value = False
@ -105,7 +109,8 @@ def launch_terminal():
time.sleep(2)
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)
kbd.press(Keycode.ENTER)
kbd.release_all()
@ -130,7 +135,7 @@ def launch_terminal():
time.sleep(pause)
# type a message a few times
for i in range(3):
for _ in range(3):
layout.write("HELLO FRIEND")
# time.sleep(pause)
kbd.press(Keycode.ENTER)
@ -138,19 +143,34 @@ def launch_terminal():
# time.sleep(pause)
time.sleep(2)
layout.write(" _ _ _____ _ _ ___ _____ ____ ___ _____ _ _ ____")
layout.write(
" _ _ _____ _ _ ___ "
"_____ ____ ___ _____ _ _ ____"
)
kbd.press(Keycode.ENTER)
kbd.release_all()
layout.write("| | | | ____| | | | / _ \ | ___| _ \|_ _| ____| \ | | _ \ ")
layout.write(
"| | | | ____| | | | / _ \ | "
" ___| _ \|_ _| ____| \ | | _ \ "
)
kbd.press(Keycode.ENTER)
kbd.release_all()
layout.write("| |_| | _| | | | | | | | | | |_ | |_) || || _| | \| | | | |")
layout.write(
"| |_| | _| | | | | | | | | | |"
"_ | |_) || || _| | \| | | | |"
)
kbd.press(Keycode.ENTER)
kbd.release_all()
layout.write("| _ | |___| |___| |__| |_| | | _| | _ < | || |___| |\ | |_| |")
layout.write(
"| _ | |___| |___| |__| |_| | | "
" _| | _ < | || |___| |\ | |_| |"
)
kbd.press(Keycode.ENTER)
kbd.release_all()
layout.write("|_| |_|_____|_____|_____\___/ |_| |_| \_\___|_____|_| \_|____/ ")
layout.write(
"|_| |_|_____|_____|_____\___/ |_"
"| |_| \_\___|_____|_| \_|____/ "
)
kbd.press(Keycode.ENTER)
kbd.release_all()
@ -159,6 +179,7 @@ def launch_terminal():
kbd.press(Keycode.ENTER)
kbd.release_all()
def download_image():
led.value = False
# run this after running 'launch_terminal'
@ -178,7 +199,14 @@ def download_image():
# this says where to save image, and where to get it
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)
kbd.press(Keycode.ENTER)
led.value = True
@ -200,7 +228,12 @@ def replace_background():
led.value = False
# run this after download_image (which ran after launch_terminal)
# 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)
kbd.press(Keycode.ENTER)
kbd.release_all()
@ -216,6 +249,7 @@ def replace_background():
led.value = True
time.sleep(3) # give it a moment to refresh dock and BG
def hide_everything():
led.value = False
# print("Hiding stuff... ")
@ -224,6 +258,7 @@ def hide_everything():
time.sleep(10)
kbd.release_all()
while True:
# check for presence of jumper from GND to D2
if buttons[0].value is False and payload_delivered is 0:
@ -235,8 +270,7 @@ while True:
led.value = False
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
print("Release the water fowl!") # for debugging in screen or putty
for i in range(10): # blink 5 times

View file

@ -2,9 +2,10 @@
# for Adafruit Circuit Playground express
# with CircuitPython
from adafruit_circuitplayground.express import cpx
import time
from adafruit_circuitplayground.express import cpx
# Change this number to adjust touch sensitivity threshold, 0 is default
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_col = [WHITE, RED, YELLOW, GREEN, AQUA, BLUE, PURPLE, BLACK]
def prog_mode(i):
cpx.play_file(audio_files[i])
step_note[step] = i
def prog_mode(index):
cpx.play_file(audio_files[index])
step_note[step] = index
cpx.pixels[step_pixel[step]] = step_col[step_note[step]]
print("playing file " + audio_files[i])
print("playing file " + audio_files[index])
while True:

View file

@ -2,45 +2,48 @@
# uses two 16 NeoPixel rings (RGBW)
# connected to Gemma M0 powered by LiPo battery
import board
import neopixel
import time
pixpinLeft = board.D1 #Data In attached to Gemma pin D1
pixpinRight = board.D0 #Data In attached to Gemma pin D0
import board
import neopixel
pixpinLeft = board.D1 # Data In attached to Gemma pin D1
pixpinRight = board.D0 # Data In attached to Gemma pin D0
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,
auto_write=False)
auto_write=False)
stripRight = neopixel.NeoPixel(pixpinRight, numpix, bpp=3, 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)
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):
# Input a value 0 to 255 to get a color value.
# Note: switch the commented lines below if using RGB vs. RGBW NeoPixles
if (pos < 8) or (pos > 250):
#return (120, 0, 0, 0) #first color, red: for RGBW NeoPixels
return (120, 0, 0) #first color, red: for RGB NeoPixels
if (pos < 85):
return (int(pos * 3), int(255 - (pos*3)), 0)
#return (125, 35, 0, 0) #second color, brass: for RGBW NeoPixels
return (125, 35, 0) #second color, brass: for RGB NeoPixels
elif (pos < 170):
# return (120, 0, 0, 0) #first color, red: for RGBW NeoPixels
return (120, 0, 0) # first color, red: for RGB NeoPixels
if pos < 85:
return (int(pos * 3), int(255 - (pos * 3)), 0)
# return (125, 35, 0, 0) #second color, brass: for RGBW NeoPixels
# return (125, 35, 0) # second color, brass: for RGB NeoPixels
elif pos < 170:
pos -= 85
#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), 0)#: for RGBW NeoPixels
return (int(255 - pos * 3), 0, int(pos * 3)) # : for RGB NeoPixels
else:
pos -= 170
#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), 0)#: for RGBW NeoPixels
return (0, int(pos * 3), int(255 - pos * 3)) # : for RGB NeoPixels
def brass_cycle(wait, patternL, patternR):
# patterns do different things, try:
@ -53,14 +56,15 @@ def brass_cycle(wait, patternL, patternR):
# 256 quarter turn
for j in range(255):
for i in range(len(stripLeft)):
idxL = int ((i * patternL / len(stripLeft)) + j)
stripLeft[i] = cog(idxL & 64) #sets the second (brass) color
idxR = int ((i * patternR / len(stripRight)) + j)
stripRight[i] = cog(idxR & 64) #sets the second (brass) color
idxL = int((i * patternL / len(stripLeft)) + j)
stripLeft[i] = cog(idxL & 64) # sets the second (brass) color
idxR = int((i * patternR / len(stripRight)) + j)
stripRight[i] = cog(idxR & 64) # sets the second (brass) color
stripLeft.show()
stripRight.show()
time.sleep(wait)
while True:
brass_cycle(0.01, 256, 24) # brass color cycle with 1ms delay per step
# patternL, patternR
brass_cycle(0.01, 256, 24) # brass color cycle with 1ms delay per step
# patternL, patternR

View file

@ -1,13 +1,13 @@
# Gemma M0 Password Vault
# press cap touch pads to enter strong passwords over USB
from digitalio import DigitalInOut, Direction
import touchio
import board
import time
import board
import touchio
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
from digitalio import DigitalInOut, Direction
led = DigitalInOut(board.D13)
led.direction = Direction.OUTPUT

View file

@ -2,11 +2,12 @@
# for fine tuning Software Defined Radio CubicSDR software
# 10k pot hooked to 3v, A2, and D2 acting as GND
from analogio import AnalogIn
import board
import time
import board
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
from analogio import AnalogIn
from digitalio import DigitalInOut, Direction
d2_ground = DigitalInOut(board.D2)
@ -22,12 +23,15 @@ pot_min = 0.00
step = (pot_max - pot_min) / 10.0
last_knob = 0
def steps(x):
return round((x - pot_min) / step)
def getVoltage(pin):
return (pin.value * 3.3) / 65536
def spamKey(code):
knobkeys = [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]
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.press(knobkeys[code]) # which keycode is entered
kbd.release_all()
time.sleep(spamRate[code]) # how fast the key is spammed
while True:
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
elif steps(knob) is not 5:
elif steps(knob) != 5:
led.value = False
spamKey(steps(knob))

View file

@ -1,28 +1,29 @@
# Motion Sensor Alarm
# uses Gemma M0, vibration sensor on A0/GND, & piezo on D0/GND
import time
import pulseio
from digitalio import DigitalInOut, Direction, Pull
from analogio import AnalogIn
import board
import time
piezo = pulseio.PWMOut(board.D0, duty_cycle=0, frequency=440,
variable_frequency=True)
vibrationPin = AnalogIn(board.A0)
def get_voltage(pin):
return (pin.value * 3.3) / 65536
while True:
print((get_voltage(vibrationPin),))
vibration = get_voltage(vibrationPin)
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):
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
piezo.duty_cycle = 0 # off
time.sleep(0.02) # pause

View file

@ -1,47 +1,50 @@
import time
import board
import neopixel
import time
try:
import urandom as random # for v1.0 API support
import urandom as random # for v1.0 API support
except ImportError:
import random
import random
numpix = 36 # Number of NeoPixels
numpix = 36 # Number of NeoPixels
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
offset = 0 # Position of spinner animation
color = [160, 0, 160] # RGB color - purple
mode = 0 # Current animation effect
offset = 0 # Position of spinner animation
color = [160, 0, 160] # RGB color - purple
prevtime = time.monotonic() # Time of last animation mode switch
while True: # Loop forever...
if mode == 0: # Random sparkles - lights just one LED at a time
i = random.randint(0, numpix - 1) # Choose random pixel
strip[i] = color # Set it to current color
strip.write() # Refresh LED states
# Set same pixel to "off" color now but DON'T refresh...
# it stays on for now...bot this and the next random
# pixel will be refreshed on the next pass.
strip[i] = [0,0,0]
time.sleep(0.008) # 8 millisecond delay
elif mode == 1: # Spinny wheel (4 LEDs on at a time)
for i in range(numpix): # For each LED...
if ((offset + i) & 7) < 2: # 2 pixels out of 8...
strip[i] = color # are set to current color
else:
strip[i] = [0,0,0] # other pixels are off
strip.write() # Refresh LED states
time.sleep(0.08) # 80 millisecond delay
offset += 1 # Shift animation by 1 pixel on next frame
if offset >= 8: offset = 0
# Additional animation modes could be added here!
if mode == 0: # Random sparkles - lights just one LED at a time
i = random.randint(0, numpix - 1) # Choose random pixel
strip[i] = color # Set it to current color
strip.write() # Refresh LED states
# Set same pixel to "off" color now but DON'T refresh...
# it stays on for now...bot this and the next random
# pixel will be refreshed on the next pass.
strip[i] = [0, 0, 0]
time.sleep(0.008) # 8 millisecond delay
elif mode == 1: # Spinny wheel (4 LEDs on at a time)
for i in range(numpix): # For each LED...
if ((offset + i) & 7) < 2: # 2 pixels out of 8...
strip[i] = color # are set to current color
else:
strip[i] = [0, 0, 0] # other pixels are off
strip.write() # Refresh LED states
time.sleep(0.08) # 80 millisecond delay
offset += 1 # Shift animation by 1 pixel on next frame
if offset >= 8:
offset = 0
# Additional animation modes could be added here!
t = time.monotonic() # Current time in seconds
if (t - prevtime) >= 8: # Every 8 seconds...
mode += 1 # Advance to next mode
if mode > 1: # End of modes?
mode = 0 # Start over from beginning
strip.fill([0,0,0]) # Turn off all pixels
prevtime = t # Record time of last mode change
t = time.monotonic() # Current time in seconds
if (t - prevtime) >= 8: # Every 8 seconds...
mode += 1 # Advance to next mode
if mode > 1: # End of modes?
mode = 0 # Start over from beginning
strip.fill([0, 0, 0]) # Turn off all pixels
prevtime = t # Record time of last mode change

View file

@ -1,180 +1,186 @@
# Gemma "Firewalker Lite" sneakers
# Gemma "Firewalker Lite" sneakers
# - Uses the following Adafruit parts (X2 for two shoes):
# * Gemma M0 3V microcontroller (#3501)
# * 150 mAh LiPoly battery (#1317) or larger
# * Medium vibration sensor switch (#2384)
# * 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
# * https://learn.adafruit.com/gemma-led-sneakers
import board
import digitalio
import neopixel
import time
import digitalio
try:
import urandom as random
import urandom as random
except ImportError:
import random
import random
# Declare a NeoPixel object on led_pin with num_leds as pixels
# No auto-write.
led_pin = board.D1 # Which pin your pixels are connected to
num_leds = 40 # How many LEDs you have
circumference = 40 # Shoe circumference, in pixels, may be > NUM_LEDS
frames_per_second = 50 # Animation frames per second
brightness = 0 # Current wave height
# No auto-write.
led_pin = board.D1 # Which pin your pixels are connected to
num_leds = 40 # How many LEDs you have
circumference = 40 # Shoe circumference, in pixels, may be > NUM_LEDS
frames_per_second = 50 # Animation frames per second
brightness = 0 # Current wave height
strip = neopixel.NeoPixel(led_pin, num_leds, brightness=1, auto_write=False)
offset = 0
# vibration sensor
motion_pin = board.D0 # Pin where vibration switch is connected
pin = digitalio.DigitalInOut(motion_pin)
motion_pin = board.D0 # Pin where vibration switch is connected
pin = digitalio.DigitalInOut(motion_pin)
pin.direction = digitalio.Direction.INPUT
pin.pull = digitalio.Pull.UP
pin.pull = digitalio.Pull.UP
ramping_up = False
center = 0 # Center point of wave in fixed-point space (0 - 255)
speed = 1 # Distance to move between frames (-128 - +127)
width = 2 # Width from peak to bottom of triangle wave (0 - 128)
hue = 3 # Current wave hue (color) see comments later
center = 0 # Center point of wave in fixed-point space (0 - 255)
speed = 1 # Distance to move between frames (-128 - +127)
width = 2 # Width from peak to bottom of triangle wave (0 - 128)
hue = 3 # Current wave hue (color) see comments later
hue_target = 4 # Final hue we're aiming for
red = 5 # LED RGB color calculated from hue
green = 6 # LED RGB color calculated from hue
blue = 7 # LED RGB color calculated from hue
red = 5 # LED RGB color calculated from hue
green = 6 # LED RGB color calculated from hue
blue = 7 # LED RGB color calculated from hue
y = 0
brightness = 0
count = 0
count = 0
# Gemma can animate 3 of these on 40 LEDs at 50 FPS
# More LEDs and/or more waves will need lower
wave = [0] * 8, [0] * 8, [0] * 8
# Note that the speeds of each wave are different prime numbers.
# This avoids repetition as the waves move around the
# perimeter...if they were even numbers or multiples of each
# Note that the speeds of each wave are different prime numbers.
# This avoids repetition as the waves move around the
# perimeter...if they were even numbers or multiples of each
# other, there'd be obvious repetition in the pattern of motion...
# beat frequencies.
n_waves = len(wave)
# 90 distinct hues (0-89) around color wheel
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,
0, 0, 0, 0, 0, 0, 18, 52, 86, 120, 154, 188, 222,
255, 255, 255, 255, 255, 255, 255, 255 ]
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,
0, 0, 0, 0, 0, 0, 18, 52, 86, 120, 154, 188, 222,
255, 255, 255, 255, 255, 255, 255, 255]
# Gamma-correction table
# Gamma-correction table
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, 1, 1, 1, 1,
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,
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,
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,
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,
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,
115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
177,180,182,184,186,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 ]
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,
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,
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,
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,
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,
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, 115, 117, 119, 120, 122, 124, 126, 127, 129, 131, 133,
135, 137, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158,
160, 162, 164, 167, 169, 171, 173, 175, 177, 180, 182, 184, 186,
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
h = hue_table[hue >> 1]
def h2rgb(colour_hue):
colour_hue %= 90
h = hue_table[colour_hue >> 1]
if ( hue & 1 ):
if colour_hue & 1:
ret = h & 15
else:
ret = ( h >> 4 )
return ( ret * 17 )
ret = (h >> 4)
return ret * 17
def wave_setup():
global wave
wave = [ [ 0, 3, 60, 0, 0, 0, 0, 0 ],
[ 0, -5, 45, 0, 0, 0, 0, 0 ],
[ 0, 7, 30, 0, 0, 0, 0, 0 ] ]
wave = [[0, 3, 60, 0, 0, 0, 0, 0],
[0, -5, 45, 0, 0, 0, 0, 0],
[0, 7, 30, 0, 0, 0, 0, 0]]
# assign random starting colors to waves
for w in range(n_waves):
wave[w][hue] = wave[w][hue_target] = 90 + random.randint(0,90)
wave[w][red] = h2rgb(wave[w][hue] - 30)
wave[w][green] = h2rgb(wave[w][hue])
wave[w][blue] = h2rgb(wave[w][hue] + 30)
for wave_index in range(n_waves):
current_wave = wave[wave_index]
random_offset = random.randint(0, 90)
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():
while ( True ):
while True:
if not pin.value:
return(True)
return True
while ( True ) :
while True:
# wait for vibration sensor to trigger
if ( ramping_up == False ):
if not ramping_up:
ramping_up = vibration_detector()
wave_setup()
# But it's not just a straight shot that it ramps up.
# This is a low-pass filter...it makes the brightness
# value decelerate as it approaches a target (200 in
# this case). 207 is used here because integers round
# But it's not just a straight shot that it ramps up.
# This is a low-pass filter...it makes the brightness
# value decelerate as it approaches a target (200 in
# this case). 207 is used here because integers round
# down on division and we'd never reach the target;
# 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
if ( count == ( circumference + num_leds + 5) ):
if count == (circumference + num_leds + 5):
ramping_up = False
count = 0
# 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!
wave[w][center] += wave[w][speed]
wave[w][center] += wave[w][speed]
# 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...
if ( not random.randint(frames_per_second * 4, 255) ):
if not random.randint(frames_per_second * 4, 255):
# 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...
else:
else:
if ( wave[w][hue] < wave[w][hue_target] ):
wave[w][hue] += 1 # Move up or
else:
wave[w][hue] -= 1 # down as needed
if wave[w][hue] < wave[w][hue_target]:
wave[w][hue] += 1 # Move up or
else:
wave[w][hue] -= 1 # down as needed
# Reached destination?
if ( wave[w][hue] == wave[w][hue_target] ):
wave[w][hue] = 90 + wave[w][hue] % 90 # Clamp to 90-180 range
wave[w][hue_target] = wave[w][hue] # Copy to 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_target] = wave[w][hue] # Copy to target
wave[w][red] = h2rgb( wave[w][hue] - 30 )
wave[w][green] = h2rgb( wave[w][hue] )
wave[w][blue] = h2rgb( wave[w][hue] + 30)
wave[w][red] = h2rgb(wave[w][hue] - 30)
wave[w][green] = h2rgb(wave[w][hue])
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.
# 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)
# "* 256" because that would be
# the start of the (N+1)th pixel
@ -182,72 +188,73 @@ while ( True ) :
x = (i * 256 + 127) / circumference
# 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 w in range(n_waves):
# Calculate distance from pixel center to wave
# center point, using both signed and unsigned
for w_index in range(n_waves):
# Calculate distance from pixel center to wave
# center point, using both signed and unsigned
# 8-bit integers...
d1 = int( abs(x - wave[w][center]) )
d2 = int( abs(x - wave[w][center]) )
d1 = int(abs(x - wave[w_index][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)
# that 'wraps around' the ends of the strip as
# necessary...it's a contiguous ring, and waves
# that 'wraps around' the ends of the strip as
# necessary...it's a contiguous ring, and waves
# can move smoothly across the gap.
if ( d2 < d1 ):
d1 = d2 # d1 is pixel-to-wave-center distance
if d2 < d1:
d1 = d2 # d1 is pixel-to-wave-center distance
# d2 distance, relative to wave width, is then
# proportional to the wave's brightness at this
# d2 distance, relative to wave width, is then
# proportional to the wave's brightness at this
# pixel (basic linear y=mx+b stuff).
# Is distance within wave's influence?
# d2 is opposite; distance to wave's end
if ( d1 < wave[w][width] ):
d2 = wave[w][width] - d1
y = int ( brightness * d2 / wave[w][width] ) # 0 to 200
if d1 < wave[w_index][width]:
d2 = wave[w_index][width] - d1
y = int(brightness * d2 / wave[w_index][width]) # 0 to 200
# y is a brightness scale value --
# proportional to, but not exactly equal
# to, the resulting RGB value.
if ( y < 128 ): # Fade black to RGB color
# In HSV colorspace, this would be
# y is a brightness scale value --
# proportional to, but not exactly equal
# to, the resulting RGB value.
if y < 128: # Fade black to RGB color
# In HSV colorspace, this would be
# tweaking 'value'
n = int(y * 2 + 1) # 1-256
r += ( wave[w][red] * n ) >> 8 # More fixed-point math
g += ( wave[w][green] * n ) >> 8 # Wave color is scaled by 'n'
b += ( wave[w][blue] * n ) >> 8 # >>8 is equiv to /256
else: # Fade RGB color to white
# In HSV colorspace, this would be tweaking 'saturation'
n = int( ( y - 128 ) * 2 ) # 0-255 affects white level
m = 256 * n
n = 256 - n # 1-256 affects RGB level
r += (m + wave[w][red] * n) >> 8
g += (m + wave[w][green] * n) >> 8
b += (m + wave[w][blue] * n) >> 8
n = int(y * 2 + 1) # 1-256
r += (wave[w_index][red] * n) >> 8 # More fixed-point math
# Wave color is scaled by 'n'
g += (wave[w_index][green] * n) >> 8
b += (wave[w_index][blue] * n) >> 8 # >>8 is equiv to /256
else: # Fade RGB color to white
# In HSV colorspace, this tweaks 'saturation'
n = int((y - 128) * 2) # 0-255 affects white level
m = 256 * n
n = 256 - n # 1-256 affects RGB level
r += (m + wave[w_index][red] * 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
# from all waves that affect this pixel; may exceed
# r,g,b are 16-bit types that accumulate brightness
# from all waves that affect this pixel; may exceed
# 255. Now clip to 0-255 range:
if ( r > 255 ):
if r > 255:
r = 255
if ( g > 255 ):
if g > 255:
g = 255
if ( b > 255 ):
if b > 255:
b = 255
# Store resulting RGB value and we're done with
# Store resulting RGB value and we're done with
# this pixel!
strip[i] = (r, g, b)
# Once rendering is complete, a second pass is made
# through pixel data applying gamma correction, for
# Once rendering is complete, a second pass is made
# through pixel data applying gamma correction, for
# more perceptually linear colors.
# https://learn.adafruit.com/led-tricks-gamma-correction
for j in range( num_leds ):
( red_gamma, green_gamma, blue_gamma ) = strip[j]
for j in range(num_leds):
(red_gamma, green_gamma, blue_gamma) = strip[j]
red_gamma = gammas[red_gamma]
green_gamma = gammas[green_gamma]
blue_gamma = gammas[blue_gamma]

View file

@ -1,67 +1,72 @@
# NeoPixel earrings example. Makes a nice blinky display with just a
# few LEDs on at any time...uses MUCH less juice than rainbow display!
import time
import board
import neopixel
import time
try:
import urandom as random # for v1.0 API support
import urandom as random # for v1.0 API support
except ImportError:
import random
import random
numpix = 16 # Number of NeoPixels (e.g. 16-pixel ring)
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):
# Input a value 0 to 255 to get a color value.
# The colours are a transition r - g - b - back to r.
if (pos < 0) or (pos > 255):
return [0, 0, 0]
elif (pos < 85):
return [int(pos * 3), int(255 - (pos * 3)), 0]
elif (pos < 170):
pos -= 85
return [int(255 - pos * 3), 0, int(pos * 3)]
else:
pos -= 170
return [0, int(pos * 3), int(255 - pos * 3)]
# Input a value 0 to 255 to get a color value.
# The colours are a transition r - g - b - back to r.
if (pos < 0) or (pos > 255):
return [0, 0, 0]
elif pos < 85:
return [int(pos * 3), int(255 - (pos * 3)), 0]
elif pos < 170:
pos -= 85
return [int(255 - pos * 3), 0, int(pos * 3)]
else:
pos -= 170
return [0, int(pos * 3), int(255 - pos * 3)]
mode = 0 # Current animation effect
offset = 0 # Position of spinner animation
hue = 0 # Starting hue
color = wheel(hue & 255) # hue -> RGB color
mode = 0 # Current animation effect
offset = 0 # Position of spinner animation
hue = 0 # Starting hue
color = wheel(hue & 255) # hue -> RGB color
prevtime = time.monotonic() # Time of last animation mode switch
while True: # Loop forever...
if mode == 0: # Random sparkles - lights just one LED at a time
i = random.randint(0, numpix - 1) # Choose random pixel
strip[i] = color # Set it to current color
strip.write() # Refresh LED states
# Set same pixel to "off" color now but DON'T refresh...
# it stays on for now...bot this and the next random
# pixel will be refreshed on the next pass.
strip[i] = [0,0,0]
time.sleep(0.008) # 8 millisecond delay
elif mode == 1: # Spinny wheel (4 LEDs on at a time)
for i in range(numpix): # For each LED...
if ((offset + i) & 7) < 2: # 2 pixels out of 8...
strip[i] = color # are set to current color
else:
strip[i] = [0,0,0] # other pixels are off
strip.write() # Refresh LED states
time.sleep(0.04) # 40 millisecond delay
offset += 1 # Shift animation by 1 pixel on next frame
if offset >= 8: offset = 0
# Additional animation modes could be added here!
if mode == 0: # Random sparkles - lights just one LED at a time
i = random.randint(0, numpix - 1) # Choose random pixel
strip[i] = color # Set it to current color
strip.write() # Refresh LED states
# Set same pixel to "off" color now but DON'T refresh...
# it stays on for now...bot this and the next random
# pixel will be refreshed on the next pass.
strip[i] = [0, 0, 0]
time.sleep(0.008) # 8 millisecond delay
elif mode == 1: # Spinny wheel (4 LEDs on at a time)
for i in range(numpix): # For each LED...
if ((offset + i) & 7) < 2: # 2 pixels out of 8...
strip[i] = color # are set to current color
else:
strip[i] = [0, 0, 0] # other pixels are off
strip.write() # Refresh LED states
time.sleep(0.04) # 40 millisecond delay
offset += 1 # Shift animation by 1 pixel on next frame
if offset >= 8:
offset = 0
# Additional animation modes could be added here!
t = time.monotonic() # Current time in seconds
if (t - prevtime) >= 8: # Every 8 seconds...
mode += 1 # Advance to next mode
if mode > 1: # End of modes?
mode = 0 # Start over from beginning
hue += 80 # And change color
color = wheel(hue & 255)
strip.fill([0,0,0]) # Turn off all pixels
prevtime = t # Record time of last mode change
t = time.monotonic() # Current time in seconds
if (t - prevtime) >= 8: # Every 8 seconds...
mode += 1 # Advance to next mode
if mode > 1: # End of modes?
mode = 0 # Start over from beginning
hue += 80 # And change color
color = wheel(hue & 255)
strip.fill([0, 0, 0]) # Turn off all pixels
prevtime = t # Record time of last mode change

View file

@ -1,8 +1,9 @@
"""Interactive light show using built-in LED and capacitive touch"""
import time
import adafruit_dotstar
import touchio
import board
import touchio
led = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1)
touch_A0 = touchio.TouchIn(board.A0)
@ -33,10 +34,10 @@ def cycle_sequence(seq):
def rainbow_cycle(seq):
"""Rainbow cycle generator"""
rainbow = cycle_sequence(seq)
rainbow_sequence = cycle_sequence(seq)
while True:
# pylint: disable=stop-iteration-return
led[0] = (wheel(next(rainbow)))
led[0] = (wheel(next(rainbow_sequence)))
yield
@ -59,7 +60,6 @@ color_sequences = cycle_sequence(
]
)
cycle_speeds = cycle_sequence([0.1, 0.3, 0.5])
brightness = brightness_cycle()

View file

@ -1,8 +1,9 @@
"""Touch each pad to change red, green, and blue values on the LED"""
import time
import touchio
import adafruit_dotstar
import board
import touchio
led = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1)
touch_A0 = touchio.TouchIn(board.A0)

View file

@ -6,16 +6,17 @@
# Author: Collin Cunningham
# License: MIT License (https://opensource.org/licenses/MIT)
from digitalio import DigitalInOut, Direction, Pull
import board
import time
import board
import neopixel
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
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.fill((0,0,0))
pixels.fill((0, 0, 0))
pixels.show()
# The pins connected to each switch/button
@ -56,18 +57,21 @@ statusled.direction = Direction.OUTPUT
print("Waiting for button presses")
def pressbutton(i):
l = leds[i] # find the switch LED
k = buttonkeys[i] # get the corresp. keycode/str
l.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
l.value = False # turn on LED
kbd.release(k) # send keycode
def pressbutton(index):
switch_led = leds[index] # find the switch LED
k = buttonkeys[index] # get the corresp. keycode/str
switch_led.value = True # turn on LED
kbd.press(k) # send keycode
def releasebutton(index):
switch_led = leds[index] # find the switch LED
k = buttonkeys[index] # get the corresp. keycode/str
switch_led.value = False # turn on LED
kbd.release(k) # send keycode
def lightneopixels():
vals = [0, 0, 0]
# if switch 0 pressed, show blue
@ -82,30 +86,30 @@ def lightneopixels():
vals[0] = 255
# if all pressed, show white
if buttonspressed[0] and buttonspressed[1] and buttonspressed[2]:
vals = [255,255,255]
vals = [255, 255, 255]
# if 0 & 1 pressed, show green
if buttonspressed[0] and buttonspressed[1] and not buttonspressed[2]:
vals = [0,255,0]
pixels.fill((vals[0],vals[1],vals[2]))
vals = [0, 255, 0]
pixels.fill((vals[0], vals[1], vals[2]))
pixels.show()
while True:
# check each button
for button in buttons:
i = buttons.index(button)
if button.value == False: # button is pressed?
buttonspressed[i] = True # save pressed button
if buttonspressedlast[i] == False: # was button not pressed last time?
if button.value is False: # button is pressed?
buttonspressed[i] = True # save pressed button
# was button not pressed last time?
if buttonspressedlast[i] is False:
print("Pressed #%d" % i)
pressbutton(i)
else:
buttonspressed[i] = False # button was not pressed
if buttonspressedlast[i] == True: # was button pressed last time?
buttonspressed[i] = False # button was not pressed
if buttonspressedlast[i] is True: # was button pressed last time?
print("Released #%d" % i)
releasebutton(i)
lightneopixels()
# save pressed buttons as pressed last
buttonspressedlast = list(buttonspressed)
time.sleep(0.01)

View file

@ -1,4 +1,5 @@
import time
from adafruit_circuitplayground.express import cpx
while True:

View file

@ -1,4 +1,5 @@
import time
from adafruit_circuitplayground.express import cpx
blink_speed = 0.5

View file

@ -1,4 +1,5 @@
import time
from adafruit_circuitplayground.express import cpx
while True:

View file

@ -1,14 +1,24 @@
import time
from adafruit_circuitplayground.express import cpx
# pylint: disable=redefined-outer-name
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):
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

View file

@ -13,18 +13,18 @@ last_command = None
brightness_up = 95 # Up arrow
brightness_down = 79 # Down arrow
command_to_color = { # button = color
247: (255, 0, 0), # 1 = red
119: (255, 40, 0), # 2 = orange
183: (255, 150, 0), # 3 = yellow
215: (0, 255, 0), # 4 = green
87: (0, 255, 120), # 5 = teal
151: (0, 255, 255), # 6 = cyan
231: (0, 0, 255), # 7 = blue
103: (180, 0, 255), # 8 = purple
167: (255, 0, 20), # 9 = magenta
command_to_color = { # button = color
247: (255, 0, 0), # 1 = red
119: (255, 40, 0), # 2 = orange
183: (255, 150, 0), # 3 = yellow
215: (0, 255, 0), # 4 = green
87: (0, 255, 120), # 5 = teal
151: (0, 255, 255), # 6 = cyan
231: (0, 0, 255), # 7 = blue
103: (180, 0, 255), # 8 = purple
167: (255, 0, 20), # 9 = magenta
207: (255, 255, 255), # 0 = white
127: (0, 0, 0), # Play/Pause = off
127: (0, 0, 0), # Play/Pause = off
}
while True:

View file

@ -1,5 +1,8 @@
import time
from adafruit_circuitplayground.express import cpx
# pylint: disable=stop-iteration-return
@ -9,12 +12,12 @@ def wheel(pos):
if pos < 0 or pos > 255:
return 0, 0, 0
if pos < 85:
return int(255 - pos*3), int(pos*3), 0
return int(255 - pos * 3), int(pos * 3), 0
if pos < 170:
pos -= 85
return 0, int(255 - pos*3), int(pos*3)
return 0, int(255 - pos * 3), int(pos * 3)
pos -= 170
return int(pos * 3), 0, int(255 - (pos*3))
return int(pos * 3), 0, int(255 - (pos * 3))
def cycle_sequence(seq):
@ -32,13 +35,13 @@ def rainbow_lamp(seq):
color_sequences = cycle_sequence([
range(256), # rainbow_cycle
[0], # red
[10], # orange
[30], # yellow
[85], # green
[137], # cyan
[170], # blue
[213], # purple
[0], # red
[10], # orange
[30], # yellow
[85], # green
[137], # cyan
[170], # blue
[213], # purple
[0, 10, 30, 85, 137, 170, 213], # party mode
])

View file

@ -1,4 +1,5 @@
import time
from adafruit_circuitplayground.express import cpx
@ -8,25 +9,33 @@ def wheel(pos):
if pos < 0 or pos > 255:
return 0, 0, 0
if pos < 85:
return int(255 - pos*3), int(pos*3), 0
return int(255 - pos * 3), int(pos * 3), 0
if pos < 170:
pos -= 85
return 0, int(255 - pos*3), int(pos*3)
return 0, int(255 - pos * 3), int(pos * 3)
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
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):
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):
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
@ -54,13 +63,13 @@ def brightness_lamp():
color_sequences = cycle_sequence([
range(256), # rainbow_cycle
[0], # red
[10], # orange
[30], # yellow
[85], # green
[137], # cyan
[170], # blue
[213], # purple
[0], # red
[10], # orange
[30], # yellow
[85], # green
[137], # cyan
[170], # blue
[213], # purple
[0, 10, 30, 85, 137, 170, 213], # party mode
])

View file

@ -1,13 +1,13 @@
from adafruit_circuitplayground.express import cpx
touchpad_to_color = {
"touch_A1": (255, 0, 0), # red
"touch_A2": (255, 40, 0), # orange
"touch_A1": (255, 0, 0), # red
"touch_A2": (255, 40, 0), # orange
"touch_A3": (255, 150, 0), # yellow
"touch_A4": (0, 255, 0), # green
"touch_A5": (0, 0, 255), # blue
"touch_A4": (0, 255, 0), # green
"touch_A5": (0, 0, 255), # blue
"touch_A6": (180, 0, 255), # purple
"touch_A7": (0, 0, 0), # off
"touch_A7": (0, 0, 0), # off
}
while True:

View file

@ -2,16 +2,16 @@ from adafruit_circuitplayground.express import cpx
while True:
if cpx.touch_A1:
cpx.pixels.fill((255, 0, 0)) # red
cpx.pixels.fill((255, 0, 0)) # red
elif cpx.touch_A2:
cpx.pixels.fill((255, 40, 0)) # orange
cpx.pixels.fill((255, 40, 0)) # orange
elif cpx.touch_A3:
cpx.pixels.fill((255, 150, 0)) # yellow
elif cpx.touch_A4:
cpx.pixels.fill((0, 255, 0)) # green
cpx.pixels.fill((0, 255, 0)) # green
elif cpx.touch_A5:
cpx.pixels.fill((0, 0, 255)) # blue
cpx.pixels.fill((0, 0, 255)) # blue
elif cpx.touch_A6:
cpx.pixels.fill((180, 0, 255)) # purple
elif cpx.touch_A7:
cpx.pixels.fill((0, 0, 0)) # off
cpx.pixels.fill((0, 0, 0)) # off

View file

@ -1,7 +1,8 @@
from digitalio import DigitalInOut, Direction, Pull
import board
import time
import board
from digitalio import DigitalInOut, Direction, Pull
button = DigitalInOut(board.D1)
button.direction = Direction.INPUT
button.pull = Pull.UP
@ -11,8 +12,8 @@ led.direction = Direction.OUTPUT
while True:
if button.value:
led.value = True # check if the pushbutton is pressed.
led.value = True # check if the pushbutton is pressed.
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

View file

@ -3,15 +3,18 @@
# connected to GND, 3.3V, and pin A1
# and prints the results to the REPL
from analogio import AnalogIn
import board
import time
import board
from analogio import AnalogIn
analogin = AnalogIn(board.A1)
def getVoltage(pin): # helper
def getVoltage(pin): # helper
return (pin.value * 3.3) / 65536
while True:
print("Analog Voltage: %f" % getVoltage(analogin))
time.sleep(0.1)
time.sleep(0.1)

View file

@ -1,6 +1,6 @@
from digitalio import DigitalInOut, Direction, Pull
import audioio
import board
from digitalio import DigitalInOut, Direction, Pull
# enable the speaker
spkrenable = DigitalInOut(board.SPEAKER_ENABLE)
@ -19,8 +19,9 @@ buttonB.pull = Pull.DOWN
# The two files assigned to buttons A & B
audiofiles = ["rimshot.wav", "laugh.wav"]
def play_file(filename):
print("playing file "+filename)
print("playing file " + filename)
f = open(filename, "rb")
a = audioio.AudioOut(board.A0, f)
a.play()
@ -28,6 +29,7 @@ def play_file(filename):
pass
print("finished")
while True:
if buttonA.value:
play_file(audiofiles[0])

View file

@ -1,11 +1,12 @@
from digitalio import DigitalInOut, Direction
import array
import math
import time
import audioio
import board
import array
import time
import math
from digitalio import DigitalInOut, Direction
FREQUENCY = 440 # 440 Hz middle 'A'
FREQUENCY = 440 # 440 Hz middle 'A'
SAMPLERATE = 8000 # 8000 samples/second, recommended!
# Generate one period of sine wav.
@ -22,5 +23,5 @@ spkrenable.value = True
sample = audioio.AudioOut(board.SPEAKER, sine_wave)
sample.frequency = SAMPLERATE
sample.play(loop=True) # keep playing the sample over and over
time.sleep(1) # until...
sample.stop() # we tell the board to stop
time.sleep(1) # until...
sample.stop() # we tell the board to stop

View file

@ -1,14 +1,15 @@
# CircuitPlaygroundExpress_Blinky
import digitalio
import board
import time
led = digitalio.DigitalInOut(board.D13) #defines the variable 'led'
led.direction = digitalio.Direction.OUTPUT #set the pin as output
import board
import digitalio
while True: #code below this point loops over and over
led.value = True #turn on the LED
time.sleep(0.5) #pause
led.value = False #turn off the LED
time.sleep(0.5) #pause
led = digitalio.DigitalInOut(board.D13) # defines the variable 'led'
led.direction = digitalio.Direction.OUTPUT # set the pin as output
while True: # code below this point loops over and over
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