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 Hue_Controller/secrets.h
.idea

View file

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

View file

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

View file

@ -1,26 +1,28 @@
import time import time
import board import board
import neopixel import neopixel
try: try:
import urandom as random # for v1.0 API support import urandom as random # for v1.0 API support
except ImportError: except ImportError:
import random import random
numpix = 24 # Number of NeoPixels numpix = 24 # Number of NeoPixels
pixpin = board.D0 # Pin where NeoPixels are connected pixpin = board.D0 # Pin where NeoPixels are connected
strip = neopixel.NeoPixel(pixpin, numpix, brightness=0.3) strip = neopixel.NeoPixel(pixpin, numpix, brightness=0.3)
mode = 0 # Current animation effect mode = 0 # Current animation effect
offset = 0 # Position of spinner animation offset = 0 # Position of spinner animation
color = [255, 0, 0] # RGB color - red color = [255, 0, 0] # RGB color - red
prevtime = time.monotonic() # Time of last animation mode switch prevtime = time.monotonic() # Time of last animation mode switch
while True: # Loop forever... while True: # Loop forever...
if mode == 0: # Random sparkles - lights just one LED at a time if mode == 0: # Random sparkles - lights just one LED at a time
i = random.randint(0, numpix - 1) # Choose random pixel i = random.randint(0, numpix - 1) # Choose random pixel
strip[i] = color # Set it to current color strip[i] = color # Set it to current color
strip.write() # Refresh LED states strip.write() # Refresh LED states
# Set same pixel to "off" color now but DON'T refresh... # Set same pixel to "off" color now but DON'T refresh...
# it stays on for now...bot this and the next random # it stays on for now...bot this and the next random
# pixel will be refreshed on the next pass. # pixel will be refreshed on the next pass.
@ -35,22 +37,22 @@ while True: # Loop forever...
# types, so we get the reversed motion on #2 for free). # types, so we get the reversed motion on #2 for free).
for i in range(numpix): # For each LED... for i in range(numpix): # For each LED...
if ((offset + i) & 7) < 2: # 2 pixels out of 8... if ((offset + i) & 7) < 2: # 2 pixels out of 8...
strip[i] = color # are set to current color strip[i] = color # are set to current color
else: else:
strip[i] = [0, 0, 0] # other pixels are off strip[i] = [0, 0, 0] # other pixels are off
strip.write() # Refresh LED states strip.write() # Refresh LED states
time.sleep(0.04) # 40 millisecond delay time.sleep(0.04) # 40 millisecond delay
offset += 1 # Shift animation by 1 pixel on next frame offset += 1 # Shift animation by 1 pixel on next frame
if offset >= 8: if offset >= 8:
offset = 0 offset = 0
# Additional animation modes could be added here! # Additional animation modes could be added here!
t = time.monotonic() # Current time in seconds t = time.monotonic() # Current time in seconds
if (t - prevtime) >= 8: # Every 8 seconds... if (t - prevtime) >= 8: # Every 8 seconds...
mode += 1 # Advance to next mode mode += 1 # Advance to next mode
if mode > 1: # End of modes? if mode > 1: # End of modes?
mode = 0 # Start over from beginning mode = 0 # Start over from beginning
# Rotate color R->G->B # Rotate color R->G->B
color = [color[2], color[0], color[1]] color = [color[2], color[0], color[1]]
strip.fill([0, 0, 0]) # Turn off all pixels strip.fill([0, 0, 0]) # Turn off all pixels
prevtime = t # Record time of last mode change prevtime = t # Record time of last mode change

View file

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

View file

@ -1,7 +1,8 @@
import time import time
from digitalio import DigitalInOut, Direction
import board import board
import neopixel import neopixel
from digitalio import DigitalInOut, Direction
pixpin = board.D1 pixpin = board.D1
numpix = 8 numpix = 8
@ -11,6 +12,7 @@ led.direction = Direction.OUTPUT
strip = neopixel.NeoPixel(pixpin, numpix, brightness=1, auto_write=True) strip = neopixel.NeoPixel(pixpin, numpix, brightness=1, auto_write=True)
def wheel(pos): def wheel(pos):
# Input a value 0 to 255 to get a color value. # Input a value 0 to 255 to get a color value.
# The colours are a transition r - g - b - back to r. # The colours are a transition r - g - b - back to r.
@ -20,23 +22,27 @@ def wheel(pos):
return (int(pos * 3), int(255 - (pos*3)), 0) return (int(pos * 3), int(255 - (pos*3)), 0)
elif pos < 170: elif pos < 170:
pos -= 85 pos -= 85
return (int(255 - pos*3), 0, int(pos*3)) return (int(255 - pos * 3), 0, int(pos * 3))
else: else:
pos -= 170 pos -= 170
return (0, int(pos*3), int(255 - pos*3)) return (0, int(pos * 3), int(255 - pos * 3))
def rainbow_cycle(wait): def rainbow_cycle(wait):
for j in range(255*5): for j in range(255 * 5):
for i in range(len(strip)): for i in range(len(strip)):
idx = int ((i * 256 / len(strip)) + j) idx = int((i * 256 / len(strip)) + j)
strip[i] = wheel(idx & 255) strip[i] = wheel(idx & 255)
time.sleep(wait) time.sleep(wait)
def rainbow(wait): def rainbow(wait):
for j in range(255): for j in range(255):
for i in range(len(strip)): for i in range(len(strip)):
idx = int (i+j) idx = int(i + j)
strip[i] = wheel(idx & 255) strip[i] = wheel(idx & 255)
time.sleep(wait)
while True: while True:
rainbow_cycle(0.05) rainbow_cycle(0.05)

View file

@ -1,4 +1,5 @@
import time import time
import board import board
import pulseio import pulseio
from digitalio import DigitalInOut, Direction from digitalio import DigitalInOut, Direction
@ -10,10 +11,9 @@ pwm = pulseio.PWMOut(pwm_leds, frequency=1000, duty_cycle=0)
# digital LEDs connected on D2 # digital LEDs connected on D2
digital_leds = DigitalInOut(board.D2) digital_leds = DigitalInOut(board.D2)
digital_leds.direction = Direction.OUTPUT digital_leds.direction = Direction.OUTPUT
brightness = 0 # how bright the LED is
brightness = 0 # how bright the LED is fade_amount = 1285 # 2% steping of 2^16
fade_amount = 1285 # 2% steping of 2^16 counter = 0 # counter to keep track of cycles
counter = 0 # counter to keep track of cycles
while True: while True:

View file

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

View file

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

View file

@ -1,8 +1,9 @@
import digitalio
from board import *
import time import time
import digitalio
from adafruit_hid.keyboard import Keyboard from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode from adafruit_hid.keycode import Keycode
from board import D13, D12, D11, D10, D9, D6, D5, A0, A1, A2, A3, A4, A5
# A simple neat keyboard demo in circuitpython # A simple neat keyboard demo in circuitpython

View file

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

View file

@ -1,7 +1,8 @@
import time import time
import adafruit_sgp30
import board import board
import busio import busio
import adafruit_sgp30
i2c = busio.I2C(board.SCL, board.SDA, frequency=100000) i2c = busio.I2C(board.SCL, board.SDA, frequency=100000)
@ -13,26 +14,29 @@ sgp30.set_iaq_baseline(0x8973, 0x8aae)
# highest tVOC recorded in 30 seconds # highest tVOC recorded in 30 seconds
highest_breath_result = 0 highest_breath_result = 0
def warmup_message():
warmup_time = 20 def warmup_message():
warmup_time = 20
warmup_counter = 0 warmup_counter = 0
co2eq, tvoc = sgp30.iaq_measure() # initial read required to get sensor going # initial read required to get sensor going
sgp30.iaq_measure()
print() print()
print("Warming Up [%d seconds]..." % warmup_time) print("Warming Up [%d seconds]..." % warmup_time)
while ( warmup_counter <= 20 ): while warmup_counter <= 20:
print('.', end='') print('.', end='')
time.sleep(1) time.sleep(1)
warmup_counter += 1 warmup_counter += 1
def get_breath_reading():
breath_time = 30 # seconds to record breath reading def get_breath_reading():
breath_counter = 0 # one second count up to breath_time value breath_time = 30 # seconds to record breath reading
breath_saves = [0] * ( breath_time + 1 ) # initialize list with empty values # one second count up to breath_time value
breath_counter = 0
# initialize list with empty values
breath_saves = [0] * (breath_time + 1)
print() print()
print("We will collect breath samples for 30 seconds.") print("We will collect breath samples for 30 seconds.")
@ -40,27 +44,31 @@ def get_breath_reading():
input(" *** Press a key when ready. *** ") input(" *** Press a key when ready. *** ")
print() print()
while ( breath_counter <= breath_time ): while breath_counter <= breath_time:
co2eq, tvoc = sgp30.iaq_measure() _, tvoc = sgp30.iaq_measure()
breath_saves[breath_counter] = tvoc breath_saves[breath_counter] = tvoc
print(tvoc, ', ', end='') print(tvoc, ', ', end='')
time.sleep(1) time.sleep(1)
breath_counter += 1 breath_counter += 1
breath_saves = sorted(breath_saves) breath_saves = sorted(breath_saves)
highest_breath_result = breath_saves[breath_counter - 1] result = breath_saves[breath_counter - 1]
return result
return(highest_breath_result)
# show the highest reading recorded # show the highest reading recorded
def show_results(highest_breath_result):
def show_results(breath_result):
print() print()
print() print()
print("peak VOC reading:", highest_breath_result) print("peak VOC reading:", breath_result)
print() print()
input("Press any key to test again") input("Press any key to test again")
print() print()
# main # main
while True: while True:
warmup_message() warmup_message()

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,19 +1,20 @@
# CircuitPython IO demo #1 - General Purpose I/O # CircuitPython IO demo #1 - General Purpose I/O
import time import time
from digitalio import DigitalInOut, Direction, Pull
import board import board
from digitalio import DigitalInOut, Direction, Pull
led = DigitalInOut(board.D13) led = DigitalInOut(board.D13)
led.direction = Direction.OUTPUT led.direction = Direction.OUTPUT
switch = DigitalInOut(board.D2) # For Gemma M0, Trinket M0, Metro M0 Express, ItsyBitsy M0 Express # For Gemma M0, Trinket M0, Metro M0 Express, ItsyBitsy M0 Express
switch = DigitalInOut(board.D2)
# switch = DigitalInOut(board.D5) # For Feather M0 Express # switch = DigitalInOut(board.D5) # For Feather M0 Express
# switch = DigitalInOut(board.D7) # For Circuit Playground Express # switch = DigitalInOut(board.D7) # For Circuit Playground Express
switch.direction = Direction.INPUT switch.direction = Direction.INPUT
switch.pull = Pull.UP switch.pull = Pull.UP
while True: while True:
# We could also just do "led.value = not switch.value"! # We could also just do "led.value = not switch.value"!
if switch.value: if switch.value:

View file

@ -1,11 +1,13 @@
# CircuitPython demo - Dotstar # CircuitPython demo - Dotstar
import time import time
import board
import adafruit_dotstar import adafruit_dotstar
import board
num_pixels = 30 num_pixels = 30
pixels = adafruit_dotstar.DotStar(board.A1, board.A2, num_pixels, brightness=0.1, auto_write=False) pixels = adafruit_dotstar.DotStar(
board.A1, board.A2, num_pixels, brightness=0.1, auto_write=False)
def wheel(pos): def wheel(pos):
@ -103,7 +105,8 @@ MAGENTA = (255, 0, 20)
WHITE = (255, 255, 255) WHITE = (255, 255, 255)
while True: while True:
color_fill(RED, 0.5) # Change this number to change how long it stays on each solid color. # Change this number to change how long it stays on each solid color.
color_fill(RED, 0.5)
color_fill(YELLOW, 0.5) color_fill(YELLOW, 0.5)
color_fill(ORANGE, 0.5) color_fill(ORANGE, 0.5)
color_fill(GREEN, 0.5) color_fill(GREEN, 0.5)
@ -114,12 +117,15 @@ while True:
color_fill(MAGENTA, 0.5) color_fill(MAGENTA, 0.5)
color_fill(WHITE, 0.5) color_fill(WHITE, 0.5)
slice_alternating(0.1) # Increase or decrease this to speed up or slow down the animation. # Increase or decrease this to speed up or slow down the animation.
slice_alternating(0.1)
color_fill(WHITE, 0.5) color_fill(WHITE, 0.5)
slice_rainbow(0.1) # Increase or decrease this to speed up or slow down the animation. # Increase or decrease this to speed up or slow down the animation.
slice_rainbow(0.1)
time.sleep(0.5) time.sleep(0.5)
rainbow_cycle(0) # Increase this number to slow down the rainbow animation. # Increase this number to slow down the rainbow animation.
rainbow_cycle(0)

View file

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

View file

@ -1,4 +1,5 @@
import time import time
import analogio import analogio
import board import board
import digitalio import digitalio
@ -21,7 +22,8 @@ def get_voltage(pin):
return (pin.value * 3.3) / 65536 return (pin.value * 3.3) / 65536
def steps(axis): # Maps the potentiometer voltage range to 0-20 in whole numbers def steps(axis):
""" Maps the potentiometer voltage range to 0-20 """
return round((axis - pot_min) / step) return round((axis - pot_min) / step)

View file

@ -1,8 +1,9 @@
# CircuitPython demo - I2C scan # CircuitPython demo - I2C scan
import time
import board import board
import busio import busio
import time
i2c = busio.I2C(board.SCL, board.SDA) i2c = busio.I2C(board.SCL, board.SDA)
@ -10,5 +11,6 @@ while not i2c.try_lock():
pass pass
while True: while True:
print("I2C addresses found:", [hex(device_address) for device_address in i2c.scan()]) print("I2C addresses found:", [hex(device_address)
for device_address in i2c.scan()])
time.sleep(2) time.sleep(2)

View file

@ -1,9 +1,10 @@
# CircuitPython Demo - I2C sensor # CircuitPython Demo - I2C sensor
import time
import adafruit_tsl2561
import board import board
import busio import busio
import adafruit_tsl2561
import time
i2c = busio.I2C(board.SCL, board.SDA) i2c = busio.I2C(board.SCL, board.SDA)
@ -11,7 +12,8 @@ i2c = busio.I2C(board.SCL, board.SDA)
while not i2c.try_lock(): while not i2c.try_lock():
pass pass
# Print the addresses found once # Print the addresses found once
print("I2C addresses found:", [hex(device_address) for device_address in i2c.scan()]) print("I2C addresses found:", [hex(device_address)
for device_address in i2c.scan()])
# Unlock I2C now that we're done scanning. # Unlock I2C now that we're done scanning.
i2c.unlock() i2c.unlock()

View file

@ -1,11 +1,12 @@
import time import time
import board
import neopixel
import adafruit_dotstar import adafruit_dotstar
import board
# For Trinket M0, Gemma M0, and ItsyBitsy M0 Express # For Trinket M0, Gemma M0, and ItsyBitsy M0 Express
led = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1) led = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1)
# For Feather M0 Express, Metro M0 Express, Metro M4 Express, and Circuit Playground Express # For Feather M0 Express, Metro M0 Express, Metro M4 Express, and Circuit
# Playground Express
# led = neopixel.NeoPixel(board.NEOPIXEL, 1) # led = neopixel.NeoPixel(board.NEOPIXEL, 1)
led.brightness = 0.3 led.brightness = 0.3

View file

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

View file

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

View file

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

View file

@ -1,13 +1,15 @@
# CircuitPython demo - NeoPixel # CircuitPython demo - NeoPixel
import time import time
import board import board
import neopixel import neopixel
pixel_pin = board.A1 pixel_pin = board.A1
num_pixels = 8 num_pixels = 8
pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=0.3, auto_write=False) pixels = neopixel.NeoPixel(pixel_pin, num_pixels,
brightness=0.3, auto_write=False)
def wheel(pos): def wheel(pos):
@ -51,7 +53,8 @@ PURPLE = (180, 0, 255)
while True: while True:
pixels.fill(RED) pixels.fill(RED)
pixels.show() pixels.show()
time.sleep(1) # Increase or decrease to change the speed of the solid color change. # Increase or decrease to change the speed of the solid color change.
time.sleep(1)
pixels.fill(GREEN) pixels.fill(GREEN)
pixels.show() pixels.show()
time.sleep(1) time.sleep(1)

View file

@ -1,6 +1,7 @@
# CircuitPython demo - NeoPixel RGBW # CircuitPython demo - NeoPixel RGBW
import time import time
import board import board
import neopixel import neopixel
@ -8,7 +9,8 @@ pixel_pin = board.A1
num_pixels = 8 num_pixels = 8
pixels = neopixel.NeoPixel(pixel_pin, num_pixels, pixels = neopixel.NeoPixel(pixel_pin, num_pixels,
brightness=0.3, auto_write=False, pixel_order=(1, 0, 2, 3)) brightness=0.3, auto_write=False,
pixel_order=(1, 0, 2, 3))
def wheel(pos): def wheel(pos):
@ -52,7 +54,8 @@ PURPLE = (180, 0, 255, 0)
while True: while True:
pixels.fill(RED) pixels.fill(RED)
pixels.show() pixels.show()
time.sleep(1) # Increase or decrease to change the speed of the solid color change. # Increase or decrease to change the speed of the solid color change.
time.sleep(1)
pixels.fill(GREEN) pixels.fill(GREEN)
pixels.show() pixels.show()
time.sleep(1) time.sleep(1)

View file

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

View file

@ -1,17 +1,21 @@
import time import time
import pulseio
import board import board
import pulseio
# For the M0 boards: # For the M0 boards:
piezo = pulseio.PWMOut(board.A2, duty_cycle=0, frequency=440, variable_frequency=True) piezo = pulseio.PWMOut(board.A2, duty_cycle=0,
frequency=440, variable_frequency=True)
# For Metro M4 Express: # For Metro M4 Express:
# piezo = pulseio.PWMOut(board.A1, duty_cycle=0, frequency=440, variable_frequency=True) # piezo = pulseio.PWMOut(
# board.A1, duty_cycle=0, frequency=440, variable_frequency=True
# )
while True: while True:
for f in (262, 294, 330, 349, 392, 440, 494, 523): for f in (262, 294, 330, 349, 392, 440, 494, 523):
piezo.frequency = f piezo.frequency = f
piezo.duty_cycle = 65536 // 2 # On 50% piezo.duty_cycle = 65536 // 2 # On 50%
time.sleep(0.25) # On for 1/4 second time.sleep(0.25) # On for 1/4 second
piezo.duty_cycle = 0 # Off piezo.duty_cycle = 0 # Off
time.sleep(0.05) # Pause between notes time.sleep(0.05) # Pause between notes
time.sleep(0.5) time.sleep(0.5)

View file

@ -1,4 +1,5 @@
import time import time
import board import board
import simpleio import simpleio
@ -8,5 +9,5 @@ while True:
simpleio.tone(board.A2, f, 0.25) # on for 1/4 second simpleio.tone(board.A2, f, 0.25) # on for 1/4 second
# For the Metro M4 Express: # For the Metro M4 Express:
# simpleio.tone(board.A1, f, 0.25) # on for 1/4 second # simpleio.tone(board.A1, f, 0.25) # on for 1/4 second
time.sleep(0.05) # pause between notes time.sleep(0.05) # pause between notes
time.sleep(0.5) time.sleep(0.5)

View file

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

View file

@ -1,8 +1,8 @@
# CircuitPython Demo - USB/Serial echo # CircuitPython Demo - USB/Serial echo
import digitalio
import board import board
import busio import busio
import digitalio
led = digitalio.DigitalInOut(board.D13) led = digitalio.DigitalInOut(board.D13)
led.direction = digitalio.Direction.OUTPUT led.direction = digitalio.Direction.OUTPUT
@ -16,7 +16,8 @@ while True:
if data is not None: if data is not None:
led.value = True led.value = True
data_string = ''.join([chr(b) for b in data]) # convert bytearray to string # convert bytearray to string
data_string = ''.join([chr(b) for b in data])
print(data_string, end="") print(data_string, end="")
led.value = False led.value = False

View file

@ -9,5 +9,5 @@ for pin_name in dir(board):
print("PWM on:", pin_name) # Prints the valid, PWM-capable pins! print("PWM on:", pin_name) # Prints the valid, PWM-capable pins!
except ValueError: # This is the error returned when the pin is invalid. except ValueError: # This is the error returned when the pin is invalid.
print("No PWM on:", pin_name) # Prints the invalid pins. print("No PWM on:", pin_name) # Prints the invalid pins.
except RuntimeError: # This is the error returned when there is a timer conflict. except RuntimeError: # Timer conflict error.
print("Timers in use:", pin_name) # Prints the timer conflict pins. print("Timers in use:", pin_name) # Prints the timer conflict pins.

View file

@ -2,7 +2,7 @@ import board
import busio import busio
def is_hardware_SPI(clock_pin, data_pin): def is_hardware_spi(clock_pin, data_pin):
try: try:
p = busio.SPI(clock_pin, data_pin) p = busio.SPI(clock_pin, data_pin)
p.deinit() p.deinit()
@ -11,7 +11,8 @@ def is_hardware_SPI(clock_pin, data_pin):
return False return False
if is_hardware_SPI(board.A1, board.A2): # Provide the two pins you intend to use. # Provide the two pins you intend to use.
if is_hardware_spi(board.A1, board.A2):
print("This pin combination is hardware SPI!") print("This pin combination is hardware SPI!")
else: else:
print("This pin combination isn't hardware SPI.") print("This pin combination isn't hardware SPI.")

View file

@ -2,7 +2,7 @@ import board
import busio import busio
def is_hardware_UART(tx, rx): def is_hardware_uart(tx, rx):
try: try:
p = busio.UART(tx, rx) p = busio.UART(tx, rx)
p.deinit() p.deinit()
@ -32,7 +32,7 @@ for tx_pin in get_unique_pins():
if rx_pin is tx_pin: if rx_pin is tx_pin:
continue continue
else: else:
if is_hardware_UART(tx_pin, rx_pin): if is_hardware_uart(tx_pin, rx_pin):
print("RX pin:", rx_pin, "\t TX pin:", tx_pin) print("RX pin:", rx_pin, "\t TX pin:", tx_pin)
else: else:
pass pass

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,19 +1,20 @@
# CircuitPython IO demo #1 - General Purpose I/O # CircuitPython IO demo #1 - General Purpose I/O
import time import time
from digitalio import DigitalInOut, Direction, Pull
import board import board
from digitalio import DigitalInOut, Direction, Pull
led = DigitalInOut(board.D13) led = DigitalInOut(board.D13)
led.direction = Direction.OUTPUT led.direction = Direction.OUTPUT
switch = DigitalInOut(board.D2) # For Gemma M0, Trinket M0, Metro M0 Express, ItsyBitsy M0 Express # For Gemma M0, Trinket M0, Metro M0 Express, ItsyBitsy M0 Express
switch = DigitalInOut(board.D2)
# switch = DigitalInOut(board.D5) # For Feather M0 Express # switch = DigitalInOut(board.D5) # For Feather M0 Express
# switch = DigitalInOut(board.D7) # For Circuit Playground Express # switch = DigitalInOut(board.D7) # For Circuit Playground Express
switch.direction = Direction.INPUT switch.direction = Direction.INPUT
switch.pull = Pull.UP switch.pull = Pull.UP
while True: while True:
# We could also just do "led.value = not switch.value"! # We could also just do "led.value = not switch.value"!
if switch.value: if switch.value:

View file

@ -1,11 +1,13 @@
# CircuitPython demo - Dotstar # CircuitPython demo - Dotstar
import time import time
import board
import adafruit_dotstar import adafruit_dotstar
import board
num_pixels = 30 num_pixels = 30
pixels = adafruit_dotstar.DotStar(board.A1, board.A2, num_pixels, brightness=0.1, auto_write=False) pixels = adafruit_dotstar.DotStar(
board.A1, board.A2, num_pixels, brightness=0.1, auto_write=False)
def wheel(pos): def wheel(pos):
@ -103,7 +105,8 @@ MAGENTA = (255, 0, 20)
WHITE = (255, 255, 255) WHITE = (255, 255, 255)
while True: while True:
color_fill(RED, 0.5) # Change this number to change how long it stays on each solid color. # Change this number to change how long it stays on each solid color.
color_fill(RED, 0.5)
color_fill(YELLOW, 0.5) color_fill(YELLOW, 0.5)
color_fill(ORANGE, 0.5) color_fill(ORANGE, 0.5)
color_fill(GREEN, 0.5) color_fill(GREEN, 0.5)
@ -114,12 +117,15 @@ while True:
color_fill(MAGENTA, 0.5) color_fill(MAGENTA, 0.5)
color_fill(WHITE, 0.5) color_fill(WHITE, 0.5)
slice_alternating(0.1) # Increase or decrease this to speed up or slow down the animation. # Increase or decrease this to speed up or slow down the animation.
slice_alternating(0.1)
color_fill(WHITE, 0.5) color_fill(WHITE, 0.5)
slice_rainbow(0.1) # Increase or decrease this to speed up or slow down the animation. # Increase or decrease this to speed up or slow down the animation.
slice_rainbow(0.1)
time.sleep(0.5) time.sleep(0.5)
rainbow_cycle(0) # Increase this number to slow down the rainbow animation. # Increase this number to slow down the rainbow animation.
rainbow_cycle(0)

View file

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

View file

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

View file

@ -1,13 +1,15 @@
# CircuitPython demo - NeoPixel # CircuitPython demo - NeoPixel
import time import time
import board import board
import neopixel import neopixel
pixel_pin = board.A1 pixel_pin = board.A1
num_pixels = 8 num_pixels = 8
pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=0.3, auto_write=False) pixels = neopixel.NeoPixel(pixel_pin, num_pixels,
brightness=0.3, auto_write=False)
def wheel(pos): def wheel(pos):
@ -51,7 +53,8 @@ PURPLE = (180, 0, 255)
while True: while True:
pixels.fill(RED) pixels.fill(RED)
pixels.show() pixels.show()
time.sleep(1) # Increase or decrease to change the speed of the solid color change. # Increase or decrease to change the speed of the solid color change.
time.sleep(1)
pixels.fill(GREEN) pixels.fill(GREEN)
pixels.show() pixels.show()
time.sleep(1) time.sleep(1)

View file

@ -1,6 +1,7 @@
# CircuitPython demo - NeoPixel RGBW # CircuitPython demo - NeoPixel RGBW
import time import time
import board import board
import neopixel import neopixel
@ -8,7 +9,8 @@ pixel_pin = board.A1
num_pixels = 8 num_pixels = 8
pixels = neopixel.NeoPixel(pixel_pin, num_pixels, pixels = neopixel.NeoPixel(pixel_pin, num_pixels,
brightness=0.3, auto_write=False, pixel_order=(1, 0, 2, 3)) brightness=0.3, auto_write=False,
pixel_order=(1, 0, 2, 3))
def wheel(pos): def wheel(pos):
@ -52,7 +54,8 @@ PURPLE = (180, 0, 255, 0)
while True: while True:
pixels.fill(RED) pixels.fill(RED)
pixels.show() pixels.show()
time.sleep(1) # Increase or decrease to change the speed of the solid color change. # Increase or decrease to change the speed of the solid color change.
time.sleep(1)
pixels.fill(GREEN) pixels.fill(GREEN)
pixels.show() pixels.show()
time.sleep(1) time.sleep(1)

View file

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

View file

@ -1,14 +1,16 @@
import time import time
import pulseio
import board
piezo = pulseio.PWMOut(board.A2, duty_cycle=0, frequency=440, variable_frequency=True) import board
import pulseio
piezo = pulseio.PWMOut(board.A2, duty_cycle=0,
frequency=440, variable_frequency=True)
while True: while True:
for f in (262, 294, 330, 349, 392, 440, 494, 523): for f in (262, 294, 330, 349, 392, 440, 494, 523):
piezo.frequency = f piezo.frequency = f
piezo.duty_cycle = 65536 // 2 # On 50% piezo.duty_cycle = 65536 // 2 # On 50%
time.sleep(0.25) # On for 1/4 second time.sleep(0.25) # On for 1/4 second
piezo.duty_cycle = 0 # Off piezo.duty_cycle = 0 # Off
time.sleep(0.05) # Pause between notes time.sleep(0.05) # Pause between notes
time.sleep(0.5) time.sleep(0.5)

View file

@ -1,9 +1,10 @@
import time import time
import board import board
import simpleio import simpleio
while True: while True:
for f in (262, 294, 330, 349, 392, 440, 494, 523): for f in (262, 294, 330, 349, 392, 440, 494, 523):
simpleio.tone(board.A2, f, 0.25) # on for 1/4 second simpleio.tone(board.A2, f, 0.25) # on for 1/4 second
time.sleep(0.05) # pause between notes time.sleep(0.05) # pause between notes
time.sleep(0.5) time.sleep(0.5)

View file

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

View file

@ -1,8 +1,8 @@
# CircuitPython Demo - USB/Serial echo # CircuitPython Demo - USB/Serial echo
import digitalio
import board import board
import busio import busio
import digitalio
led = digitalio.DigitalInOut(board.D13) led = digitalio.DigitalInOut(board.D13)
led.direction = digitalio.Direction.OUTPUT led.direction = digitalio.Direction.OUTPUT
@ -16,7 +16,8 @@ while True:
if data is not None: if data is not None:
led.value = True led.value = True
data_string = ''.join([chr(b) for b in data]) # convert bytearray to string # convert bytearray to string
data_string = ''.join([chr(b) for b in data])
print(data_string, end="") print(data_string, end="")
led.value = False led.value = False

View file

@ -9,5 +9,5 @@ for pin_name in dir(board):
print("PWM on:", pin_name) # Prints the valid, PWM-capable pins! print("PWM on:", pin_name) # Prints the valid, PWM-capable pins!
except ValueError: # This is the error returned when the pin is invalid. except ValueError: # This is the error returned when the pin is invalid.
print("No PWM on:", pin_name) # Prints the invalid pins. print("No PWM on:", pin_name) # Prints the invalid pins.
except RuntimeError: # This is the error returned when there is a timer conflict. except RuntimeError: # Timer conflict error.
print("Timers in use:", pin_name) # Prints the timer conflict pins. print("Timers in use:", pin_name) # Prints the timer conflict pins.

View file

@ -11,7 +11,8 @@ def is_hardware_SPI(clock_pin, data_pin):
return False return False
if is_hardware_SPI(board.A1, board.A2): # Provide the two pins you intend to use. # Provide the two pins you intend to use.
if is_hardware_SPI(board.A1, board.A2):
print("This pin combination is hardware SPI!") print("This pin combination is hardware SPI!")
else: else:
print("This pin combination isn't hardware SPI.") print("This pin combination isn't hardware SPI.")

View file

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

View file

@ -1,24 +1,26 @@
# Gemma M0 version of TVBgone! # Gemma M0 version of TVBgone!
import board
import array import array
import time import time
from digitalio import DigitalInOut, Direction, Pull
import pulseio
import adafruit_dotstar
pixel = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2) import adafruit_dotstar
import board
import pulseio
from digitalio import DigitalInOut, Direction
pixel = adafruit_dotstar.DotStar(
board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2)
pixel.fill((0, 0, 0)) pixel.fill((0, 0, 0))
# Button to see output debug # Button to see output debug
led = DigitalInOut(board.D13) led = DigitalInOut(board.D13)
led.direction = Direction.OUTPUT led.direction = Direction.OUTPUT
pwm = pulseio.PWMOut(board.A1, frequency=38000, duty_cycle=2 ** 15, variable_frequency=True) pwm = pulseio.PWMOut(board.A1, frequency=38000,
duty_cycle=2 ** 15, variable_frequency=True)
pulse = pulseio.PulseOut(pwm) pulse = pulseio.PulseOut(pwm)
time.sleep(0.5) # Give a half second before starting time.sleep(0.5) # Give a half second before starting
# gooooo! # gooooo!
f = open("/codes.txt", "r") f = open("/codes.txt", "r")
for line in f: for line in f:
@ -30,7 +32,7 @@ for line in f:
try: try:
repeat = code['repeat'] repeat = code['repeat']
delay = code['repeat_delay'] delay = code['repeat_delay']
except KeyError: # by default, repeat once only! except KeyError: # by default, repeat once only!
repeat = 1 repeat = 1
delay = 0 delay = 0
# The table holds the on/off pairs # The table holds the on/off pairs
@ -46,5 +48,5 @@ for line in f:
time.sleep(delay) time.sleep(delay)
led.value = False led.value = False
time.sleep(code['delay']) time.sleep(code['delay'])
f.close() f.close()

View file

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

View file

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

View file

@ -1,11 +1,12 @@
# CircuitPython 3.0 CRICKIT demo # CircuitPython 3.0 CRICKIT demo
from adafruit_seesaw.seesaw import Seesaw
from adafruit_seesaw.pwmout import PWMOut
from adafruit_motor import servo, motor
from busio import I2C
import board
import time import time
import board
from adafruit_motor import servo, motor
from adafruit_seesaw.pwmout import PWMOut
from adafruit_seesaw.seesaw import Seesaw
from busio import I2C
i2c = I2C(board.SCL, board.SDA) i2c = I2C(board.SCL, board.SDA)
ss = Seesaw(i2c) ss = Seesaw(i2c)
@ -14,22 +15,22 @@ print("Bubble machine!")
SERVOS = True SERVOS = True
DCMOTORS = True DCMOTORS = True
#################### Create 4 Servos # Create 4 Servos
servos = [] servos = []
if SERVOS: if SERVOS:
for ss_pin in (17, 16, 15, 14): for ss_pin in (17, 16, 15, 14):
pwm = PWMOut(ss, ss_pin) pwm = PWMOut(ss, ss_pin)
pwm.frequency = 50 pwm.frequency = 50
_servo = servo.Servo(pwm) _servo = servo.Servo(pwm)
_servo.angle = 90 # starting angle, middle _servo.angle = 90 # starting angle, middle
servos.append(_servo) servos.append(_servo)
#################### Create 2 DC motors # Create 2 DC motors
motors = [] motors = []
if DCMOTORS: if DCMOTORS:
for ss_pin in ((18, 19), (22, 23)): for ss_pin in ((18, 19), (22, 23)):
pwm0 = PWMOut(ss, ss_pin[0]) pwm0 = PWMOut(ss, ss_pin[0])
pwm1 = PWMOut(ss, ss_pin[1]) pwm1 = PWMOut(ss, ss_pin[1])
_motor = motor.DCMotor(pwm0, pwm1) _motor = motor.DCMotor(pwm0, pwm1)
motors.append(_motor) motors.append(_motor)
@ -45,4 +46,4 @@ while True:
motors[0].throttle = 0 motors[0].throttle = 0
print("servo up") print("servo up")
servos[0].angle = 0 servos[0].angle = 0
time.sleep(1) time.sleep(1)

View file

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

View file

@ -25,8 +25,10 @@
# calibrated with your body touching it (making it less accurate). # calibrated with your body touching it (making it less accurate).
# #
# Also note this depends on two external modules to be loaded on the Gemma M0: # Also note this depends on two external modules to be loaded on the Gemma M0:
# - Adafruit CircuitPython DotStar: https://github.com/adafruit/Adafruit_CircuitPython_DotStar # - Adafruit CircuitPython DotStar:
# - Adafruit CircuitPython FancyLED: https://github.com/adafruit/Adafruit_CircuitPython_FancyLED # https://github.com/adafruit/Adafruit_CircuitPython_DotStar
# - Adafruit CircuitPython FancyLED:
# https://github.com/adafruit/Adafruit_CircuitPython_FancyLED
# #
# You _must_ have both adafruit_dotstar.mpy and the adafruit_fancyled folder # You _must_ have both adafruit_dotstar.mpy and the adafruit_fancyled folder
# and files within it on your board for this code to work! If you run into # and files within it on your board for this code to work! If you run into
@ -38,51 +40,49 @@
import math import math
import time import time
import adafruit_dotstar
import adafruit_fancyled.adafruit_fancyled as fancy
import board import board
import digitalio import digitalio
import touchio import touchio
import adafruit_dotstar
import adafruit_fancyled.adafruit_fancyled as fancy
# Variables that control the code. Try changing these to modify speed, color, # Variables that control the code. Try changing these to modify speed, color,
# etc. # etc.
START_DELAY = 5.0 # How many seconds to wait after power up before START_DELAY = 5.0 # How many seconds to wait after power up before
# jumping into the animation and initializing the # jumping into the animation and initializing the
# touch input. This gives you time to take move your # touch input. This gives you time to take move your
# fingers off the flower so the capacitive touch # fingers off the flower so the capacitive touch
# sensing is better calibrated. During the delay # sensing is better calibrated. During the delay
# the small red LED on the board will flash. # the small red LED on the board will flash.
TOUCH_PIN = board.D0 # The board pin to listen for touches and trigger the TOUCH_PIN = board.D0 # The board pin to listen for touches and trigger the
# heart beat animation. You can change this to any # heart beat animation. You can change this to any
# other pin like board.D2 or board.D1. Make sure not # other pin like board.D2 or board.D1. Make sure not
# to touch this pin as the board powers on or the # to touch this pin as the board powers on or the
# capacitive sensing will get confused (just reset # capacitive sensing will get confused (just reset
# the board and try again). # the board and try again).
BRIGHTNESS = 1.0 # The brightness of the colors. Set this to a value BRIGHTNESS = 1.0 # The brightness of the colors. Set this to a value
# anywhere within 0 and 1.0, where 1.0 is full bright. # anywhere within 0 and 1.0, where 1.0 is full bright.
# For example 0.5 would be half brightness. # For example 0.5 would be half brightness.
RAINBOW_PERIOD_S = 18.0 # How many seconds it takes for the default rainbow RAINBOW_PERIOD_S = 18.0 # How many seconds it takes for the default rainbow
# cycle animation to perform a full cycle. Increase # cycle animation to perform a full cycle. Increase
# this to slow down the animation or decrease to speed # this to slow down the animation or decrease to speed
# it up. # it up.
HEARTBEAT_BPM = 60.0 # Heartbeat animation beats per minute. Increase to HEARTBEAT_BPM = 60.0 # Heartbeat animation beats per minute. Increase to
# speed up the heartbeat, and decrease to slow down. # speed up the heartbeat, and decrease to slow down.
HEARTBEAT_HUE = 300.0 # The color hue to use when animating the heartbeat HEARTBEAT_HUE = 300.0 # The color hue to use when animating the heartbeat
# animation. Pick a value in the range of 0 to 359 # animation. Pick a value in the range of 0 to 359
# degrees, see the hue spectrum here: # degrees, see the hue spectrum here:
# https://en.wikipedia.org/wiki/Hue # https://en.wikipedia.org/wiki/Hue
# A value of 300 is a nice pink color. # A value of 300 is a nice pink color.
# First initialize the DotStar LED and turn it off. # First initialize the DotStar LED and turn it off.
dotstar = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1) dotstar = adafruit_dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1)
dotstar[0] = (0,0,0) dotstar[0] = (0, 0, 0)
# Also make sure the on-board red LED is turned off. # Also make sure the on-board red LED is turned off.
red_led = digitalio.DigitalInOut(board.L) red_led = digitalio.DigitalInOut(board.L)
@ -103,24 +103,29 @@ while time.monotonic() - start <= START_DELAY:
touch = touchio.TouchIn(TOUCH_PIN) touch = touchio.TouchIn(TOUCH_PIN)
# Convert periods to frequencies that are used later in animations. # Convert periods to frequencies that are used later in animations.
rainbow_freq = 1.0/RAINBOW_PERIOD_S rainbow_freq = 1.0 / RAINBOW_PERIOD_S
# Calculcate periods and values used by the heartbeat animation. # Calculcate periods and values used by the heartbeat animation.
beat_period = 60.0/HEARTBEAT_BPM beat_period = 60.0 / HEARTBEAT_BPM
beat_quarter_period = beat_period/4.0 # Quarter period controls the speed of beat_quarter_period = beat_period / 4.0 # Quarter period controls the speed of
# the heartbeat drop-off (using an # the heartbeat drop-off (using an
# exponential decay function). # exponential decay function).
beat_phase = beat_period/5.0 # Phase controls how long in-between beat_phase = beat_period / 5.0 # Phase controls how long in-between
# the two parts of the heart beat
# (the 'ba-boom' of the beat).
# the two parts of the heart beat
# (the 'ba-boom' of the beat).
# Handy function for linear interpolation of a value. Pass in a value # Handy function for linear interpolation of a value. Pass in a value
# x that's within the range x0...x1 and a range y0...y1 to get an output value # x that's within the range x0...x1 and a range y0...y1 to get an output value
# y that's proportionally within y0...y1 based on x within x0...x1. Handy for # y that's proportionally within y0...y1 based on x within x0...x1. Handy for
# transforming a value in one range to a value in another (like Arduino's map # transforming a value in one range to a value in another (like Arduino's map
# function). # function).
def lerp(x, x0, x1, y0, y1): def lerp(x, x0, x1, y0, y1):
return y0+(x-x0)*((y1-y0)/(x1-x0)) return y0 + (x - x0) * ((y1 - y0) / (x1 - x0))
# Main loop below will run forever: # Main loop below will run forever:
while True: while True:
@ -139,8 +144,8 @@ while True:
# out of phase so one occurs a little bit after the other. # out of phase so one occurs a little bit after the other.
t0 = current % beat_period t0 = current % beat_period
t1 = (current + beat_phase) % beat_period t1 = (current + beat_phase) % beat_period
x0 = math.pow(math.e, -t0/beat_quarter_period) x0 = math.pow(math.e, -t0 / beat_quarter_period)
x1 = math.pow(math.e, -t1/beat_quarter_period) x1 = math.pow(math.e, -t1 / beat_quarter_period)
# After calculating both exponential decay values pick the biggest one # After calculating both exponential decay values pick the biggest one
# as the secondary one will occur after the first. Scale each by # as the secondary one will occur after the first. Scale each by
# the global brightness and then convert to RGB color using the fixed # the global brightness and then convert to RGB color using the fixed
@ -149,14 +154,14 @@ while True:
# like we expect for full bright to zero brightness with HSV color # like we expect for full bright to zero brightness with HSV color
# (i.e. no interpolation is necessary). # (i.e. no interpolation is necessary).
val = max(x0, x1) * BRIGHTNESS val = max(x0, x1) * BRIGHTNESS
color = fancy.gamma_adjust(fancy.CHSV(HEARTBEAT_HUE/359.0, 1.0, val)) color = fancy.gamma_adjust(fancy.CHSV(HEARTBEAT_HUE / 359.0, 1.0, val))
dotstar[0] = color.pack() dotstar[0] = color.pack()
else: else:
# The touch input is not being touched (touch.value is False) so # The touch input is not being touched (touch.value is False) so
# compute the hue with a smooth cycle over time. # compute the hue with a smooth cycle over time.
# First use the sine function to smoothly generate a value that goes # First use the sine function to smoothly generate a value that goes
# from -1.0 to 1.0 at a certain frequency to match the rainbow period. # from -1.0 to 1.0 at a certain frequency to match the rainbow period.
x = math.sin(2.0*math.pi*rainbow_freq*current) x = math.sin(2.0 * math.pi * rainbow_freq * current)
# Then compute the hue by converting the sine wave value from something # Then compute the hue by converting the sine wave value from something
# that goes from -1.0 to 1.0 to instead go from 0 to 1.0 hue. # that goes from -1.0 to 1.0 to instead go from 0 to 1.0 hue.
hue = lerp(x, -1.0, 1.0, 0.0, 1.0) hue = lerp(x, -1.0, 1.0, 0.0, 1.0)

View file

@ -34,40 +34,39 @@ import busio
import digitalio import digitalio
import touchio import touchio
# Variables that control the code. Try changing these to modify speed, color, # Variables that control the code. Try changing these to modify speed, color,
# etc. # etc.
START_DELAY = 5.0 # How many seconds to wait after power up before START_DELAY = 5.0 # How many seconds to wait after power up before
# jumping into the animation and initializing the # jumping into the animation and initializing the
# touch input. This gives you time to take move your # touch input. This gives you time to take move your
# fingers off the flower so the capacitive touch # fingers off the flower so the capacitive touch
# sensing is better calibrated. During the delay # sensing is better calibrated. During the delay
# the small red LED on the board will flash. # the small red LED on the board will flash.
TOUCH_PIN = board.D0 # The board pin to listen for touches and trigger the TOUCH_PIN = board.D0 # The board pin to listen for touches and trigger the
# heart beat animation. You can change this to any # heart beat animation. You can change this to any
# other pin like board.D2 or board.D1. Make sure not # other pin like board.D2 or board.D1. Make sure not
# to touch this pin as the board powers on or the # to touch this pin as the board powers on or the
# capacitive sensing will get confused (just reset # capacitive sensing will get confused (just reset
# the board and try again). # the board and try again).
BRIGHTNESS = 1.0 # The brightness of the colors. Set this to a value BRIGHTNESS = 1.0 # The brightness of the colors. Set this to a value
# anywhere within 0 and 1.0, where 1.0 is full bright. # anywhere within 0 and 1.0, where 1.0 is full bright.
# For example 0.5 would be half brightness. # For example 0.5 would be half brightness.
RAINBOW_PERIOD_S = 18.0 # How many seconds it takes for the default rainbow RAINBOW_PERIOD_S = 18.0 # How many seconds it takes for the default rainbow
# cycle animation to perform a full cycle. Increase # cycle animation to perform a full cycle. Increase
# this to slow down the animation or decrease to speed # this to slow down the animation or decrease to speed
# it up. # it up.
HEARTBEAT_BPM = 60.0 # Heartbeat animation beats per minute. Increase to HEARTBEAT_BPM = 60.0 # Heartbeat animation beats per minute. Increase to
# speed up the heartbeat, and decrease to slow down. # speed up the heartbeat, and decrease to slow down.
HEARTBEAT_HUE = 300.0 # The color hue to use when animating the heartbeat HEARTBEAT_HUE = 300.0 # The color hue to use when animating the heartbeat
# animation. Pick a value in the range of 0 to 359 # animation. Pick a value in the range of 0 to 359
# degrees, see the hue spectrum here: # degrees, see the hue spectrum here:
# https://en.wikipedia.org/wiki/Hue # https://en.wikipedia.org/wiki/Hue
# A value of 300 is a nice pink color. # A value of 300 is a nice pink color.
# First initialize the DotStar LED and turn it off. # First initialize the DotStar LED and turn it off.
# We'll manually drive the dotstar instead of depending on the adafruit_dotstar # We'll manually drive the dotstar instead of depending on the adafruit_dotstar
@ -78,7 +77,11 @@ dotstar_spi = busio.SPI(clock=board.APA102_SCK, MOSI=board.APA102_MOSI)
# pixel data, followed by bytes of 0xFF tail (just one for 1 pixel). # pixel data, followed by bytes of 0xFF tail (just one for 1 pixel).
dotstar_data = bytearray([0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, dotstar_data = bytearray([0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
0xFF]) 0xFF])
# Define a function to simplify setting dotstar color. # Define a function to simplify setting dotstar color.
def dotstar_color(rgb_color): def dotstar_color(rgb_color):
# Set the color of the dot star LED. This is barebones dotstar driving # Set the color of the dot star LED. This is barebones dotstar driving
# code for simplicity and less dependency on other libraries. We're only # code for simplicity and less dependency on other libraries. We're only
@ -93,6 +96,8 @@ def dotstar_color(rgb_color):
dotstar_spi.write(dotstar_data) dotstar_spi.write(dotstar_data)
finally: finally:
dotstar_spi.unlock() dotstar_spi.unlock()
# Call the function above to turn off the dotstar initially (set it to all 0). # Call the function above to turn off the dotstar initially (set it to all 0).
dotstar_color((0, 0, 0)) dotstar_color((0, 0, 0))
@ -115,23 +120,24 @@ while time.monotonic() - start <= START_DELAY:
touch = touchio.TouchIn(TOUCH_PIN) touch = touchio.TouchIn(TOUCH_PIN)
# Convert periods to frequencies that are used later in animations. # Convert periods to frequencies that are used later in animations.
rainbow_freq = 1.0/RAINBOW_PERIOD_S rainbow_freq = 1.0 / RAINBOW_PERIOD_S
# Calculcate periods and values used by the heartbeat animation. # Calculcate periods and values used by the heartbeat animation.
beat_period = 60.0/HEARTBEAT_BPM beat_period = 60.0 / HEARTBEAT_BPM
beat_quarter_period = beat_period/4.0 # Quarter period controls the speed of beat_quarter_period = beat_period / 4.0 # Quarter period controls the speed of
# the heartbeat drop-off (using an # the heartbeat drop-off (using an
# exponential decay function). # exponential decay function).
beat_phase = beat_period/5.0 # Phase controls how long in-between beat_phase = beat_period / 5.0 # Phase controls how long in-between
# the two parts of the heart beat # the two parts of the heart beat
# (the 'ba-boom' of the beat). # (the 'ba-boom' of the beat).
# Define a gamma correction lookup table to make colors more accurate. # Define a gamma correction lookup table to make colors more accurate.
# See this guide for more background on gamma correction: # See this guide for more background on gamma correction:
# https://learn.adafruit.com/led-tricks-gamma-correction/ # https://learn.adafruit.com/led-tricks-gamma-correction/
gamma8 = bytearray(256) gamma8 = bytearray(256)
for i in range(len(gamma8)): for i in range(len(gamma8)):
gamma8[i] = int(math.pow(i/255.0, 2.8)*255.0+0.5) & 0xFF gamma8[i] = int(math.pow(i / 255.0, 2.8) * 255.0 + 0.5) & 0xFF
# Define a function to convert from HSV (hue, saturation, value) color to # Define a function to convert from HSV (hue, saturation, value) color to
# RGB colors that DotStar LEDs speak. The HSV color space is a nicer for # RGB colors that DotStar LEDs speak. The HSV color space is a nicer for
@ -140,18 +146,17 @@ for i in range(len(gamma8)):
# value that range from 0 to 1.0. This will also use the gamma correction # value that range from 0 to 1.0. This will also use the gamma correction
# table above to get the most accurate color. Adapted from C/C++ code here: # table above to get the most accurate color. Adapted from C/C++ code here:
# https://www.cs.rit.edu/~ncs/color/t_convert.html # https://www.cs.rit.edu/~ncs/color/t_convert.html
def HSV_to_RGB(h, s, v): def HSV_to_RGB(h, s, v):
r = 0
g = 0
b = 0
if s == 0.0: if s == 0.0:
r = v r = v
g = v g = v
b = v b = v
else: else:
h /= 60.0 # sector 0 to 5 h /= 60.0 # sector 0 to 5
i = int(math.floor(h)) i = int(math.floor(h))
f = h - i # factorial part of h f = h - i # factorial part of h
p = v * (1.0 - s) p = v * (1.0 - s)
q = v * (1.0 - s * f) q = v * (1.0 - s * f)
t = v * (1.0 - s * (1.0 - f)) t = v * (1.0 - s * (1.0 - f))
@ -179,18 +184,22 @@ def HSV_to_RGB(h, s, v):
r = v r = v
g = p g = p
b = q b = q
r = gamma8[int(255.0*r)] r = gamma8[int(255.0 * r)]
g = gamma8[int(255.0*g)] g = gamma8[int(255.0 * g)]
b = gamma8[int(255.0*b)] b = gamma8[int(255.0 * b)]
return (r, g, b) return (r, g, b)
# Another handy function for linear interpolation of a value. Pass in a value # Another handy function for linear interpolation of a value. Pass in a value
# x that's within the range x0...x1 and a range y0...y1 to get an output value # x that's within the range x0...x1 and a range y0...y1 to get an output value
# y that's proportionally within y0...y1 based on x within x0...x1. Handy for # y that's proportionally within y0...y1 based on x within x0...x1. Handy for
# transforming a value in one range to a value in another (like Arduino's map # transforming a value in one range to a value in another (like Arduino's map
# function). # function).
def lerp(x, x0, x1, y0, y1): def lerp(x, x0, x1, y0, y1):
return y0+(x-x0)*((y1-y0)/(x1-x0)) return y0 + (x - x0) * ((y1 - y0) / (x1 - x0))
# Main loop below will run forever: # Main loop below will run forever:
while True: while True:
@ -209,8 +218,8 @@ while True:
# out of phase so one occurs a little bit after the other. # out of phase so one occurs a little bit after the other.
t0 = current % beat_period t0 = current % beat_period
t1 = (current + beat_phase) % beat_period t1 = (current + beat_phase) % beat_period
x0 = math.pow(math.e, -t0/beat_quarter_period) x0 = math.pow(math.e, -t0 / beat_quarter_period)
x1 = math.pow(math.e, -t1/beat_quarter_period) x1 = math.pow(math.e, -t1 / beat_quarter_period)
# After calculating both exponential decay values pick the biggest one # After calculating both exponential decay values pick the biggest one
# as the secondary one will occur after the first. Scale each by # as the secondary one will occur after the first. Scale each by
# the global brightness and then convert to RGB color using the fixed # the global brightness and then convert to RGB color using the fixed
@ -225,7 +234,7 @@ while True:
# compute the hue with a smooth cycle over time. # compute the hue with a smooth cycle over time.
# First use the sine function to smoothly generate a value that goes # First use the sine function to smoothly generate a value that goes
# from -1.0 to 1.0 at a certain frequency to match the rainbow period. # from -1.0 to 1.0 at a certain frequency to match the rainbow period.
x = math.sin(2.0*math.pi*rainbow_freq*current) x = math.sin(2.0 * math.pi * rainbow_freq * current)
# Then compute the hue by converting the sine wave value from something # Then compute the hue by converting the sine wave value from something
# that goes from -1.0 to 1.0 to instead go from 0 to 359 degrees. # that goes from -1.0 to 1.0 to instead go from 0 to 359 degrees.
hue = lerp(x, -1.0, 1.0, 0.0, 359.0) hue = lerp(x, -1.0, 1.0, 0.0, 359.0)

View file

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

View file

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

View file

@ -29,36 +29,38 @@ Explainatory comments are used verbatim from that code.
import math import math
import random import random
import adafruit_dotstar
import adafruit_lsm303
import board import board
import busio import busio
import adafruit_lsm303 N_GRAINS = 10 # Number of grains of sand
import adafruit_dotstar WIDTH = 12 # Display width in pixels
HEIGHT = 6 # Display height in pixels
N_GRAINS = 10 # Number of grains of sand
WIDTH = 12 # Display width in pixels
HEIGHT = 6 # Display height in pixels
NUMBER_PIXELS = WIDTH * HEIGHT NUMBER_PIXELS = WIDTH * HEIGHT
MAX_FPS = 45 # Maximum redraw rate, frames/second MAX_FPS = 45 # Maximum redraw rate, frames/second
GRAIN_COLOR = (0, 0, 16) GRAIN_COLOR = (0, 0, 16)
MAX_X = WIDTH * 256 - 1 MAX_X = WIDTH * 256 - 1
MAX_Y = HEIGHT * 256 - 1 MAX_Y = HEIGHT * 256 - 1
class Grain: class Grain:
"""A simple struct to hold position and velocity information for a single grain.""" """A simple struct to hold position and velocity information
for a single grain."""
def __init__(self): def __init__(self):
"""Initialize grain position and velocity.""" """Initialize grain position and velocity."""
x = 0 self.x = 0
y = 0 self.y = 0
vx = 0 self.vx = 0
vy = 0 self.vy = 0
grains = [Grain() for _ in range(N_GRAINS)] grains = [Grain() for _ in range(N_GRAINS)]
i2c = busio.I2C(board.SCL, board.SDA) i2c = busio.I2C(board.SCL, board.SDA)
sensor = adafruit_lsm303.LSM303(i2c) sensor = adafruit_lsm303.LSM303(i2c)
wing = adafruit_dotstar.DotStar(board.D13, board.D11, WIDTH * HEIGHT, 0.25, False) wing = adafruit_dotstar.DotStar(
board.D13, board.D11, WIDTH * HEIGHT, 0.25, False)
oldidx = 0 oldidx = 0
newidx = 0 newidx = 0
@ -68,19 +70,23 @@ newy = 0
occupied_bits = [False for _ in range(WIDTH * HEIGHT)] occupied_bits = [False for _ in range(WIDTH * HEIGHT)]
def index_of_xy(x, y): def index_of_xy(x, y):
"""Convert an x/column and y/row into an index into a linear pixel array. """Convert an x/column and y/row into an index into
a linear pixel array.
:param int x: column value :param int x: column value
:param int y: row value :param int y: row value
""" """
return (y >> 8) * WIDTH + (x >> 8) return (y >> 8) * WIDTH + (x >> 8)
def already_present(limit, x, y): def already_present(limit, x, y):
"""Check if a pixel is already used. """Check if a pixel is already used.
:param int limit: the index into the grain array of the grain being assigned a pixel :param int limit: the index into the grain array of
Only grains already allocated need to be checks against. the grain being assigned a pixel Only grains already
allocated need to be checks against.
:param int x: proposed clumn value for the new grain :param int x: proposed clumn value for the new grain
:param int y: proposed row valuse for the new grain :param int y: proposed row valuse for the new grain
""" """
@ -89,6 +95,7 @@ def already_present(limit, x, y):
return True return True
return False return False
for g in grains: for g in grains:
placed = False placed = False
while not placed: while not placed:
@ -109,20 +116,20 @@ while True:
# Read accelerometer... # Read accelerometer...
f_x, f_y, f_z = sensor.raw_acceleration f_x, f_y, f_z = sensor.raw_acceleration
ax = f_x >> 8 # Transform accelerometer axes ax = f_x >> 8 # Transform accelerometer axes
ay = f_y >> 8 # to grain coordinate space ay = f_y >> 8 # to grain coordinate space
az = abs(f_z) >> 11 # Random motion factor az = abs(f_z) >> 11 # Random motion factor
az = 1 if (az >= 3) else (4 - az) # Clip & invert az = 1 if (az >= 3) else (4 - az) # Clip & invert
ax -= az # Subtract motion factor from X, Y ax -= az # Subtract motion factor from X, Y
ay -= az ay -= az
az2 = (az << 1) + 1 # Range of random motion to add back in az2 = (az << 1) + 1 # Range of random motion to add back in
# ...and apply 2D accel vector to grain velocities... # ...and apply 2D accel vector to grain velocities...
v2 = 0 # Velocity squared v2 = 0 # Velocity squared
v = 0.0 # Absolute velociy v = 0.0 # Absolute velociy
for g in grains: for g in grains:
g.vx += ax + random.randint(0, az2) # A little randomness makes g.vx += ax + random.randint(0, az2) # A little randomness makes
g.vy += ay + random.randint(0, az2) # tall stacks topple better! g.vy += ay + random.randint(0, az2) # tall stacks topple better!
# Terminal velocity (in any direction) is 256 units -- equal to # Terminal velocity (in any direction) is 256 units -- equal to
# 1 pixel -- which keeps moving grains from passing through each other # 1 pixel -- which keeps moving grains from passing through each other
@ -131,10 +138,10 @@ while True:
# diagonal movement isn't faster # diagonal movement isn't faster
v2 = g.vx * g.vx + g.vy * g.vy v2 = g.vx * g.vx + g.vy * g.vy
if v2 > 65536: # If v^2 > 65536, then v > 256 if v2 > 65536: # If v^2 > 65536, then v > 256
v = math.floor(math.sqrt(v2)) # Velocity vector magnitude v = math.floor(math.sqrt(v2)) # Velocity vector magnitude
g.vx = (g.vx // v) << 8 # Maintain heading g.vx = (g.vx // v) << 8 # Maintain heading
g.vy = (g.vy // v) << 8 # Limit magnitude g.vy = (g.vy // v) << 8 # Limit magnitude
# ...then update position of each grain, one at a time, checking for # ...then update position of each grain, one at a time, checking for
# collisions and having them react. This really seems like it shouldn't # collisions and having them react. This really seems like it shouldn't
@ -148,11 +155,11 @@ while True:
# the tiny 8-bit AVR microcontroller and my tiny dinosaur brain.) # the tiny 8-bit AVR microcontroller and my tiny dinosaur brain.)
for g in grains: for g in grains:
newx = g.x + g.vx # New position in grain space newx = g.x + g.vx # New position in grain space
newy = g.y + g.vy newy = g.y + g.vy
if newx > MAX_X: # If grain would go out of bounds if newx > MAX_X: # If grain would go out of bounds
newx = MAX_X # keep it inside, and newx = MAX_X # keep it inside, and
g.vx //= -2 # give a slight bounce off the wall g.vx //= -2 # give a slight bounce off the wall
elif newx < 0: elif newx < 0:
newx = 0 newx = 0
g.vx //= -2 g.vx //= -2
@ -163,56 +170,66 @@ while True:
newy = 0 newy = 0
g.vy //= -2 g.vy //= -2
oldidx = index_of_xy(g.x, g.y) # prior pixel oldidx = index_of_xy(g.x, g.y) # prior pixel
newidx = index_of_xy(newx, newy) # new pixel newidx = index_of_xy(newx, newy) # new pixel
if oldidx != newidx and occupied_bits[newidx]: # If grain is moving to a new pixel... # If grain is moving to a new pixel...
# but if that pixel is already occupied... if oldidx != newidx and occupied_bits[newidx]:
delta = abs(newidx - oldidx) # What direction when blocked? # but if that pixel is already occupied...
if delta == 1: # 1 pixel left or right # What direction when blocked?
newx = g.x # cancel x motion delta = abs(newidx - oldidx)
g.vx //= -2 # and bounce X velocity (Y is ok) if delta == 1: # 1 pixel left or right
newidx = oldidx # no pixel change newx = g.x # cancel x motion
elif delta == WIDTH: # 1 pixel up or down # and bounce X velocity (Y is ok)
newy = g.y # cancel Y motion g.vx //= -2
g.vy //= -2 # and bounce Y velocity (X is ok) newidx = oldidx # no pixel change
newidx = oldidx # no pixel change elif delta == WIDTH: # 1 pixel up or down
else: # Diagonal intersection is more tricky... newy = g.y # cancel Y motion
# Try skidding along just one axis of motion if possible (start w/ # and bounce Y velocity (X is ok)
# faster axis). Because we've already established that diagonal g.vy //= -2
# (both-axis) motion is occurring, moving on either axis alone WILL newidx = oldidx # no pixel change
# change the pixel index, no need to check that again. else: # Diagonal intersection is more tricky...
if abs(g.vx) > abs(g.vy): # x axis is faster # Try skidding along just one axis of motion if
# possible (start w/ faster axis). Because we've
# already established that diagonal (both-axis)
# motion is occurring, moving on either axis alone
# WILL change the pixel index, no need to check
# that again.
if abs(g.vx) > abs(g.vy): # x axis is faster
newidx = index_of_xy(newx, g.y) newidx = index_of_xy(newx, g.y)
if not occupied_bits[newidx]: # that pixel is free, take it! But... # that pixel is free, take it! But...
newy = g.y # cancel Y motion if not occupied_bits[newidx]:
g.vy //= -2 # and bounce Y velocity newy = g.y # cancel Y motion
else: # X pixel is taken, so try Y... g.vy //= -2 # and bounce Y velocity
else: # X pixel is taken, so try Y...
newidx = index_of_xy(g.x, newy) newidx = index_of_xy(g.x, newy)
if not occupied_bits[newidx]: # Pixel is free, take it, but first... # Pixel is free, take it, but first...
newx = g.x # Cancel X motion if not occupied_bits[newidx]:
g.vx //= -2 # Bounce X velocity newx = g.x # Cancel X motion
else: # both spots are occupied g.vx //= -2 # Bounce X velocity
newx = g.x # Cancel X & Y motion else: # both spots are occupied
newx = g.x # Cancel X & Y motion
newy = g.y newy = g.y
g.vx //= -2 # Bounce X & Y velocity g.vx //= -2 # Bounce X & Y velocity
g.vy //= -2 g.vy //= -2
newidx = oldidx # Not moving newidx = oldidx # Not moving
else: # y axis is faster. start there else: # y axis is faster. start there
newidx = index_of_xy(g.x, newy) newidx = index_of_xy(g.x, newy)
if not occupied_bits[newidx]: # Pixel's free! Take it! But... # Pixel's free! Take it! But...
newx = g.x # Cancel X motion if not occupied_bits[newidx]:
g.vx //= -2 # Bounce X velocity newx = g.x # Cancel X motion
else: # Y pixel is taken, so try X... g.vx //= -2 # Bounce X velocity
else: # Y pixel is taken, so try X...
newidx = index_of_xy(newx, g.y) newidx = index_of_xy(newx, g.y)
if not occupied_bits[newidx]: # Pixel is free, take it, but first... # Pixel is free, take it, but first...
newy = g.y # cancel Y motion if not occupied_bits[newidx]:
g.vy //= -2 # and bounce Y velocity newy = g.y # cancel Y motion
else: # both spots are occupied g.vy //= -2 # and bounce Y velocity
newx = g.x # Cancel X & Y motion else: # both spots are occupied
newx = g.x # Cancel X & Y motion
newy = g.y newy = g.y
g.vx //= -2 # Bounce X & Y velocity g.vx //= -2 # Bounce X & Y velocity
g.vy //= -2 g.vy //= -2
newidx = oldidx # Not moving newidx = oldidx # Not moving
occupied_bits[oldidx] = False occupied_bits[oldidx] = False
occupied_bits[newidx] = True occupied_bits[newidx] = True
g.x = newx g.x = newx

View file

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

View file

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

View file

@ -25,8 +25,8 @@ THE SOFTWARE.
Manage the emulator hardware. Manage the emulator hardware.
""" """
import digitalio
import adafruit_mcp230xx import adafruit_mcp230xx
import digitalio
# control pin values # control pin values
@ -57,7 +57,7 @@ class Emulator(object):
def __init__(self, i2c): def __init__(self, i2c):
self.mcp = adafruit_mcp230xx.MCP23017(i2c) self.mcp = adafruit_mcp230xx.MCP23017(i2c)
self.mcp.iodir = 0x0000 # Make all pins outputs self.mcp.iodir = 0x0000 # Make all pins outputs
# Configure the individual control pins # Configure the individual control pins
@ -85,47 +85,40 @@ class Emulator(object):
self.led_pin.direction = digitalio.Direction.OUTPUT self.led_pin.direction = digitalio.Direction.OUTPUT
self.led_pin.value = False self.led_pin.value = False
def __pulse_write(self): def __pulse_write(self):
self.write_pin.value = WRITE_ENABLED self.write_pin.value = WRITE_ENABLED
self.write_pin.value = WRITE_DISABLED self.write_pin.value = WRITE_DISABLED
def __deactivate_ram(self): def __deactivate_ram(self):
self.chip_select_pin.value = CHIP_DISABLED self.chip_select_pin.value = CHIP_DISABLED
def __activate_ram(self): def __activate_ram(self):
self.chip_select_pin.value = CHIP_ENABLED self.chip_select_pin.value = CHIP_ENABLED
def __reset_address_counter(self): def __reset_address_counter(self):
self.clock_reset_pin.value = RESET_ACTIVE self.clock_reset_pin.value = RESET_ACTIVE
self.clock_reset_pin.value = RESET_INACTIVE self.clock_reset_pin.value = RESET_INACTIVE
def __advance_address_counter(self): def __advance_address_counter(self):
self.address_clock_pin.value = CLOCK_ACTIVE self.address_clock_pin.value = CLOCK_ACTIVE
self.address_clock_pin.value = CLOCK_INACTIVE self.address_clock_pin.value = CLOCK_INACTIVE
def __output_on_port_a(self, data_byte): def __output_on_port_a(self, data_byte):
"""A hack to get around the limitation of the 23017 library to use 8-bit ports""" """A hack to get around the limitation of the 23017
library to use 8-bit ports"""
self.mcp.gpio = (self.mcp.gpio & 0xFF00) | (data_byte & 0x00FF) self.mcp.gpio = (self.mcp.gpio & 0xFF00) | (data_byte & 0x00FF)
def enter_program_mode(self): def enter_program_mode(self):
"""Enter program mode, allowing loading of the emulator RAM.""" """Enter program mode, allowing loading of the emulator RAM."""
self.mode_pin.value = PROGRAMMER_USE self.mode_pin.value = PROGRAMMER_USE
self.led_pin.value = LED_OFF self.led_pin.value = LED_OFF
def enter_emulate_mode(self): def enter_emulate_mode(self):
"""Enter emulate mode, giving control of the emulator ram to the host.""" """Enter emulate mode, giving control of the emulator
ram to the host."""
self.mode_pin.value = EMULATE_USE self.mode_pin.value = EMULATE_USE
self.led_pin.value = LED_ON self.led_pin.value = LED_ON
def load_ram(self, code): def load_ram(self, code):
"""Load the emulator RAM. Automatically switched to program mode. """Load the emulator RAM. Automatically switched to program mode.
:param [byte] code: the list of bytes to load into the emulator RAM :param [byte] code: the list of bytes to load into the emulator RAM

View file

@ -29,18 +29,17 @@ Targeted for the SAMD51 boards.
by Dave Astels by Dave Astels
""" """
import digitalio import adafruit_sdcard
import adafruit_ssd1306
import board import board
import busio import busio
import adafruit_ssd1306 import digitalio
import storage import storage
import adafruit_sdcard from debouncer import Debouncer
from directory_node import DirectoryNode from directory_node import DirectoryNode
from emulator import Emulator from emulator import Emulator
from debouncer import Debouncer
#-------------------------------------------------------------------------------- # --------------------------------------------------------------------------------
# Initialize Rotary encoder # Initialize Rotary encoder
# Encoder button is a digital input with pullup on D2 # Encoder button is a digital input with pullup on D2
@ -55,7 +54,7 @@ rot_b = digitalio.DigitalInOut(board.D3)
rot_b.direction = digitalio.Direction.INPUT rot_b.direction = digitalio.Direction.INPUT
rot_b.pull = digitalio.Pull.UP rot_b.pull = digitalio.Pull.UP
#-------------------------------------------------------------------------------- # --------------------------------------------------------------------------------
# Initialize I2C and OLED # Initialize I2C and OLED
i2c = busio.I2C(board.SCL, board.SDA) i2c = busio.I2C(board.SCL, board.SDA)
@ -65,12 +64,12 @@ oled.fill(0)
oled.text("Initializing SD", 0, 10) oled.text("Initializing SD", 0, 10)
oled.show() oled.show()
#-------------------------------------------------------------------------------- # --------------------------------------------------------------------------------
# Initialize SD card # Initialize SD card
#SD_CS = board.D10 # SD_CS = board.D10
# Connect to the card and mount the filesystem. # Connect to the card and mount the filesystem.
spi = busio.SPI(board.D13, board.D11, board.D12) # SCK, MOSI, MISO spi = busio.SPI(board.D13, board.D11, board.D12) # SCK, MOSI, MISO
cs = digitalio.DigitalInOut(board.D10) cs = digitalio.DigitalInOut(board.D10)
sdcard = adafruit_sdcard.SDCard(spi, cs) sdcard = adafruit_sdcard.SDCard(spi, cs)
vfs = storage.VfsFat(sdcard) vfs = storage.VfsFat(sdcard)
@ -80,8 +79,7 @@ oled.fill(0)
oled.text("Done", 0, 10) oled.text("Done", 0, 10)
oled.show() oled.show()
# --------------------------------------------------------------------------------
#--------------------------------------------------------------------------------
# Initialize globals # Initialize globals
encoder_counter = 0 encoder_counter = 0
@ -101,7 +99,7 @@ current_mode = PROGRAM_MODE
emulator = Emulator(i2c) emulator = Emulator(i2c)
#-------------------------------------------------------------------------------- # --------------------------------------------------------------------------------
# Helper functions # Helper functions
def is_binary_name(filename): def is_binary_name(filename):
@ -138,7 +136,7 @@ def program():
current_dir.force_update() current_dir.force_update()
#-------------------------------------------------------------------------------- # --------------------------------------------------------------------------------
# Main loop # Main loop
current_dir = DirectoryNode(oled, name="/sd") current_dir = DirectoryNode(oled, name="/sd")
@ -196,7 +194,7 @@ while True:
rotary_prev_state = rotary_curr_state rotary_prev_state = rotary_curr_state
# Handle encoder rotation # Handle encoder rotation
if current_mode == PROGRAM_MODE: #Ignore rotation if in EMULATE mode if current_mode == PROGRAM_MODE: # Ignore rotation if in EMULATE mode
if encoder_direction == -1: if encoder_direction == -1:
current_dir.up() current_dir.up()
elif encoder_direction == 1: elif encoder_direction == 1:

View file

@ -6,12 +6,13 @@
# Use a jumper wire from D2 to GND to prevent injection while programming! # Use a jumper wire from D2 to GND to prevent injection while programming!
from digitalio import DigitalInOut, Direction, Pull
import board
import time import time
import board
from adafruit_hid.keyboard import Keyboard from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
from adafruit_hid.keycode import Keycode
from digitalio import DigitalInOut, Direction, Pull
#################################################################### ####################################################################
# Select the target operating system for payload: # Select the target operating system for payload:
@ -53,7 +54,10 @@ led.value = True
# Wait a moment # Wait a moment
pause = 0.25 pause = 0.25
# The functions that follow are the various payloads to deliver # The functions that follow are the various payloads to deliver
def launch_terminal(): def launch_terminal():
if operating_system is 0: if operating_system is 0:
led.value = False led.value = False
@ -105,7 +109,8 @@ def launch_terminal():
time.sleep(2) time.sleep(2)
led.value = False led.value = False
layout.write("echo \'Try to be more careful what you put in your USB port.\'") layout.write(
"echo \'Try to be more careful what you put in your USB port.\'")
time.sleep(pause) time.sleep(pause)
kbd.press(Keycode.ENTER) kbd.press(Keycode.ENTER)
kbd.release_all() kbd.release_all()
@ -130,7 +135,7 @@ def launch_terminal():
time.sleep(pause) time.sleep(pause)
# type a message a few times # type a message a few times
for i in range(3): for _ in range(3):
layout.write("HELLO FRIEND") layout.write("HELLO FRIEND")
# time.sleep(pause) # time.sleep(pause)
kbd.press(Keycode.ENTER) kbd.press(Keycode.ENTER)
@ -138,19 +143,34 @@ def launch_terminal():
# time.sleep(pause) # time.sleep(pause)
time.sleep(2) time.sleep(2)
layout.write(" _ _ _____ _ _ ___ _____ ____ ___ _____ _ _ ____") layout.write(
" _ _ _____ _ _ ___ "
"_____ ____ ___ _____ _ _ ____"
)
kbd.press(Keycode.ENTER) kbd.press(Keycode.ENTER)
kbd.release_all() kbd.release_all()
layout.write("| | | | ____| | | | / _ \ | ___| _ \|_ _| ____| \ | | _ \ ") layout.write(
"| | | | ____| | | | / _ \ | "
" ___| _ \|_ _| ____| \ | | _ \ "
)
kbd.press(Keycode.ENTER) kbd.press(Keycode.ENTER)
kbd.release_all() kbd.release_all()
layout.write("| |_| | _| | | | | | | | | | |_ | |_) || || _| | \| | | | |") layout.write(
"| |_| | _| | | | | | | | | | |"
"_ | |_) || || _| | \| | | | |"
)
kbd.press(Keycode.ENTER) kbd.press(Keycode.ENTER)
kbd.release_all() kbd.release_all()
layout.write("| _ | |___| |___| |__| |_| | | _| | _ < | || |___| |\ | |_| |") layout.write(
"| _ | |___| |___| |__| |_| | | "
" _| | _ < | || |___| |\ | |_| |"
)
kbd.press(Keycode.ENTER) kbd.press(Keycode.ENTER)
kbd.release_all() kbd.release_all()
layout.write("|_| |_|_____|_____|_____\___/ |_| |_| \_\___|_____|_| \_|____/ ") layout.write(
"|_| |_|_____|_____|_____\___/ |_"
"| |_| \_\___|_____|_| \_|____/ "
)
kbd.press(Keycode.ENTER) kbd.press(Keycode.ENTER)
kbd.release_all() kbd.release_all()
@ -159,6 +179,7 @@ def launch_terminal():
kbd.press(Keycode.ENTER) kbd.press(Keycode.ENTER)
kbd.release_all() kbd.release_all()
def download_image(): def download_image():
led.value = False led.value = False
# run this after running 'launch_terminal' # run this after running 'launch_terminal'
@ -178,7 +199,14 @@ def download_image():
# this says where to save image, and where to get it # this says where to save image, and where to get it
led.value = False led.value = False
layout.write('curl -o ~/Desktop/hackimage.jpg https://cdn-learn.adafruit.com/assets/assets/000/051/840/original/hacks_foulFowl.jpg')
url = (
'https://cdn-learn.adafruit.com/assets/assets/000/051/840/'
'original/hacks_foulFowl.jpg'
)
layout.write(
'curl -o ~/Desktop/hackimage.jpg {}'.format(url)
)
time.sleep(pause) time.sleep(pause)
kbd.press(Keycode.ENTER) kbd.press(Keycode.ENTER)
led.value = True led.value = True
@ -200,7 +228,12 @@ def replace_background():
led.value = False led.value = False
# run this after download_image (which ran after launch_terminal) # run this after download_image (which ran after launch_terminal)
# it uses actionscript to change the background # it uses actionscript to change the background
layout.write('osascript -e \'tell application \"System Events\" to set picture of every desktop to (POSIX path of (path to home folder) & \"/Desktop/hackimage.jpg\" as POSIX file as alias)\'') layout.write(
'osascript -e \'tell application \"System Events\" '
'to set picture of every desktop to (POSIX path of '
'(path to home folder) & \"/Desktop/hackimage.jpg\" '
'as POSIX file as alias)\''
)
time.sleep(pause) time.sleep(pause)
kbd.press(Keycode.ENTER) kbd.press(Keycode.ENTER)
kbd.release_all() kbd.release_all()
@ -216,6 +249,7 @@ def replace_background():
led.value = True led.value = True
time.sleep(3) # give it a moment to refresh dock and BG time.sleep(3) # give it a moment to refresh dock and BG
def hide_everything(): def hide_everything():
led.value = False led.value = False
# print("Hiding stuff... ") # print("Hiding stuff... ")
@ -224,6 +258,7 @@ def hide_everything():
time.sleep(10) time.sleep(10)
kbd.release_all() kbd.release_all()
while True: while True:
# check for presence of jumper from GND to D2 # check for presence of jumper from GND to D2
if buttons[0].value is False and payload_delivered is 0: if buttons[0].value is False and payload_delivered is 0:
@ -235,8 +270,7 @@ while True:
led.value = False led.value = False
payload_delivered = 1 payload_delivered = 1
if buttons[0].value is True and payload_delivered is 0: # run it
if buttons[0].value is True and payload_delivered is 0: #run it
led.value = True led.value = True
print("Release the water fowl!") # for debugging in screen or putty print("Release the water fowl!") # for debugging in screen or putty
for i in range(10): # blink 5 times for i in range(10): # blink 5 times

View file

@ -2,9 +2,10 @@
# for Adafruit Circuit Playground express # for Adafruit Circuit Playground express
# with CircuitPython # with CircuitPython
from adafruit_circuitplayground.express import cpx
import time import time
from adafruit_circuitplayground.express import cpx
# Change this number to adjust touch sensitivity threshold, 0 is default # Change this number to adjust touch sensitivity threshold, 0 is default
cpx.adjust_touch_threshold(600) cpx.adjust_touch_threshold(600)
@ -40,11 +41,12 @@ step_pixel = [9, 8, 7, 6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
# step colors # step colors
step_col = [WHITE, RED, YELLOW, GREEN, AQUA, BLUE, PURPLE, BLACK] step_col = [WHITE, RED, YELLOW, GREEN, AQUA, BLUE, PURPLE, BLACK]
def prog_mode(i):
cpx.play_file(audio_files[i]) def prog_mode(index):
step_note[step] = i cpx.play_file(audio_files[index])
step_note[step] = index
cpx.pixels[step_pixel[step]] = step_col[step_note[step]] cpx.pixels[step_pixel[step]] = step_col[step_note[step]]
print("playing file " + audio_files[i]) print("playing file " + audio_files[index])
while True: while True:

View file

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

View file

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

View file

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

View file

@ -1,28 +1,29 @@
# Motion Sensor Alarm # Motion Sensor Alarm
# uses Gemma M0, vibration sensor on A0/GND, & piezo on D0/GND # uses Gemma M0, vibration sensor on A0/GND, & piezo on D0/GND
import time
import pulseio import pulseio
from digitalio import DigitalInOut, Direction, Pull
from analogio import AnalogIn from analogio import AnalogIn
import board import board
import time
piezo = pulseio.PWMOut(board.D0, duty_cycle=0, frequency=440, piezo = pulseio.PWMOut(board.D0, duty_cycle=0, frequency=440,
variable_frequency=True) variable_frequency=True)
vibrationPin = AnalogIn(board.A0) vibrationPin = AnalogIn(board.A0)
def get_voltage(pin): def get_voltage(pin):
return (pin.value * 3.3) / 65536 return (pin.value * 3.3) / 65536
while True: while True:
print((get_voltage(vibrationPin),)) print((get_voltage(vibrationPin),))
vibration = get_voltage(vibrationPin) vibration = get_voltage(vibrationPin)
if vibration < 1: # the sensor has been tripped, you can adjust this value if vibration < 1: # the sensor has been tripped, you can adjust this value
# for sensitivity # for sensitivity
for f in (2620, 4400, 2620, 4400, 2620, 4400, 2620, 4400): for f in (2620, 4400, 2620, 4400, 2620, 4400, 2620, 4400):
piezo.frequency = f piezo.frequency = f
piezo.duty_cycle = 65536//2 # on 50% piezo.duty_cycle = 65536 // 2 # on 50%
time.sleep(0.2) # on 1/5 second time.sleep(0.2) # on 1/5 second
piezo.duty_cycle = 0 # off piezo.duty_cycle = 0 # off
time.sleep(0.02) # pause time.sleep(0.02) # pause

View file

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

View file

@ -1,180 +1,186 @@
# Gemma "Firewalker Lite" sneakers # Gemma "Firewalker Lite" sneakers
# - Uses the following Adafruit parts (X2 for two shoes): # - Uses the following Adafruit parts (X2 for two shoes):
# * Gemma M0 3V microcontroller (#3501) # * Gemma M0 3V microcontroller (#3501)
# * 150 mAh LiPoly battery (#1317) or larger # * 150 mAh LiPoly battery (#1317) or larger
# * Medium vibration sensor switch (#2384) # * Medium vibration sensor switch (#2384)
# * 60/m NeoPixel RGB LED strip (#1138 or #1461) # * 60/m NeoPixel RGB LED strip (#1138 or #1461)
# * LiPoly charger such as #1304 # * LiPoly charger such as #1304
# #
# - originally written by Phil Burgess for Gemma using Arduino # - originally written by Phil Burgess for Gemma using Arduino
# * https://learn.adafruit.com/gemma-led-sneakers # * https://learn.adafruit.com/gemma-led-sneakers
import board import board
import digitalio
import neopixel import neopixel
import time
import digitalio
try: try:
import urandom as random import urandom as random
except ImportError: except ImportError:
import random import random
# Declare a NeoPixel object on led_pin with num_leds as pixels # Declare a NeoPixel object on led_pin with num_leds as pixels
# No auto-write. # No auto-write.
led_pin = board.D1 # Which pin your pixels are connected to led_pin = board.D1 # Which pin your pixels are connected to
num_leds = 40 # How many LEDs you have num_leds = 40 # How many LEDs you have
circumference = 40 # Shoe circumference, in pixels, may be > NUM_LEDS circumference = 40 # Shoe circumference, in pixels, may be > NUM_LEDS
frames_per_second = 50 # Animation frames per second frames_per_second = 50 # Animation frames per second
brightness = 0 # Current wave height brightness = 0 # Current wave height
strip = neopixel.NeoPixel(led_pin, num_leds, brightness=1, auto_write=False) strip = neopixel.NeoPixel(led_pin, num_leds, brightness=1, auto_write=False)
offset = 0 offset = 0
# vibration sensor # vibration sensor
motion_pin = board.D0 # Pin where vibration switch is connected motion_pin = board.D0 # Pin where vibration switch is connected
pin = digitalio.DigitalInOut(motion_pin) pin = digitalio.DigitalInOut(motion_pin)
pin.direction = digitalio.Direction.INPUT pin.direction = digitalio.Direction.INPUT
pin.pull = digitalio.Pull.UP pin.pull = digitalio.Pull.UP
ramping_up = False ramping_up = False
center = 0 # Center point of wave in fixed-point space (0 - 255) center = 0 # Center point of wave in fixed-point space (0 - 255)
speed = 1 # Distance to move between frames (-128 - +127) speed = 1 # Distance to move between frames (-128 - +127)
width = 2 # Width from peak to bottom of triangle wave (0 - 128) width = 2 # Width from peak to bottom of triangle wave (0 - 128)
hue = 3 # Current wave hue (color) see comments later hue = 3 # Current wave hue (color) see comments later
hue_target = 4 # Final hue we're aiming for hue_target = 4 # Final hue we're aiming for
red = 5 # LED RGB color calculated from hue red = 5 # LED RGB color calculated from hue
green = 6 # LED RGB color calculated from hue green = 6 # LED RGB color calculated from hue
blue = 7 # LED RGB color calculated from hue blue = 7 # LED RGB color calculated from hue
y = 0 y = 0
brightness = 0 brightness = 0
count = 0 count = 0
# Gemma can animate 3 of these on 40 LEDs at 50 FPS # Gemma can animate 3 of these on 40 LEDs at 50 FPS
# More LEDs and/or more waves will need lower # More LEDs and/or more waves will need lower
wave = [0] * 8, [0] * 8, [0] * 8 wave = [0] * 8, [0] * 8, [0] * 8
# Note that the speeds of each wave are different prime numbers. # Note that the speeds of each wave are different prime numbers.
# This avoids repetition as the waves move around the # This avoids repetition as the waves move around the
# perimeter...if they were even numbers or multiples of each # perimeter...if they were even numbers or multiples of each
# other, there'd be obvious repetition in the pattern of motion... # other, there'd be obvious repetition in the pattern of motion...
# beat frequencies. # beat frequencies.
n_waves = len(wave) n_waves = len(wave)
# 90 distinct hues (0-89) around color wheel # 90 distinct hues (0-89) around color wheel
hue_table = [ 255, 255, 255, 255, 255, 255, 255, 255, 237, 203, hue_table = [255, 255, 255, 255, 255, 255, 255, 255, 237, 203,
169, 135, 101, 67, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 169, 135, 101, 67, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 18, 52, 86, 120, 154, 188, 222, 0, 0, 0, 0, 0, 0, 18, 52, 86, 120, 154, 188, 222,
255, 255, 255, 255, 255, 255, 255, 255 ] 255, 255, 255, 255, 255, 255, 255, 255]
# Gamma-correction table # Gamma-correction table
gammas = [ gammas = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36, 25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50, 37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68, 51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89, 69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114, 90, 92, 93, 95, 96, 98, 99, 101, 102, 104, 105, 107, 109, 110,
115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142, 112, 114, 115, 117, 119, 120, 122, 124, 126, 127, 129, 131, 133,
144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175, 135, 137, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158,
177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213, 160, 162, 164, 167, 169, 171, 173, 175, 177, 180, 182, 184, 186,
215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 ] 189, 191, 193, 196, 198, 200, 203, 205, 208, 210, 213, 215, 218,
220, 223, 225, 228, 231, 233, 236, 239, 241, 244, 247, 249, 252,
255
]
def h2rgb(hue):
# return value
ret = 0
hue %= 90 def h2rgb(colour_hue):
h = hue_table[hue >> 1] colour_hue %= 90
h = hue_table[colour_hue >> 1]
if ( hue & 1 ): if colour_hue & 1:
ret = h & 15 ret = h & 15
else: else:
ret = ( h >> 4 ) ret = (h >> 4)
return ( ret * 17 ) return ret * 17
def wave_setup(): def wave_setup():
global wave global wave
wave = [ [ 0, 3, 60, 0, 0, 0, 0, 0 ], wave = [[0, 3, 60, 0, 0, 0, 0, 0],
[ 0, -5, 45, 0, 0, 0, 0, 0 ], [0, -5, 45, 0, 0, 0, 0, 0],
[ 0, 7, 30, 0, 0, 0, 0, 0 ] ] [0, 7, 30, 0, 0, 0, 0, 0]]
# assign random starting colors to waves # assign random starting colors to waves
for w in range(n_waves): for wave_index in range(n_waves):
wave[w][hue] = wave[w][hue_target] = 90 + random.randint(0,90) current_wave = wave[wave_index]
wave[w][red] = h2rgb(wave[w][hue] - 30) random_offset = random.randint(0, 90)
wave[w][green] = h2rgb(wave[w][hue])
wave[w][blue] = h2rgb(wave[w][hue] + 30) current_wave[hue] = current_wave[hue_target] = 90 + random_offset
current_wave[red] = h2rgb(current_wave[hue] - 30)
current_wave[green] = h2rgb(current_wave[hue])
current_wave[blue] = h2rgb(current_wave[hue] + 30)
def vibration_detector(): def vibration_detector():
while ( True ): while True:
if not pin.value: if not pin.value:
return(True) return True
while ( True ) :
while True:
# wait for vibration sensor to trigger # wait for vibration sensor to trigger
if ( ramping_up == False ): if not ramping_up:
ramping_up = vibration_detector() ramping_up = vibration_detector()
wave_setup() wave_setup()
# But it's not just a straight shot that it ramps up. # But it's not just a straight shot that it ramps up.
# This is a low-pass filter...it makes the brightness # This is a low-pass filter...it makes the brightness
# value decelerate as it approaches a target (200 in # value decelerate as it approaches a target (200 in
# this case). 207 is used here because integers round # this case). 207 is used here because integers round
# down on division and we'd never reach the target; # down on division and we'd never reach the target;
# it's an ersatz ceil() function: ((199*7)+200+7)/8 = 200; # it's an ersatz ceil() function: ((199*7)+200+7)/8 = 200;
brightness = int( ((brightness * 7) + 207) / 8 ) brightness = int(((brightness * 7) + 207) / 8)
count += 1 count += 1
if ( count == ( circumference + num_leds + 5) ): if count == (circumference + num_leds + 5):
ramping_up = False ramping_up = False
count = 0 count = 0
# Wave positions and colors are updated... # Wave positions and colors are updated...
for w in range(n_waves): for w in range(n_waves):
# Move wave; wraps around ends, is OK! # Move wave; wraps around ends, is OK!
wave[w][center] += wave[w][speed] wave[w][center] += wave[w][speed]
# Hue not currently changing? # Hue not currently changing?
if ( wave[w][hue] == wave[w][hue_target] ): if wave[w][hue] == wave[w][hue_target]:
# There's a tiny random chance of picking a new hue... # There's a tiny random chance of picking a new hue...
if ( not random.randint(frames_per_second * 4, 255) ): if not random.randint(frames_per_second * 4, 255):
# Within 1/3 color wheel # Within 1/3 color wheel
wave[w][hue_target] = random.randint(wave[w][hue] - 30, wave[w][hue] + 30) wave[w][hue_target] = random.randint(
wave[w][hue] - 30, wave[w][hue] + 30)
# This wave's hue is currently shifting... # This wave's hue is currently shifting...
else: else:
if ( wave[w][hue] < wave[w][hue_target] ): if wave[w][hue] < wave[w][hue_target]:
wave[w][hue] += 1 # Move up or wave[w][hue] += 1 # Move up or
else: else:
wave[w][hue] -= 1 # down as needed wave[w][hue] -= 1 # down as needed
# Reached destination? # Reached destination?
if ( wave[w][hue] == wave[w][hue_target] ): if wave[w][hue] == wave[w][hue_target]:
wave[w][hue] = 90 + wave[w][hue] % 90 # Clamp to 90-180 range wave[w][hue] = 90 + wave[w][hue] % 90 # Clamp to 90-180 range
wave[w][hue_target] = wave[w][hue] # Copy to target wave[w][hue_target] = wave[w][hue] # Copy to target
wave[w][red] = h2rgb( wave[w][hue] - 30 ) wave[w][red] = h2rgb(wave[w][hue] - 30)
wave[w][green] = h2rgb( wave[w][hue] ) wave[w][green] = h2rgb(wave[w][hue])
wave[w][blue] = h2rgb( wave[w][hue] + 30) wave[w][blue] = h2rgb(wave[w][hue] + 30)
# Now render the LED strip using the current # Now render the LED strip using the current
# brightness & wave states. # brightness & wave states.
# Each LED in strip is visited just once... # Each LED in strip is visited just once...
for i in range(num_leds): for i in range(num_leds):
# Transform 'i' (LED number in pixel space) to the # Transform 'i' (LED number in pixel space) to the
# equivalent point in 8-bit fixed-point space (0-255) # equivalent point in 8-bit fixed-point space (0-255)
# "* 256" because that would be # "* 256" because that would be
# the start of the (N+1)th pixel # the start of the (N+1)th pixel
@ -182,72 +188,73 @@ while ( True ) :
x = (i * 256 + 127) / circumference x = (i * 256 + 127) / circumference
# LED assumed off, but wave colors will add up here # LED assumed off, but wave colors will add up here
r = g = b = 0 r = g = b = 0
# For each item in wave[] array... # For each item in wave[] array...
for w in range(n_waves): for w_index in range(n_waves):
# Calculate distance from pixel center to wave # Calculate distance from pixel center to wave
# center point, using both signed and unsigned # center point, using both signed and unsigned
# 8-bit integers... # 8-bit integers...
d1 = int( abs(x - wave[w][center]) ) d1 = int(abs(x - wave[w_index][center]))
d2 = int( abs(x - wave[w][center]) ) d2 = int(abs(x - wave[w_index][center]))
# Then take the lesser of the two, resulting in # Then take the lesser of the two, resulting in
# a distance (0-128) # a distance (0-128)
# that 'wraps around' the ends of the strip as # that 'wraps around' the ends of the strip as
# necessary...it's a contiguous ring, and waves # necessary...it's a contiguous ring, and waves
# can move smoothly across the gap. # can move smoothly across the gap.
if ( d2 < d1 ): if d2 < d1:
d1 = d2 # d1 is pixel-to-wave-center distance d1 = d2 # d1 is pixel-to-wave-center distance
# d2 distance, relative to wave width, is then # d2 distance, relative to wave width, is then
# proportional to the wave's brightness at this # proportional to the wave's brightness at this
# pixel (basic linear y=mx+b stuff). # pixel (basic linear y=mx+b stuff).
# Is distance within wave's influence? # Is distance within wave's influence?
# d2 is opposite; distance to wave's end # d2 is opposite; distance to wave's end
if ( d1 < wave[w][width] ): if d1 < wave[w_index][width]:
d2 = wave[w][width] - d1 d2 = wave[w_index][width] - d1
y = int ( brightness * d2 / wave[w][width] ) # 0 to 200 y = int(brightness * d2 / wave[w_index][width]) # 0 to 200
# y is a brightness scale value -- # y is a brightness scale value --
# proportional to, but not exactly equal # proportional to, but not exactly equal
# to, the resulting RGB value. # to, the resulting RGB value.
if ( y < 128 ): # Fade black to RGB color if y < 128: # Fade black to RGB color
# In HSV colorspace, this would be # In HSV colorspace, this would be
# tweaking 'value' # tweaking 'value'
n = int(y * 2 + 1) # 1-256 n = int(y * 2 + 1) # 1-256
r += ( wave[w][red] * n ) >> 8 # More fixed-point math r += (wave[w_index][red] * n) >> 8 # More fixed-point math
g += ( wave[w][green] * n ) >> 8 # Wave color is scaled by 'n' # Wave color is scaled by 'n'
b += ( wave[w][blue] * n ) >> 8 # >>8 is equiv to /256 g += (wave[w_index][green] * n) >> 8
else: # Fade RGB color to white b += (wave[w_index][blue] * n) >> 8 # >>8 is equiv to /256
# In HSV colorspace, this would be tweaking 'saturation' else: # Fade RGB color to white
n = int( ( y - 128 ) * 2 ) # 0-255 affects white level # In HSV colorspace, this tweaks 'saturation'
m = 256 * n n = int((y - 128) * 2) # 0-255 affects white level
n = 256 - n # 1-256 affects RGB level m = 256 * n
r += (m + wave[w][red] * n) >> 8 n = 256 - n # 1-256 affects RGB level
g += (m + wave[w][green] * n) >> 8 r += (m + wave[w_index][red] * n) >> 8
b += (m + wave[w][blue] * n) >> 8 g += (m + wave[w_index][green] * n) >> 8
b += (m + wave[w_index][blue] * n) >> 8
# r,g,b are 16-bit types that accumulate brightness # r,g,b are 16-bit types that accumulate brightness
# from all waves that affect this pixel; may exceed # from all waves that affect this pixel; may exceed
# 255. Now clip to 0-255 range: # 255. Now clip to 0-255 range:
if ( r > 255 ): if r > 255:
r = 255 r = 255
if ( g > 255 ): if g > 255:
g = 255 g = 255
if ( b > 255 ): if b > 255:
b = 255 b = 255
# Store resulting RGB value and we're done with # Store resulting RGB value and we're done with
# this pixel! # this pixel!
strip[i] = (r, g, b) strip[i] = (r, g, b)
# Once rendering is complete, a second pass is made # Once rendering is complete, a second pass is made
# through pixel data applying gamma correction, for # through pixel data applying gamma correction, for
# more perceptually linear colors. # more perceptually linear colors.
# https://learn.adafruit.com/led-tricks-gamma-correction # https://learn.adafruit.com/led-tricks-gamma-correction
for j in range( num_leds ): for j in range(num_leds):
( red_gamma, green_gamma, blue_gamma ) = strip[j] (red_gamma, green_gamma, blue_gamma) = strip[j]
red_gamma = gammas[red_gamma] red_gamma = gammas[red_gamma]
green_gamma = gammas[green_gamma] green_gamma = gammas[green_gamma]
blue_gamma = gammas[blue_gamma] blue_gamma = gammas[blue_gamma]

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,14 +1,24 @@
import time import time
from adafruit_circuitplayground.express import cpx from adafruit_circuitplayground.express import cpx
# pylint: disable=redefined-outer-name # pylint: disable=redefined-outer-name
def upright(x, y, z): def upright(x, y, z):
return abs(x) < accel_threshold and abs(y) < accel_threshold and abs(9.8 - z) < accel_threshold x_up = abs(x) < accel_threshold
y_up = abs(y) < accel_threshold
z_up = abs(9.8 - z) < accel_threshold
return x_up and y_up and z_up
def left_side(x, y, z): def left_side(x, y, z):
return abs(9.8 - x) < accel_threshold and abs(y) < accel_threshold and abs(z) < accel_threshold x_side = abs(9.8 - x) < accel_threshold
y_side = abs(y) < accel_threshold
z_side = abs(z) < accel_threshold
return x_side and y_side and z_side
state = None state = None

View file

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

View file

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

View file

@ -1,4 +1,5 @@
import time import time
from adafruit_circuitplayground.express import cpx from adafruit_circuitplayground.express import cpx
@ -8,25 +9,33 @@ def wheel(pos):
if pos < 0 or pos > 255: if pos < 0 or pos > 255:
return 0, 0, 0 return 0, 0, 0
if pos < 85: if pos < 85:
return int(255 - pos*3), int(pos*3), 0 return int(255 - pos * 3), int(pos * 3), 0
if pos < 170: if pos < 170:
pos -= 85 pos -= 85
return 0, int(255 - pos*3), int(pos*3) return 0, int(255 - pos * 3), int(pos * 3)
pos -= 170 pos -= 170
return int(pos * 3), 0, int(255 - (pos*3)) return int(pos * 3), 0, int(255 - (pos * 3))
# pylint: disable=redefined-outer-name # pylint: disable=redefined-outer-name
def upright(x, y, z): def upright(x, y, z):
return abs(x) < accel_threshold and abs(y) < accel_threshold and abs(9.8 - z) < accel_threshold return abs(x) < accel_threshold \
and abs(y) < accel_threshold \
and abs(9.8 - z) < accel_threshold
def right_side(x, y, z): def right_side(x, y, z):
return abs(-9.8 - x) < accel_threshold and abs(y) < accel_threshold and abs(z) < accel_threshold return abs(-9.8 - x) < accel_threshold \
and abs(y) < accel_threshold \
and abs(z) < accel_threshold
def left_side(x, y, z): def left_side(x, y, z):
return abs(9.8 - x) < accel_threshold and abs(y) < accel_threshold and abs(z) < accel_threshold return abs(9.8 - x) < accel_threshold \
and abs(y) < accel_threshold \
and abs(z) < accel_threshold
# pylint: enable=redefined-outer-name # pylint: enable=redefined-outer-name
@ -54,13 +63,13 @@ def brightness_lamp():
color_sequences = cycle_sequence([ color_sequences = cycle_sequence([
range(256), # rainbow_cycle range(256), # rainbow_cycle
[0], # red [0], # red
[10], # orange [10], # orange
[30], # yellow [30], # yellow
[85], # green [85], # green
[137], # cyan [137], # cyan
[170], # blue [170], # blue
[213], # purple [213], # purple
[0, 10, 30, 85, 137, 170, 213], # party mode [0, 10, 30, 85, 137, 170, 213], # party mode
]) ])

View file

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

View file

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

View file

@ -1,7 +1,8 @@
from digitalio import DigitalInOut, Direction, Pull
import board
import time import time
import board
from digitalio import DigitalInOut, Direction, Pull
button = DigitalInOut(board.D1) button = DigitalInOut(board.D1)
button.direction = Direction.INPUT button.direction = Direction.INPUT
button.pull = Pull.UP button.pull = Pull.UP
@ -11,8 +12,8 @@ led.direction = Direction.OUTPUT
while True: while True:
if button.value: if button.value:
led.value = True # check if the pushbutton is pressed. led.value = True # check if the pushbutton is pressed.
else: else:
led.value = False # turn LED off led.value = False # turn LED off
time.sleep(0.01) # debounce delay time.sleep(0.01) # debounce delay

View file

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

View file

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

View file

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

View file

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

Some files were not shown because too many files have changed in this diff Show more