Merge branch 'master' into hoop-earrings-show-instead-of-write
This commit is contained in:
commit
dd9e457ff7
1495 changed files with 3677174 additions and 2990 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -1,2 +1,5 @@
|
|||
*~
|
||||
Hue_Controller/secrets.h
|
||||
.idea
|
||||
|
||||
CircuitPython_Logger/secrets\.py
|
||||
|
|
|
|||
433
.pylintrc
Normal file
433
.pylintrc
Normal file
|
|
@ -0,0 +1,433 @@
|
|||
[MASTER]
|
||||
|
||||
# A comma-separated list of package or module names from where C extensions may
|
||||
# be loaded. Extensions are loading into the active Python interpreter and may
|
||||
# run arbitrary code
|
||||
extension-pkg-whitelist=
|
||||
|
||||
# Add files or directories to the blacklist. They should be base names, not
|
||||
# paths.
|
||||
ignore=CVS
|
||||
|
||||
# Add files or directories matching the regex patterns to the blacklist. The
|
||||
# regex matches against base names, not paths.
|
||||
ignore-patterns=
|
||||
|
||||
# Python code to execute, usually for sys.path manipulation such as
|
||||
# pygtk.require().
|
||||
#init-hook=
|
||||
|
||||
# Use multiple processes to speed up Pylint.
|
||||
# jobs=1
|
||||
jobs=2
|
||||
|
||||
# List of plugins (as comma separated values of python modules names) to load,
|
||||
# usually to register additional checkers.
|
||||
load-plugins=
|
||||
|
||||
# Pickle collected data for later comparisons.
|
||||
persistent=yes
|
||||
|
||||
# Specify a configuration file.
|
||||
#rcfile=
|
||||
|
||||
# Allow loading of arbitrary C extensions. Extensions are imported into the
|
||||
# active Python interpreter and may run arbitrary code.
|
||||
unsafe-load-any-extension=no
|
||||
|
||||
|
||||
[MESSAGES CONTROL]
|
||||
|
||||
# Only show warnings with the listed confidence levels. Leave empty to show
|
||||
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
|
||||
confidence=
|
||||
|
||||
# Disable the message, report, category or checker with the given id(s). You
|
||||
# can either give multiple identifiers separated by comma (,) or put this
|
||||
# option multiple times (only on the command line, not in the configuration
|
||||
# file where it should appear only once).You can also use "--disable=all" to
|
||||
# disable everything first and then reenable specific checks. For example, if
|
||||
# you want to run only the similarities checker, you can use "--disable=all
|
||||
# --enable=similarities". If you want to run only the classes checker, but have
|
||||
# no Warning level messages displayed, use"--disable=all --enable=classes
|
||||
# --disable=W"
|
||||
# disable=import-error,print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call
|
||||
disable=too-many-instance-attributes,len-as-condition,too-few-public-methods,anomalous-backslash-in-string,no-else-return,simplifiable-if-statement,too-many-arguments,duplicate-code,no-name-in-module,no-member,print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call,import-error,missing-docstring,invalid-name,bad-whitespace,consider-using-enumerate
|
||||
|
||||
# Enable the message, report, category or checker with the given id(s). You can
|
||||
# either give multiple identifier separated by comma (,) or put this option
|
||||
# multiple time (only on the command line, not in the configuration file where
|
||||
# it should appear only once). See also the "--disable" option for examples.
|
||||
enable=
|
||||
|
||||
|
||||
[REPORTS]
|
||||
|
||||
# Python expression which should return a note less than 10 (10 is the highest
|
||||
# note). You have access to the variables errors warning, statement which
|
||||
# respectively contain the number of errors / warnings messages and the total
|
||||
# number of statements analyzed. This is used by the global evaluation report
|
||||
# (RP0004).
|
||||
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
|
||||
|
||||
# Template used to display messages. This is a python new-style format string
|
||||
# used to format the message information. See doc for all details
|
||||
msg-template='{path} {line}: {msg} ({symbol})'
|
||||
|
||||
# Set the output format. Available formats are text, parseable, colorized, json
|
||||
# and msvs (visual studio).You can also give a reporter class, eg
|
||||
# mypackage.mymodule.MyReporterClass.
|
||||
output-format=text
|
||||
|
||||
# Tells whether to display a full report or only the messages
|
||||
reports=no
|
||||
|
||||
# Activate the evaluation score.
|
||||
score=yes
|
||||
|
||||
|
||||
[REFACTORING]
|
||||
|
||||
# Maximum number of nested blocks for function / method body
|
||||
max-nested-blocks=5
|
||||
|
||||
|
||||
[LOGGING]
|
||||
|
||||
# Logging modules to check that the string format arguments are in logging
|
||||
# function parameter format
|
||||
logging-modules=logging
|
||||
|
||||
|
||||
[SPELLING]
|
||||
|
||||
# Spelling dictionary name. Available dictionaries: none. To make it working
|
||||
# install python-enchant package.
|
||||
spelling-dict=
|
||||
|
||||
# List of comma separated words that should not be checked.
|
||||
spelling-ignore-words=
|
||||
|
||||
# A path to a file that contains private dictionary; one word per line.
|
||||
spelling-private-dict-file=
|
||||
|
||||
# Tells whether to store unknown words to indicated private dictionary in
|
||||
# --spelling-private-dict-file option instead of raising a message.
|
||||
spelling-store-unknown-words=no
|
||||
|
||||
|
||||
[MISCELLANEOUS]
|
||||
|
||||
# List of note tags to take in consideration, separated by a comma.
|
||||
# notes=FIXME,XXX,TODO
|
||||
notes=FIXME,XXX
|
||||
|
||||
|
||||
[TYPECHECK]
|
||||
|
||||
# List of decorators that produce context managers, such as
|
||||
# contextlib.contextmanager. Add to this list to register other decorators that
|
||||
# produce valid context managers.
|
||||
contextmanager-decorators=contextlib.contextmanager
|
||||
|
||||
# List of members which are set dynamically and missed by pylint inference
|
||||
# system, and so shouldn't trigger E1101 when accessed. Python regular
|
||||
# expressions are accepted.
|
||||
generated-members=
|
||||
|
||||
# Tells whether missing members accessed in mixin class should be ignored. A
|
||||
# mixin class is detected if its name ends with "mixin" (case insensitive).
|
||||
ignore-mixin-members=yes
|
||||
|
||||
# This flag controls whether pylint should warn about no-member and similar
|
||||
# checks whenever an opaque object is returned when inferring. The inference
|
||||
# can return multiple potential results while evaluating a Python object, but
|
||||
# some branches might not be evaluated, which results in partial inference. In
|
||||
# that case, it might be useful to still emit no-member and other checks for
|
||||
# the rest of the inferred objects.
|
||||
ignore-on-opaque-inference=yes
|
||||
|
||||
# List of class names for which member attributes should not be checked (useful
|
||||
# for classes with dynamically set attributes). This supports the use of
|
||||
# qualified names.
|
||||
ignored-classes=optparse.Values,thread._local,_thread._local
|
||||
|
||||
# List of module names for which member attributes should not be checked
|
||||
# (useful for modules/projects where namespaces are manipulated during runtime
|
||||
# and thus existing member attributes cannot be deduced by static analysis. It
|
||||
# supports qualified module names, as well as Unix pattern matching.
|
||||
ignored-modules=
|
||||
|
||||
# Show a hint with possible names when a member name was not found. The aspect
|
||||
# of finding the hint is based on edit distance.
|
||||
missing-member-hint=yes
|
||||
|
||||
# The minimum edit distance a name should have in order to be considered a
|
||||
# similar match for a missing member name.
|
||||
missing-member-hint-distance=1
|
||||
|
||||
# The total number of similar names that should be taken in consideration when
|
||||
# showing a hint for a missing member.
|
||||
missing-member-max-choices=1
|
||||
|
||||
|
||||
[VARIABLES]
|
||||
|
||||
# List of additional names supposed to be defined in builtins. Remember that
|
||||
# you should avoid to define new builtins when possible.
|
||||
additional-builtins=
|
||||
|
||||
# Tells whether unused global variables should be treated as a violation.
|
||||
allow-global-unused-variables=yes
|
||||
|
||||
# List of strings which can identify a callback function by name. A callback
|
||||
# name must start or end with one of those strings.
|
||||
callbacks=cb_,_cb
|
||||
|
||||
# A regular expression matching the name of dummy variables (i.e. expectedly
|
||||
# not used).
|
||||
dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
|
||||
|
||||
# Argument names that match this expression will be ignored. Default to name
|
||||
# with leading underscore
|
||||
ignored-argument-names=_.*|^ignored_|^unused_
|
||||
|
||||
# Tells whether we should check for unused import in __init__ files.
|
||||
init-import=no
|
||||
|
||||
# List of qualified module names which can have objects that can redefine
|
||||
# builtins.
|
||||
redefining-builtins-modules=six.moves,future.builtins
|
||||
|
||||
|
||||
[FORMAT]
|
||||
|
||||
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
|
||||
# expected-line-ending-format=
|
||||
expected-line-ending-format=LF
|
||||
|
||||
# Regexp for a line that is allowed to be longer than the limit.
|
||||
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
|
||||
|
||||
# Number of spaces of indent required inside a hanging or continued line.
|
||||
indent-after-paren=4
|
||||
|
||||
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
|
||||
# tab).
|
||||
indent-string=' '
|
||||
|
||||
# Maximum number of characters on a single line.
|
||||
max-line-length=100
|
||||
|
||||
# Maximum number of lines in a module
|
||||
max-module-lines=1000
|
||||
|
||||
# List of optional constructs for which whitespace checking is disabled. `dict-
|
||||
# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
|
||||
# `trailing-comma` allows a space between comma and closing bracket: (a, ).
|
||||
# `empty-line` allows space-only lines.
|
||||
no-space-check=trailing-comma,dict-separator
|
||||
|
||||
# Allow the body of a class to be on the same line as the declaration if body
|
||||
# contains single statement.
|
||||
single-line-class-stmt=no
|
||||
|
||||
# Allow the body of an if to be on the same line as the test if there is no
|
||||
# else.
|
||||
single-line-if-stmt=no
|
||||
|
||||
|
||||
[SIMILARITIES]
|
||||
|
||||
# Ignore comments when computing similarities.
|
||||
ignore-comments=yes
|
||||
|
||||
# Ignore docstrings when computing similarities.
|
||||
ignore-docstrings=yes
|
||||
|
||||
# Ignore imports when computing similarities.
|
||||
ignore-imports=no
|
||||
|
||||
# Minimum lines number of a similarity.
|
||||
min-similarity-lines=4
|
||||
|
||||
|
||||
[BASIC]
|
||||
|
||||
# Naming hint for argument names
|
||||
argument-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
# Regular expression matching correct argument names
|
||||
argument-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
# Naming hint for attribute names
|
||||
attr-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
# Regular expression matching correct attribute names
|
||||
attr-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
# Bad variable names which should always be refused, separated by a comma
|
||||
bad-names=foo,bar,baz,toto,tutu,tata
|
||||
|
||||
# Naming hint for class attribute names
|
||||
class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
|
||||
|
||||
# Regular expression matching correct class attribute names
|
||||
class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
|
||||
|
||||
# Naming hint for class names
|
||||
# class-name-hint=[A-Z_][a-zA-Z0-9]+$
|
||||
class-name-hint=[A-Z_][a-zA-Z0-9_]+$
|
||||
|
||||
# Regular expression matching correct class names
|
||||
# class-rgx=[A-Z_][a-zA-Z0-9]+$
|
||||
class-rgx=[A-Z_][a-zA-Z0-9_]+$
|
||||
|
||||
# Naming hint for constant names
|
||||
const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$
|
||||
|
||||
# Regular expression matching correct constant names
|
||||
const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
|
||||
|
||||
# Minimum line length for functions/classes that require docstrings, shorter
|
||||
# ones are exempt.
|
||||
docstring-min-length=-1
|
||||
|
||||
# Naming hint for function names
|
||||
function-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
# Regular expression matching correct function names
|
||||
function-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
# Good variable names which should always be accepted, separated by a comma
|
||||
# good-names=i,j,k,ex,Run,_
|
||||
good-names=r,g,b,w,i,j,k,n,x,y,z,ex,ok,Run,_
|
||||
|
||||
# Include a hint for the correct naming format with invalid-name
|
||||
include-naming-hint=no
|
||||
|
||||
# Naming hint for inline iteration names
|
||||
inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$
|
||||
|
||||
# Regular expression matching correct inline iteration names
|
||||
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
|
||||
|
||||
# Naming hint for method names
|
||||
method-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
# Regular expression matching correct method names
|
||||
method-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
# Naming hint for module names
|
||||
module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
|
||||
|
||||
# Regular expression matching correct module names
|
||||
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
|
||||
|
||||
# Colon-delimited sets of names that determine each other's naming style when
|
||||
# the name regexes allow several styles.
|
||||
name-group=
|
||||
|
||||
# Regular expression which should only match function or class names that do
|
||||
# not require a docstring.
|
||||
no-docstring-rgx=^_
|
||||
|
||||
# List of decorators that produce properties, such as abc.abstractproperty. Add
|
||||
# to this list to register other decorators that produce valid properties.
|
||||
property-classes=abc.abstractproperty
|
||||
|
||||
# Naming hint for variable names
|
||||
variable-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
# Regular expression matching correct variable names
|
||||
variable-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
||||
|
||||
|
||||
[IMPORTS]
|
||||
|
||||
# Allow wildcard imports from modules that define __all__.
|
||||
allow-wildcard-with-all=no
|
||||
|
||||
# Analyse import fallback blocks. This can be used to support both Python 2 and
|
||||
# 3 compatible code, which means that the block might have code that exists
|
||||
# only in one or another interpreter, leading to false positives when analysed.
|
||||
analyse-fallback-blocks=no
|
||||
|
||||
# Deprecated modules which should not be used, separated by a comma
|
||||
deprecated-modules=optparse,tkinter.tix
|
||||
|
||||
# Create a graph of external dependencies in the given file (report RP0402 must
|
||||
# not be disabled)
|
||||
ext-import-graph=
|
||||
|
||||
# Create a graph of every (i.e. internal and external) dependencies in the
|
||||
# given file (report RP0402 must not be disabled)
|
||||
import-graph=
|
||||
|
||||
# Create a graph of internal dependencies in the given file (report RP0402 must
|
||||
# not be disabled)
|
||||
int-import-graph=
|
||||
|
||||
# Force import order to recognize a module as part of the standard
|
||||
# compatibility libraries.
|
||||
known-standard-library=
|
||||
|
||||
# Force import order to recognize a module as part of a third party library.
|
||||
known-third-party=enchant
|
||||
|
||||
|
||||
[CLASSES]
|
||||
|
||||
# List of method names used to declare (i.e. assign) instance attributes.
|
||||
defining-attr-methods=__init__,__new__,setUp
|
||||
|
||||
# List of member names, which should be excluded from the protected access
|
||||
# warning.
|
||||
exclude-protected=_asdict,_fields,_replace,_source,_make
|
||||
|
||||
# List of valid names for the first argument in a class method.
|
||||
valid-classmethod-first-arg=cls
|
||||
|
||||
# List of valid names for the first argument in a metaclass class method.
|
||||
valid-metaclass-classmethod-first-arg=mcs
|
||||
|
||||
|
||||
[DESIGN]
|
||||
|
||||
# Maximum number of arguments for function / method
|
||||
max-args=5
|
||||
|
||||
# Maximum number of attributes for a class (see R0902).
|
||||
# max-attributes=7
|
||||
max-attributes=11
|
||||
|
||||
# Maximum number of boolean expressions in a if statement
|
||||
max-bool-expr=5
|
||||
|
||||
# Maximum number of branch for function / method body
|
||||
max-branches=12
|
||||
|
||||
# Maximum number of locals for function / method body
|
||||
max-locals=15
|
||||
|
||||
# Maximum number of parents for a class (see R0901).
|
||||
max-parents=7
|
||||
|
||||
# Maximum number of public methods for a class (see R0904).
|
||||
max-public-methods=20
|
||||
|
||||
# Maximum number of return / yield for function / method body
|
||||
max-returns=6
|
||||
|
||||
# Maximum number of statements in function / method body
|
||||
max-statements=50
|
||||
|
||||
# Minimum number of public methods for a class (see R0903).
|
||||
min-public-methods=1
|
||||
|
||||
|
||||
[EXCEPTIONS]
|
||||
|
||||
# Exceptions that will emit a warning when being caught. Defaults to
|
||||
# "Exception"
|
||||
overgeneral-exceptions=Exception
|
||||
35
.travis.yml
Normal file
35
.travis.yml
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
dist: trusty
|
||||
sudo: false
|
||||
language: python
|
||||
python:
|
||||
- "3.6"
|
||||
|
||||
cache:
|
||||
|
||||
cache:
|
||||
pip: true
|
||||
directories:
|
||||
- ~/arduino_ide
|
||||
- ~/.arduino15/packages/
|
||||
- ~/Arduino
|
||||
|
||||
env:
|
||||
global:
|
||||
- ARDUINO_IDE_VERSION="1.8.7"
|
||||
- PRETTYNAME="Adafruit Learning System Guides"
|
||||
- PLATFORM_CHECK_ONLY_ON_FILE=true
|
||||
|
||||
before_install:
|
||||
- source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/install.sh)
|
||||
|
||||
install:
|
||||
- ./arduino_libinstall
|
||||
- pip install --force-reinstall pylint==1.9.2
|
||||
|
||||
script:
|
||||
- ./pylint_check
|
||||
- build_main_platforms
|
||||
- build_aux_platforms
|
||||
- build_cplay_platforms
|
||||
- build_m4_platforms
|
||||
- build_io_platforms
|
||||
73
3D_Printed_Bionic_Eye/3D_Printed_Bionic_Eye.ino
Normal file
73
3D_Printed_Bionic_Eye/3D_Printed_Bionic_Eye.ino
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/*******************************************************************
|
||||
Bionic Eye sketch for Adafruit Trinket.
|
||||
|
||||
by Bill Earl
|
||||
for Adafruit Industries
|
||||
|
||||
Required library is the Adafruit_SoftServo library
|
||||
available at https://github.com/adafruit/Adafruit_SoftServo
|
||||
The standard Arduino IDE servo library will not work with 8 bit
|
||||
AVR microcontrollers like Trinket and Gemma due to differences
|
||||
in available timer hardware and programming. We simply refresh
|
||||
by piggy-backing on the timer0 millis() counter
|
||||
|
||||
Trinket: Bat+ Gnd Pin #0 Pin #1
|
||||
Connection: Servo+ Servo- Tilt Rotate
|
||||
(Red) (Brown) Servo Servo
|
||||
(Orange)(Orange)
|
||||
|
||||
*******************************************************************/
|
||||
|
||||
#include <Adafruit_SoftServo.h> // SoftwareServo (works on non PWM pins)
|
||||
|
||||
#define TILTSERVOPIN 0 // Servo control line (orange) on Trinket Pin #0
|
||||
#define ROTATESERVOPIN 1 // Servo control line (orange) on Trinket Pin #1
|
||||
|
||||
Adafruit_SoftServo TiltServo, RotateServo; //create TWO servo objects
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Set up the interrupt that will refresh the servo for us automagically
|
||||
OCR0A = 0xAF; // any number is OK
|
||||
TIMSK |= _BV(OCIE0A); // Turn on the compare interrupt (below!)
|
||||
|
||||
TiltServo.attach(TILTSERVOPIN); // Attach the servo to pin 0 on Trinket
|
||||
RotateServo.attach(ROTATESERVOPIN); // Attach the servo to pin 1 on Trinket
|
||||
delay(15); // Wait 15ms for the servo to reach the position
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
delay(100);
|
||||
TiltServo.detach(); // release the servo
|
||||
RotateServo.detach(); // release the servo
|
||||
|
||||
if(random(100) > 80) // on average, move once every 500ms
|
||||
{
|
||||
TiltServo.attach(TILTSERVOPIN); // Attach the servo to pin 0 on Trinket
|
||||
TiltServo.write(random(120, 180)); // Tell servo to go to position
|
||||
}
|
||||
if(random(100) > 90) // on average, move once every 500ms
|
||||
{
|
||||
RotateServo.attach(ROTATESERVOPIN); // Attach the servo to pin 1 on Trinket
|
||||
RotateServo.write(random(0, 180)); // Tell servo to go to position
|
||||
}
|
||||
}
|
||||
|
||||
// We'll take advantage of the built in millis() timer that goes off
|
||||
// to keep track of time, and refresh the servo every 20 milliseconds
|
||||
// The SIGNAL(TIMER0_COMPA_vect) function is the interrupt that will be
|
||||
// Called by the microcontroller every 2 milliseconds
|
||||
volatile uint8_t counter = 0;
|
||||
SIGNAL(TIMER0_COMPA_vect)
|
||||
{
|
||||
// this gets called every 2 milliseconds
|
||||
counter += 2;
|
||||
// every 20 milliseconds, refresh the servos!
|
||||
if (counter >= 20)
|
||||
{
|
||||
counter = 0;
|
||||
TiltServo.refresh();
|
||||
RotateServo.refresh();
|
||||
}
|
||||
}
|
||||
50
3D_Printed_Bionic_Eye/3D_Printed_Bionic_Eye.py
Normal file
50
3D_Printed_Bionic_Eye/3D_Printed_Bionic_Eye.py
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
# Bionic Eye sketch for Adafruit Trinket.
|
||||
#
|
||||
# written by Bill Earl for Arduino
|
||||
# ported to CircuitPython by Mikey Sklar
|
||||
# for Adafruit Industries
|
||||
#
|
||||
# Required library is the Adafruit_SoftServo library
|
||||
# available at https://github.com/adafruit/Adafruit_SoftServo
|
||||
# The standard Arduino IDE servo library will not work with 8 bit
|
||||
# AVR microcontrollers like Trinket and Gemma due to differences
|
||||
# in available timer hardware and programming. We simply refresh
|
||||
# by piggy-backing on the timer0 millis() counter
|
||||
#
|
||||
# Trinket: Bat+ Gnd Pin #0 Pin #2
|
||||
# Connection: Servo+ Servo- Tilt Rotate
|
||||
# (Red) (Black) Servo Servo
|
||||
# (Orange)(Orange)
|
||||
|
||||
import time
|
||||
import random
|
||||
import board
|
||||
import pulseio
|
||||
from adafruit_motor import servo
|
||||
|
||||
# we are intentionally avoiding Trinket Pin #1 (board.A0)
|
||||
# as it does not have PWM capability
|
||||
tilt_servo_pin = board.A2 # servo control line (orange) Trinket Pin #0
|
||||
rotate_servo_pin = board.A1 # servo control line (orange) Trinket Pin #2
|
||||
|
||||
# servo object setup for the M0 boards:
|
||||
tilt_pwm = pulseio.PWMOut(tilt_servo_pin, duty_cycle=2 ** 15, frequency=50)
|
||||
rotate_pwm = pulseio.PWMOut(rotate_servo_pin, duty_cycle=2 ** 15, frequency=50)
|
||||
tilt_servo = servo.Servo(tilt_pwm)
|
||||
rotate_servo = servo.Servo(rotate_pwm)
|
||||
|
||||
# servo timing and angle range
|
||||
tilt_min = 120 # lower limit to tilt rotation range
|
||||
max_rotate = 180 # rotation range limited to half circle
|
||||
|
||||
while True:
|
||||
|
||||
# servo tilt - on average move every 500ms
|
||||
if random.randint(0,100) > 80:
|
||||
tilt_servo.angle = random.randint(tilt_min, max_rotate)
|
||||
time.sleep(.25)
|
||||
|
||||
# servo rotate - on average move every 500ms
|
||||
if random.randint(0,100) > 90:
|
||||
rotate_servo.angle = random.randint(0, max_rotate)
|
||||
time.sleep(.25)
|
||||
4
3D_Printed_Bionic_Eye/README.md
Normal file
4
3D_Printed_Bionic_Eye/README.md
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# 3D_Printed_Bionic_Eye
|
||||
|
||||
Code to accompany this Adafruit tutorial:
|
||||
https://learn.adafruit.com/3d-printed-bionic-eye
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
// Fiery demon horns (rawr!) for Adafruit Trinket/Gemma.
|
||||
// Adafruit invests time and resources providing this open source code,
|
||||
// please support Adafruit and open-source hardware by purchasing
|
||||
// products from Adafruit!
|
||||
#include <Adafruit_NeoPixel.h>
|
||||
#include <avr/power.h>
|
||||
|
||||
#define N_HORNS 1
|
||||
#define N_LEDS 30 // Per horn
|
||||
#define PIN 0
|
||||
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(N_HORNS * N_LEDS, PIN);
|
||||
|
||||
// /\ -> Fire-like effect is the sum of multiple triangle
|
||||
// ____/ \____ waves in motion, with a 'warm' color map applied.
|
||||
#define N_WAVES 6 // Number of simultaneous waves (per horn)
|
||||
// Coordinate space for waves is 16x the pixel spacing,
|
||||
// allowing fixed-point math to be used instead of floats.
|
||||
struct {
|
||||
int16_t lower; // Lower bound of wave
|
||||
int16_t upper; // Upper bound of wave
|
||||
int16_t mid; // Midpoint (peak) ((lower+upper)/2)
|
||||
uint8_t vlower; // Velocity of lower bound
|
||||
uint8_t vupper; // Velocity of upper bound
|
||||
uint16_t intensity; // Brightness at peak
|
||||
} wave[N_HORNS][N_WAVES];
|
||||
long fade; // Decreases brightness as wave moves
|
||||
|
||||
// Gamma correction improves appearance of midrange colors
|
||||
uint8_t gamma[] PROGMEM = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
|
||||
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
|
||||
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
|
||||
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
|
||||
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
|
||||
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
|
||||
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
|
||||
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
|
||||
90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,
|
||||
115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
|
||||
144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
|
||||
177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
|
||||
215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 };
|
||||
|
||||
static void random_wave(uint8_t h,uint8_t w) { // Randomize one wave struct
|
||||
wave[h][w].upper = -1; // Always start just below head of strip
|
||||
wave[h][w].lower = -16 * (3 + random(4)); // Lower end starts ~3-7 pixels back
|
||||
wave[h][w].mid = (wave[h][w].lower + wave[h][w].upper) / 2;
|
||||
wave[h][w].vlower = 3 + random(4); // Lower end moves at ~1/8 to 1/4 pixel/frame
|
||||
wave[h][w].vupper = wave[h][w].vlower + random(4); // Upper end moves a bit faster, spreading wave
|
||||
wave[h][w].intensity = 300 + random(600);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
uint8_t h, w;
|
||||
|
||||
randomSeed(analogRead(1));
|
||||
pixels.begin();
|
||||
for(h=0; h<N_HORNS; h++) {
|
||||
for(w=0; w<N_WAVES; w++) random_wave(h, w);
|
||||
}
|
||||
fade = 234 + N_LEDS / 2;
|
||||
if(fade > 255) fade = 255;
|
||||
|
||||
// A ~100 Hz timer interrupt on Timer/Counter1 makes everything run
|
||||
// at regular intervals, regardless of current amount of motion.
|
||||
#if F_CPU == 16000000L
|
||||
clock_prescale_set(clock_div_1);
|
||||
TCCR1 = _BV(PWM1A) | _BV(CS13) | _BV(CS11) | _BV(CS10); // 1:1024 prescale
|
||||
OCR1C = F_CPU / 1024 / 100 - 1;
|
||||
#else
|
||||
TCCR1 = _BV(PWM1A) | _BV(CS13) | _BV(CS11); // 1:512 prescale
|
||||
OCR1C = F_CPU / 512 / 100 - 1;
|
||||
#endif
|
||||
GTCCR = 0; // No PWM out
|
||||
TIMSK |= _BV(TOIE1); // Enable overflow interrupt
|
||||
}
|
||||
|
||||
void loop() { } // Not used -- everything's in interrupt below
|
||||
|
||||
ISR(TIMER1_OVF_vect) {
|
||||
uint8_t h, w, i, r, g, b;
|
||||
int16_t x;
|
||||
uint16_t sum;
|
||||
|
||||
for(h=0; h<N_HORNS; h++) { // For each horn...
|
||||
for(x=7, i=0; i<N_LEDS; i++, x+=16) { // For each LED along horn...
|
||||
for(sum=w=0; w<N_WAVES; w++) { // For each wave of horn...
|
||||
if((x < wave[h][w].lower) || (x > wave[h][w].upper)) continue; // Out of range
|
||||
if(x <= wave[h][w].mid) { // Lower half of wave (ramping up to peak brightness)
|
||||
sum += wave[h][w].intensity * (x - wave[h][w].lower) / (wave[h][w].mid - wave[h][w].lower);
|
||||
} else { // Upper half of wave (ramping down from peak)
|
||||
sum += wave[h][w].intensity * (wave[h][w].upper - x) / (wave[h][w].upper - wave[h][w].mid);
|
||||
}
|
||||
}
|
||||
// Now the magnitude (sum) is remapped to color for the LEDs.
|
||||
// A blackbody palette is used - fades white-yellow-red-black.
|
||||
if(sum < 255) { // 0-254 = black to red-1
|
||||
r = pgm_read_byte(&gamma[sum]);
|
||||
g = b = 0;
|
||||
} else if(sum < 510) { // 255-509 = red to yellow-1
|
||||
r = 255;
|
||||
g = pgm_read_byte(&gamma[sum - 255]);
|
||||
b = 0;
|
||||
} else if(sum < 765) { // 510-764 = yellow to white-1
|
||||
r = g = 255;
|
||||
b = pgm_read_byte(&gamma[sum - 510]);
|
||||
} else { // 765+ = white
|
||||
r = g = b = 255;
|
||||
}
|
||||
pixels.setPixelColor(h * N_LEDS + i, r, g, b);
|
||||
}
|
||||
|
||||
for(w=0; w<N_WAVES; w++) { // Update wave positions for each horn
|
||||
wave[h][w].lower += wave[h][w].vlower; // Advance lower position
|
||||
if(wave[h][w].lower >= (N_LEDS * 16)) { // Off end of strip?
|
||||
random_wave(h, w); // Yes, 'reboot' wave
|
||||
} else { // No, adjust other values...
|
||||
wave[h][w].upper += wave[h][w].vupper;
|
||||
wave[h][w].mid = (wave[h][w].lower + wave[h][w].upper) / 2;
|
||||
wave[h][w].intensity = (wave[h][w].intensity * fade) / 256; // Dimmer
|
||||
}
|
||||
}
|
||||
}
|
||||
pixels.show();
|
||||
}
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
# Fiery demon horns (rawr!) for Adafruit Trinket/Gemma.
|
||||
# Adafruit invests time and resources providing this open source code,
|
||||
# please support Adafruit and open-source hardware by purchasing
|
||||
# products from Adafruit!
|
||||
|
||||
import board
|
||||
import neopixel
|
||||
from analogio import AnalogIn
|
||||
# pylint: disable=global-statement
|
||||
|
||||
try:
|
||||
import urandom as random
|
||||
except ImportError:
|
||||
import random
|
||||
|
||||
# /\ -> Fire-like effect is the sum_total of multiple triangle
|
||||
# ____/ \____ waves in motion, with a 'warm' color map applied.
|
||||
n_horns = 1 # number of horns
|
||||
led_pin = board.D0 # which pin your pixels are connected to
|
||||
n_leds = 30 # number of LEDs per horn
|
||||
frames_per_second = 50 # animation frames per second
|
||||
brightness = 0 # current wave height
|
||||
fade = 0 # Decreases brightness as wave moves
|
||||
pixels = neopixel.NeoPixel(led_pin, n_leds, brightness=1, auto_write=False)
|
||||
offset = 0
|
||||
|
||||
# Coordinate space for waves is 16x the pixel spacing,
|
||||
# allowing fixed-point math to be used instead of floats.
|
||||
lower = 0 # lower bound of wave
|
||||
upper = 1 # upper bound of wave
|
||||
mid = 2 # midpoint (peak) ((lower+upper)/2)
|
||||
vlower = 3 # velocity of lower bound
|
||||
vupper = 4 # velocity of upper bound
|
||||
intensity = 5 # brightness at peak
|
||||
|
||||
y = 0
|
||||
brightness = 0
|
||||
count = 0
|
||||
|
||||
# initialize 3D list
|
||||
wave = [[0] * 6] * 6, [[0] * 6] * 6, [[0] * 6] * 6, [[0] * 6] * 6, [[0] * 6] * 6, [[0] * 6] * 6
|
||||
|
||||
# Number of simultaneous waves (per horn)
|
||||
n_waves = len(wave)
|
||||
|
||||
# Gamma-correction table
|
||||
gamma = [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
|
||||
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
|
||||
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
|
||||
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
|
||||
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
|
||||
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
|
||||
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
|
||||
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
|
||||
90, 92, 93, 95, 96, 98, 99, 101, 102, 104, 105, 107, 109, 110,
|
||||
112, 114, 115, 117, 119, 120, 122, 124, 126, 127, 129, 131, 133,
|
||||
135, 137, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158,
|
||||
160, 162, 164, 167, 169, 171, 173, 175, 177, 180, 182, 184, 186,
|
||||
189, 191, 193, 196, 198, 200, 203, 205, 208, 210, 213, 215, 218,
|
||||
220, 223, 225, 228, 231, 233, 236, 239, 241, 244, 247, 249, 252,
|
||||
255
|
||||
]
|
||||
|
||||
|
||||
def random_wave(he, wi):
|
||||
wave[he][wi][upper] = -1 # Always start below head of strip
|
||||
wave[he][wi][lower] = -16 * (3 + random.randint(0,4)) # Lower end starts ~3-7 pixels back
|
||||
wave[he][wi][mid] = (wave[he][wi][lower]+ wave[he][wi][upper]) / 2
|
||||
wave[he][wi][vlower] = 3 + random.randint(0,4) # Lower end moves at ~1/8 to 1/pixels
|
||||
wave[he][wi][vupper] = wave[he][wi][vlower]+ random.randint(0,4) # Upper end moves a bit faster
|
||||
wave[he][wi][intensity] = 300 + random.randint(0,600)
|
||||
|
||||
def setup():
|
||||
global fade
|
||||
|
||||
# Random number generator is seeded from an unused 'floating'
|
||||
# analog input - this helps ensure the random color choices
|
||||
# aren't always the same order.
|
||||
pin = AnalogIn(board.A0)
|
||||
random.seed(pin.value)
|
||||
pin.deinit()
|
||||
|
||||
for he in range(n_horns):
|
||||
for wi in range(n_waves):
|
||||
random_wave(he, wi)
|
||||
|
||||
fade = 233 + n_leds / 2
|
||||
|
||||
if fade > 233:
|
||||
fade = 233
|
||||
|
||||
setup()
|
||||
|
||||
while True:
|
||||
|
||||
h = w = i = r = g = b = 0
|
||||
x = 0
|
||||
|
||||
for h in range(n_horns): # For each horn...
|
||||
x = 7
|
||||
sum_total = 0
|
||||
for i in range(n_leds): # For each LED along horn...
|
||||
x += 16
|
||||
for w in range(n_waves): # For each wave of horn...
|
||||
if (x < wave[h][w][lower]) or (x > wave[h][w][upper]):
|
||||
continue # Out of range
|
||||
if x <= wave[h][w][mid]: # Lower half of wave (ramping up peak brightness)
|
||||
sum_top = wave[h][w][intensity] * (x - wave[h][w][lower])
|
||||
sum_bottom = (wave[h][w][mid] - wave[h][w][lower])
|
||||
sum_total += sum_top / sum_bottom
|
||||
else: # Upper half of wave (ramping down from peak)
|
||||
sum_top = wave[h][w][intensity] * (wave[h][w][upper] - x)
|
||||
sum_bottom = (wave[h][w][upper] - wave[h][w][mid])
|
||||
sum_total += sum_top / sum_bottom
|
||||
|
||||
sum_total = int(sum_total) # convert from decimal to whole number
|
||||
|
||||
# Now the magnitude (sum_total) is remapped to color for the LEDs.
|
||||
# A blackbody palette is used - fades white-yellow-red-black.
|
||||
if sum_total < 255: # 0-254 = black to red-1
|
||||
r = gamma[sum_total]
|
||||
g = b = 0
|
||||
elif sum_total < 510: # 255-509 = red to yellow-1
|
||||
r = 255
|
||||
g = gamma[sum_total - 255]
|
||||
b = 0
|
||||
elif sum_total < 765: # 510-764 = yellow to white-1
|
||||
r = g = 255
|
||||
b = gamma[sum_total - 510]
|
||||
else: # 765+ = white
|
||||
r = g = b = 255
|
||||
pixels[i] = (r, g, b)
|
||||
|
||||
for w in range(n_waves): # Update wave positions for each horn
|
||||
wave[h][w][lower] += wave[h][w][vlower] # Advance lower position
|
||||
if wave[h][w][lower] >= (n_leds * 16): # Off end of strip?
|
||||
random_wave(h, w) # Yes, 'reboot' wave
|
||||
else: # No, adjust other values...
|
||||
wave[h][w][upper] += wave[h][w][vupper]
|
||||
wave[h][w][mid] = (wave[h][w][lower] + wave[h][w][upper]) / 2
|
||||
wave[h][w][intensity] = (wave[h][w][intensity] * fade) / 256 # Dimmer
|
||||
|
||||
pixels.show()
|
||||
|
|
@ -0,0 +1,157 @@
|
|||
// Adafruit Trinket+NeoPixel animation for Daft Punk-inspired helmet.
|
||||
// Contains some ATtiny85-specific stuff; won't run as-is on Uno, etc.
|
||||
|
||||
// Operates in HSV (hue, saturation, value) colorspace rather than RGB.
|
||||
// Animation is an interference pattern between two waves; one controls
|
||||
// saturation, the other controls value (brightness). The wavelength,
|
||||
// direction, speed and type (square vs triangle wave) for each is randomly
|
||||
// selected every few seconds. Hue is always linear, but other parameters
|
||||
// are similarly randomized.
|
||||
|
||||
#include <Adafruit_NeoPixel.h>
|
||||
#include <avr/power.h>
|
||||
|
||||
// GLOBAL STUFF --------------------------------------------------------------
|
||||
|
||||
#define N_LEDS 29
|
||||
#define PIN 0
|
||||
|
||||
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(N_LEDS, PIN);
|
||||
volatile uint16_t count = 1; // Countdown to next animation change
|
||||
extern const uint8_t gamma[]; // Big table at end of this code
|
||||
|
||||
volatile struct {
|
||||
uint8_t type, // 0 = square wave, 1 = triangle wave
|
||||
value[2]; // 0 = start-of-frame value, 1 = pixel-to-pixel value
|
||||
int8_t inc[2]; // 0 = frame-to-frame increment, 1 = pixel-to-pixel inc
|
||||
} wave[3]; // 0 = Hue, 1 = Saturation, 2 = Value (brightness)
|
||||
|
||||
#define WAVE_H 0 // Array indices for wave[]
|
||||
#define WAVE_S 1
|
||||
#define WAVE_V 2
|
||||
#define FRAME 0 // Array indices for value[] and inc[]
|
||||
#define PIXEL 1
|
||||
|
||||
|
||||
// INITIALIZATION ------------------------------------------------------------
|
||||
|
||||
void setup() {
|
||||
pixels.begin();
|
||||
randomSeed(analogRead(0)); // Seed random() from a floating pin (D2)
|
||||
|
||||
// Timer/Counter 1 is used to generate a steady ~50 Hz frame rate.
|
||||
#if F_CPU == 16000000L
|
||||
clock_prescale_set(clock_div_1);
|
||||
TCCR1 = _BV(PWM1A) | _BV(CS13) | _BV(CS12); // 1:2048 prescale
|
||||
OCR1C = F_CPU / 2048 / 50 - 1;
|
||||
#else
|
||||
TCCR1 = _BV(PWM1A) | _BV(CS13) | _BV(CS11) | _BV(CS10); // 1:1024
|
||||
OCR1C = F_CPU / 1024 / 50 - 1;
|
||||
#endif
|
||||
GTCCR = 0; // No PWM out
|
||||
TIMSK |= _BV(TOIE1); // Enable overflow interrupt
|
||||
}
|
||||
|
||||
void loop() { } // Not used here -- everything's in interrupt below
|
||||
|
||||
|
||||
// 50 HZ LOOP ----------------------------------------------------------------
|
||||
|
||||
ISR(TIMER1_OVF_vect) {
|
||||
uint8_t w, i, n, s, v, r, g, b;
|
||||
uint16_t v1, s1;
|
||||
|
||||
if(!(--count)) { // Time for new animation?
|
||||
count = 250 + random(250); // New effect will run for 5-10 sec.
|
||||
for(w=0; w<3; w++) { // Three waves (H,S,V)...
|
||||
wave[w].type = random(2); // Assign random type (square/triangle)
|
||||
for(i=0; i<2; i++) { // For frame and pixel increments...
|
||||
while(!(wave[w].inc[i] = random(15) - 7)); // Set non-zero random
|
||||
// wave value is never initialized; it's allowed to carry over
|
||||
}
|
||||
wave[w].value[PIXEL] = wave[w].value[FRAME];
|
||||
}
|
||||
wave[WAVE_S].inc[PIXEL] *= 16; // Make saturation & value
|
||||
wave[WAVE_V].inc[PIXEL] *= 16; // blinkier along strip
|
||||
} else { // Continue current animation; update waves
|
||||
for(w=0; w<3; w++) {
|
||||
wave[w].value[FRAME] += wave[w].inc[FRAME]; // OK if this wraps!
|
||||
wave[w].value[PIXEL] = wave[w].value[FRAME];
|
||||
}
|
||||
}
|
||||
|
||||
// Render current animation frame. COGNITIVE HAZARD: fixed point math.
|
||||
|
||||
for(i=0; i<N_LEDS; i++) { // For each LED along strip...
|
||||
|
||||
// Coarse (8-bit) HSV-to-RGB conversion, hue first:
|
||||
n = (wave[WAVE_H].value[PIXEL] % 43) * 6; // Angle within sextant; 0-255
|
||||
switch(wave[WAVE_H].value[PIXEL] / 43) { // Sextant number; 0-5
|
||||
case 0 : r = 255 ; g = n ; b = 0 ; break; // R to Y
|
||||
case 1 : r = 254 - n; g = 255 ; b = 0 ; break; // Y to G
|
||||
case 2 : r = 0 ; g = 255 ; b = n ; break; // G to C
|
||||
case 3 : r = 0 ; g = 254 - n; b = 255 ; break; // C to B
|
||||
case 4 : r = n ; g = 0 ; b = 255 ; break; // B to M
|
||||
default: r = 255 ; g = 0 ; b = 254 - n; break; // M to R
|
||||
}
|
||||
|
||||
// Saturation = 1-256 to allow >>8 instead of /255
|
||||
s = wave[WAVE_S].value[PIXEL];
|
||||
if(wave[WAVE_S].type) { // Triangle wave?
|
||||
if(s & 0x80) { // Downslope
|
||||
s = (s & 0x7F) << 1;
|
||||
s1 = 256 - s;
|
||||
} else { // Upslope
|
||||
s <<= 1;
|
||||
s1 = 1 + s;
|
||||
s = 255 - s;
|
||||
}
|
||||
} else { // Square wave
|
||||
if(s & 0x80) { // 100% saturation
|
||||
s1 = 256;
|
||||
s = 0;
|
||||
} else { // 0% saturation (white)
|
||||
s1 = 1;
|
||||
s = 255;
|
||||
}
|
||||
}
|
||||
|
||||
// Value (brightness) = 1-256 for similar reasons
|
||||
v = wave[WAVE_V].value[PIXEL];
|
||||
v1 = (wave[WAVE_V].type) ? // Triangle wave?
|
||||
((v & 0x80) ? 64 - ((v & 0x7F) << 1) : // Downslope
|
||||
1 + ( v << 1) ) : // Upslope
|
||||
((v & 0x80) ? 256 : 1); // Square wave; on/off
|
||||
|
||||
pixels.setPixelColor(i,
|
||||
pgm_read_byte(&gamma[((((r * s1) >> 8) + s) * v1) >> 8]),
|
||||
pgm_read_byte(&gamma[((((g * s1) >> 8) + s) * v1) >> 8]),
|
||||
pgm_read_byte(&gamma[((((b * s1) >> 8) + s) * v1) >> 8]));
|
||||
|
||||
// Update wave values along length of strip (values may wrap, is OK!)
|
||||
for(w=0; w<3; w++) wave[w].value[PIXEL] += wave[w].inc[PIXEL];
|
||||
}
|
||||
|
||||
pixels.show();
|
||||
}
|
||||
|
||||
// Gamma correction improves appearance of midrange colors.
|
||||
// This table is positioned down here because it's a big annoying
|
||||
// distraction. The 'extern' near the top lets us reference it earlier.
|
||||
const uint8_t gamma[] PROGMEM = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
|
||||
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
|
||||
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
|
||||
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
|
||||
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
|
||||
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
|
||||
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
|
||||
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
|
||||
90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,
|
||||
115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
|
||||
144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
|
||||
177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
|
||||
215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 };
|
||||
|
|
@ -0,0 +1,189 @@
|
|||
# Adafruit Trinket+NeoPixel animation for Daft Punk-inspired helmet.
|
||||
# Contains some ATtiny85-specific stuff; won't run as-is on Uno, etc.
|
||||
|
||||
# Operates in HSV (hue, saturation, value) colorspace rather than RGB.
|
||||
# Animation is an interference pattern between two waves; one controls
|
||||
# saturation, the other controls value (brightness). The wavelength,
|
||||
# direction, speed and type (square vs triangle wave) for each is randomly
|
||||
# selected every few seconds. Hue is always linear, but other parameters
|
||||
# are similarly randomized.
|
||||
|
||||
import random
|
||||
import board
|
||||
import neopixel
|
||||
from analogio import AnalogIn
|
||||
|
||||
n_leds = 29 # number of LEDs per horn
|
||||
led_pin = board.D0 # which pin your pixels are connected to
|
||||
|
||||
# initialize neopixel strip
|
||||
pixels = neopixel.NeoPixel(led_pin, n_leds, brightness=1, auto_write=False)
|
||||
count = 1 # countdown to next animation change
|
||||
|
||||
# Gamma-correction table
|
||||
gamma = [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
|
||||
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
|
||||
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
|
||||
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
|
||||
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
|
||||
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
|
||||
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
|
||||
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
|
||||
90, 92, 93, 95, 96, 98, 99, 101, 102, 104, 105, 107, 109, 110,
|
||||
112, 114, 115, 117, 119, 120, 122, 124, 126, 127, 129, 131, 133,
|
||||
135, 137, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158,
|
||||
160, 162, 164, 167, 169, 171, 173, 175, 177, 180, 182, 184, 186,
|
||||
189, 191, 193, 196, 198, 200, 203, 205, 208, 210, 213, 215, 218,
|
||||
220, 223, 225, 228, 231, 233, 236, 239, 241, 244, 247, 249, 252,
|
||||
255
|
||||
]
|
||||
|
||||
# initialize 3D list
|
||||
wave = [0] * 5, [0] * 5, [0] * 5
|
||||
|
||||
wave_type = 0 # 0 = square wave, 1 = triangle wave
|
||||
value_frame = 1 # start-of-frame value
|
||||
value_pixel = 2 # pixel-to-pixel value
|
||||
inc_frame = 3 # frame-to-frame increment
|
||||
inc_pixel = 4 # pixel-to-pixel inc
|
||||
|
||||
wave_h = 0 # hue
|
||||
wave_s = 1 # saturation
|
||||
wave_v = 2 # brightness
|
||||
|
||||
# Random number generator is seeded from an unused 'floating'
|
||||
# analog input - this helps ensure the random color choices
|
||||
# aren't always the same order.
|
||||
pin = AnalogIn(board.A0)
|
||||
random.seed(pin.value)
|
||||
pin.deinit()
|
||||
|
||||
# generate a non-zero random number for frame and pixel increments
|
||||
def nz_random():
|
||||
random_number = 0
|
||||
|
||||
while random_number <= 0:
|
||||
random_number = random.randint(0,15) - 7
|
||||
|
||||
return random_number
|
||||
|
||||
while True:
|
||||
|
||||
w = i = n = s = v = r = g = b = v1 = s1 = 0
|
||||
|
||||
if count <= 0: # time for new animation
|
||||
count = 250 + random.randint(0,250) # effect run for 5-10 sec.
|
||||
|
||||
for w in range(3): # three waves (H,S,V)
|
||||
wave[w][wave_type] = random.randint(0,2)# square vs triangle
|
||||
wave[w][inc_frame] = nz_random() # frame increment
|
||||
wave[w][inc_pixel] = nz_random() # pixel increment
|
||||
wave[w][value_pixel] = wave[w][value_frame]
|
||||
|
||||
wave[wave_s][inc_pixel] *= 16 # make saturation & value
|
||||
wave[wave_v][inc_pixel] *= 16 # blinkier along strip
|
||||
|
||||
else: # continue animation
|
||||
count -= 1
|
||||
for w in range(3):
|
||||
wave[w][value_frame] += wave[w][inc_frame]
|
||||
wave[w][value_pixel] = wave[w][value_frame]
|
||||
|
||||
# Render current animation frame. COGNITIVE HAZARD: fixed point math.
|
||||
for i in range(n_leds): # for each LED along strip...
|
||||
# Coarse (8-bit) HSV-to-RGB conversion, hue first:
|
||||
n = (wave[wave_h][value_pixel] % 43) * 6 # angle within sextant
|
||||
|
||||
sextant = wave[wave_h][value_pixel] / 43 # sextant number 0-5
|
||||
|
||||
# R to Y
|
||||
if sextant == 0:
|
||||
r = 255
|
||||
g = n
|
||||
b = 0
|
||||
# Y to G
|
||||
elif sextant == 1:
|
||||
r = 254 - n
|
||||
g = 255
|
||||
b = 0
|
||||
# G to C
|
||||
elif sextant == 2:
|
||||
r = 0
|
||||
g = 255
|
||||
b = n
|
||||
# C to B
|
||||
elif sextant == 3:
|
||||
r = 0
|
||||
g = 254 - n
|
||||
b = 255
|
||||
# B to M
|
||||
elif sextant == 4:
|
||||
r = n
|
||||
g = 0
|
||||
b = 255
|
||||
# M to R
|
||||
else:
|
||||
r = 255
|
||||
g = 0
|
||||
b = 254 - n
|
||||
|
||||
# Saturation = 1-256 to allow >>8 instead of /255
|
||||
s = wave[wave_s][value_pixel]
|
||||
|
||||
if wave[wave_s][wave_type]: # triangle wave?
|
||||
if s & 0x80: # downslope
|
||||
s = (s & 0x7F) << 1
|
||||
s1 = 256 - s
|
||||
else: # upslope
|
||||
s = s<<1
|
||||
s1 = 1 + s
|
||||
s = 255 - s
|
||||
else:
|
||||
if s & 0x80: # square wave
|
||||
s1 = 256 # 100% saturation
|
||||
s = 0
|
||||
else: # 0% saturation
|
||||
s1 = 1
|
||||
s = 255
|
||||
|
||||
# Value (brightness) = 1-256 for similar reasons
|
||||
v = wave[wave_v][value_pixel]
|
||||
|
||||
# value (brightness) = 1-256 for similar reasons
|
||||
if wave[wave_v][wave_type]: # triangle wave?
|
||||
if v & 0x80: # downslope
|
||||
v1 = 64 - ((v & 0x7F) << 1)
|
||||
else: # upslope
|
||||
v1 = 1 + (v << 1)
|
||||
else:
|
||||
if v & 0x80: # square wave; on/off
|
||||
v1 = 256
|
||||
else:
|
||||
v1 = 1
|
||||
|
||||
# gamma rgb values
|
||||
gr = ((((r * s1) >> 8) + s) * v1) >> 8
|
||||
gg = ((((g * s1) >> 8) + s) * v1) >> 8
|
||||
gb = ((((b * s1) >> 8) + s) * v1) >> 8
|
||||
|
||||
# gamma rgb indices range check
|
||||
if -256 < gr < 256:
|
||||
r = gamma[gr]
|
||||
|
||||
if -256 < gg < 256:
|
||||
g = gamma[gg]
|
||||
|
||||
if -256 < gb < 256:
|
||||
b = gamma[gb]
|
||||
|
||||
pixels[i] = (r, g, b)
|
||||
|
||||
# update wave values along length of strip (values may wrap, is OK!)
|
||||
for w in range(3):
|
||||
wave[w][value_pixel] += wave[w][inc_pixel]
|
||||
|
||||
pixels.show()
|
||||
4
3D_Printed_Daft_Punk_Helmet/README.md
Normal file
4
3D_Printed_Daft_Punk_Helmet/README.md
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# 3D Printed Daft Punk Helmet
|
||||
|
||||
Code to accompany this tutorial:
|
||||
https://learn.adafruit.com/3d-printed-daft-punk-helmet
|
||||
|
|
@ -1,49 +1,50 @@
|
|||
# 3D_Printed_Guardian_Sword
|
||||
# https://learn.adafruit.com/breath-of-the-wild-guardian-sword-led-3d-printed
|
||||
|
||||
import board
|
||||
import neopixel
|
||||
import time
|
||||
|
||||
pin = board.D4 # DIGITAL IO pin for NeoPixel OUTPUT from GEMMA
|
||||
pixel_count = 93 # number of neopixels
|
||||
delayval = .01 # 10 ms delay
|
||||
import board
|
||||
import neopixel
|
||||
|
||||
APIXELS = 14 # number of first orange pixels
|
||||
BPIXELS = 84 # number of blue pixels
|
||||
CPIXELS = 93 # second orange pixels
|
||||
pin = board.D4 # DIGITAL IO pin for NeoPixel OUTPUT from GEMMA
|
||||
pixel_count = 93 # number of neopixels
|
||||
delayval = .01 # 10 ms delay
|
||||
|
||||
APIXELS = 14 # number of first orange pixels
|
||||
BPIXELS = 84 # number of blue pixels
|
||||
CPIXELS = 93 # second orange pixels
|
||||
|
||||
# initialize neopixels
|
||||
pixels = neopixel.NeoPixel(pin, pixel_count, brightness=1, auto_write=False)
|
||||
|
||||
while True:
|
||||
|
||||
# For the first 14 pixels, make them orange,
|
||||
# For the first 14 pixels, make them orange,
|
||||
# starting from pixel number 0.
|
||||
for i in range( 0, APIXELS ):
|
||||
# Set Pixels to Orange Color
|
||||
pixels[i] = ( 255, 50, 0 )
|
||||
for i in range(0, APIXELS):
|
||||
# Set Pixels to Orange Color
|
||||
pixels[i] = (255, 50, 0)
|
||||
# This sends the updated pixel color to the hardware.
|
||||
pixels.write()
|
||||
# Delay for a period of time (in milliseconds).
|
||||
time.sleep(delayval)
|
||||
pixels.write()
|
||||
# Delay for a period of time (in milliseconds).
|
||||
time.sleep(delayval)
|
||||
|
||||
# Fill up 84 pixels with blue,
|
||||
# Fill up 84 pixels with blue,
|
||||
# starting with pixel number 14.
|
||||
for i in range ( 14, BPIXELS ):
|
||||
# Set Pixels to Orange Color
|
||||
pixels[i] = ( 0, 250, 200 )
|
||||
for i in range(APIXELS, BPIXELS):
|
||||
# Set Pixels to Orange Color
|
||||
pixels[i] = (0, 250, 200)
|
||||
# This sends the updated pixel color to the hardware.
|
||||
pixels.write()
|
||||
# Delay for a period of time (in milliseconds).
|
||||
time.sleep(delayval)
|
||||
pixels.write()
|
||||
# Delay for a period of time (in milliseconds).
|
||||
time.sleep(delayval)
|
||||
|
||||
# Fill up 9 pixels with orange,
|
||||
# Fill up 9 pixels with orange,
|
||||
# starting from pixel number 84.
|
||||
for i in range ( 84, CPIXELS ):
|
||||
# Set Pixels to Orange Color
|
||||
pixels[i] = ( 250, 50, 0 )
|
||||
for i in range(BPIXELS, CPIXELS):
|
||||
# Set Pixels to Orange Color
|
||||
pixels[i] = (250, 50, 0)
|
||||
# This sends the updated pixel color to the hardware.
|
||||
pixels.write()
|
||||
# Delay for a period of time (in milliseconds).
|
||||
time.sleep(delayval)
|
||||
pixels.write()
|
||||
# Delay for a period of time (in milliseconds).
|
||||
time.sleep(delayval)
|
||||
|
|
|
|||
0
3D_Printed_LED-Animation_BMO/.trinket.test
Normal file
0
3D_Printed_LED-Animation_BMO/.trinket.test
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
// Trinket/Gemma + LED matrix backpack jewelry. Plays animated
|
||||
// sequence on LED matrix. Press reset button to display again,
|
||||
// or add optional momentary button between pin #1 and +V.
|
||||
// THERE IS NO ANIMATION DATA IN THIS SOURCE FILE, you should
|
||||
// rarely need to change anything here. EDIT anim.h INSTEAD.
|
||||
|
||||
#define BRIGHTNESS 12 // 0=min, 15=max
|
||||
#define I2C_ADDR 0x70 // Edit if backpack A0/A1 jumpers set
|
||||
|
||||
#include <TinyWireM.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/sleep.h>
|
||||
#include "bmo.h" // Animation data is located here
|
||||
|
||||
static const uint8_t PROGMEM reorder[] = { // Column-reordering table
|
||||
0x00,0x40,0x20,0x60,0x10,0x50,0x30,0x70,0x08,0x48,0x28,0x68,0x18,0x58,0x38,0x78,
|
||||
0x04,0x44,0x24,0x64,0x14,0x54,0x34,0x74,0x0c,0x4c,0x2c,0x6c,0x1c,0x5c,0x3c,0x7c,
|
||||
0x02,0x42,0x22,0x62,0x12,0x52,0x32,0x72,0x0a,0x4a,0x2a,0x6a,0x1a,0x5a,0x3a,0x7a,
|
||||
0x06,0x46,0x26,0x66,0x16,0x56,0x36,0x76,0x0e,0x4e,0x2e,0x6e,0x1e,0x5e,0x3e,0x7e,
|
||||
0x01,0x41,0x21,0x61,0x11,0x51,0x31,0x71,0x09,0x49,0x29,0x69,0x19,0x59,0x39,0x79,
|
||||
0x05,0x45,0x25,0x65,0x15,0x55,0x35,0x75,0x0d,0x4d,0x2d,0x6d,0x1d,0x5d,0x3d,0x7d,
|
||||
0x03,0x43,0x23,0x63,0x13,0x53,0x33,0x73,0x0b,0x4b,0x2b,0x6b,0x1b,0x5b,0x3b,0x7b,
|
||||
0x07,0x47,0x27,0x67,0x17,0x57,0x37,0x77,0x0f,0x4f,0x2f,0x6f,0x1f,0x5f,0x3f,0x7f,
|
||||
0x80,0xc0,0xa0,0xe0,0x90,0xd0,0xb0,0xf0,0x88,0xc8,0xa8,0xe8,0x98,0xd8,0xb8,0xf8,
|
||||
0x84,0xc4,0xa4,0xe4,0x94,0xd4,0xb4,0xf4,0x8c,0xcc,0xac,0xec,0x9c,0xdc,0xbc,0xfc,
|
||||
0x82,0xc2,0xa2,0xe2,0x92,0xd2,0xb2,0xf2,0x8a,0xca,0xaa,0xea,0x9a,0xda,0xba,0xfa,
|
||||
0x86,0xc6,0xa6,0xe6,0x96,0xd6,0xb6,0xf6,0x8e,0xce,0xae,0xee,0x9e,0xde,0xbe,0xfe,
|
||||
0x81,0xc1,0xa1,0xe1,0x91,0xd1,0xb1,0xf1,0x89,0xc9,0xa9,0xe9,0x99,0xd9,0xb9,0xf9,
|
||||
0x85,0xc5,0xa5,0xe5,0x95,0xd5,0xb5,0xf5,0x8d,0xcd,0xad,0xed,0x9d,0xdd,0xbd,0xfd,
|
||||
0x83,0xc3,0xa3,0xe3,0x93,0xd3,0xb3,0xf3,0x8b,0xcb,0xab,0xeb,0x9b,0xdb,0xbb,0xfb,
|
||||
0x87,0xc7,0xa7,0xe7,0x97,0xd7,0xb7,0xf7,0x8f,0xcf,0xaf,0xef,0x9f,0xdf,0xbf,0xff };
|
||||
|
||||
void ledCmd(uint8_t x) { // Issue command to LED backback driver
|
||||
TinyWireM.beginTransmission(I2C_ADDR);
|
||||
TinyWireM.write(x);
|
||||
TinyWireM.endTransmission();
|
||||
}
|
||||
|
||||
void clear(void) { // Clear display buffer
|
||||
TinyWireM.beginTransmission(I2C_ADDR);
|
||||
for(uint8_t i=0; i<17; i++) TinyWireM.write(0);
|
||||
TinyWireM.endTransmission();
|
||||
}
|
||||
|
||||
void setup() {
|
||||
power_timer1_disable(); // Disable unused peripherals
|
||||
power_adc_disable(); // to save power
|
||||
PCMSK |= _BV(PCINT1); // Set change mask for pin 1
|
||||
TinyWireM.begin(); // I2C init
|
||||
clear(); // Blank display
|
||||
ledCmd(0x21); // Turn on oscillator
|
||||
ledCmd(0xE0 | BRIGHTNESS); // Set brightness
|
||||
ledCmd(0x81); // Display on, no blink
|
||||
}
|
||||
|
||||
uint8_t rep = REPS;
|
||||
|
||||
void loop() {
|
||||
|
||||
for(int i=0; i<sizeof(anim); i) { // For each frame...
|
||||
TinyWireM.beginTransmission(I2C_ADDR);
|
||||
TinyWireM.write(0); // Start address
|
||||
for(uint8_t j=0; j<8; j++) { // 8 rows...
|
||||
TinyWireM.write(pgm_read_byte(&reorder[pgm_read_byte(&anim[i++])]));
|
||||
TinyWireM.write(0);
|
||||
}
|
||||
TinyWireM.endTransmission();
|
||||
delay(pgm_read_byte(&anim[i++]) * 10);
|
||||
}
|
||||
|
||||
if(!--rep) { // If last cycle...
|
||||
ledCmd(0x20); // LED matrix in standby mode
|
||||
GIMSK = _BV(PCIE); // Enable pin change interrupt
|
||||
power_all_disable(); // All peripherals off
|
||||
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
|
||||
sleep_enable();
|
||||
sei(); // Keep interrupts disabled
|
||||
sleep_mode(); // Power down CPU (pin 1 will wake)
|
||||
// Execution resumes here on wake.
|
||||
GIMSK = 0; // Disable pin change interrupt
|
||||
rep = REPS; // Reset animation counter
|
||||
power_timer0_enable(); // Re-enable timer
|
||||
power_usi_enable(); // Re-enable USI
|
||||
TinyWireM.begin(); // Re-init I2C
|
||||
clear(); // Blank display
|
||||
ledCmd(0x21); // Re-enable matrix
|
||||
}
|
||||
}
|
||||
|
||||
ISR(PCINT0_vect) {} // Button tap
|
||||
117
3D_Printed_LED-Animation_BMO/3D_Printed_LED-Animation_BMO.py
Normal file
117
3D_Printed_LED-Animation_BMO/3D_Printed_LED-Animation_BMO.py
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
# Trinket/Gemma + LED matrix backpack jewelry. Plays animated
|
||||
# sequence on LED matrix. Press reset button to display again.
|
||||
|
||||
import time
|
||||
import adafruit_ht16k33.matrix
|
||||
import board
|
||||
import busio as io
|
||||
import touchio
|
||||
|
||||
touch = touchio.TouchIn(board.D1)
|
||||
|
||||
i2c = io.I2C(board.SCL, board.SDA)
|
||||
matrix = adafruit_ht16k33.matrix.Matrix8x8(i2c)
|
||||
|
||||
# pixels initializers
|
||||
x_pix = y_pix = 8
|
||||
x = y = 0
|
||||
matrix.fill(0)
|
||||
matrix.show()
|
||||
|
||||
# seconds to pause between frames
|
||||
frame_delay = [.25, .25, .25, .25, .25, .25, .25, .25, .25, .25]
|
||||
|
||||
# counter for animation frames
|
||||
frame_count = 0
|
||||
|
||||
# repeat entire animation multiple times
|
||||
reps = 255
|
||||
rep_count = reps
|
||||
|
||||
# animation bitmaps
|
||||
animation = [
|
||||
# frame 1
|
||||
[[1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 1, 1, 0, 0, 1],
|
||||
[1, 0, 0, 1, 1, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1],
|
||||
[1, 0, 0, 0, 0, 0, 0, 1], [1, 1, 0, 0, 0, 0, 1, 1],
|
||||
[1, 1, 1, 0, 0, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1]],
|
||||
# frame 2
|
||||
[[1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 1, 1, 0, 0, 1],
|
||||
[1, 0, 0, 1, 1, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1],
|
||||
[1, 0, 1, 1, 1, 1, 0, 1], [1, 0, 1, 1, 1, 1, 0, 1],
|
||||
[1, 1, 0, 0, 0, 0, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1]],
|
||||
# frame 3
|
||||
[[1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 1, 1, 0, 0, 1],
|
||||
[1, 0, 0, 1, 1, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1],
|
||||
[1, 0, 0, 0, 0, 0, 0, 1], [1, 1, 0, 0, 0, 0, 1, 1],
|
||||
[1, 1, 1, 0, 0, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1]],
|
||||
# frame 4
|
||||
[[1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 1, 1, 0, 0, 1],
|
||||
[1, 0, 0, 1, 1, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1],
|
||||
[1, 0, 1, 1, 1, 1, 0, 1], [1, 0, 1, 1, 1, 1, 0, 1],
|
||||
[1, 1, 0, 0, 0, 0, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1]],
|
||||
# frame 5
|
||||
[[1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 1, 1, 0, 0, 1],
|
||||
[1, 0, 0, 1, 1, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1],
|
||||
[1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1],
|
||||
[1, 0, 0, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1]],
|
||||
# frame 6
|
||||
[[1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 1, 1, 0, 0, 1],
|
||||
[1, 0, 0, 1, 1, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1],
|
||||
[1, 1, 1, 0, 0, 1, 1, 1], [1, 1, 0, 1, 1, 0, 1, 1],
|
||||
[1, 1, 1, 0, 0, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1]],
|
||||
# frame 7
|
||||
[[1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 1, 1, 1, 1, 0, 1],
|
||||
[0, 0, 0, 1, 1, 0, 0, 0], [1, 0, 1, 1, 1, 1, 0, 1],
|
||||
[1, 1, 1, 0, 0, 1, 1, 1], [1, 1, 0, 1, 1, 0, 1, 1],
|
||||
[1, 1, 1, 0, 0, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1]],
|
||||
# frame 8
|
||||
[[1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1],
|
||||
[0, 0, 0, 1, 1, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1],
|
||||
[1, 1, 1, 0, 0, 1, 1, 1], [1, 1, 0, 1, 1, 0, 1, 1],
|
||||
[1, 1, 1, 0, 0, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1]],
|
||||
# frame 9
|
||||
[[1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 1, 1, 1, 1, 0, 1],
|
||||
[0, 0, 0, 1, 1, 0, 0, 0], [1, 0, 1, 1, 1, 1, 0, 1],
|
||||
[1, 1, 1, 0, 0, 1, 1, 1], [1, 1, 0, 1, 1, 0, 1, 1],
|
||||
[1, 1, 1, 0, 0, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1]],
|
||||
]
|
||||
|
||||
#
|
||||
# run until we are out of animation frames
|
||||
# use Gemma's built-in reset button or switch to restart
|
||||
#
|
||||
# populate matrix
|
||||
while True:
|
||||
|
||||
if frame_count < len(animation) and rep_count >= 0:
|
||||
for x in range(x_pix):
|
||||
for y in range(y_pix):
|
||||
matrix.pixel(x, y, animation[frame_count][x][y])
|
||||
|
||||
# next animation frame
|
||||
frame_count += 1
|
||||
|
||||
# show animation
|
||||
matrix.show()
|
||||
|
||||
# pause for effect
|
||||
time.sleep(frame_delay[frame_count])
|
||||
|
||||
else:
|
||||
|
||||
matrix.fill(0)
|
||||
matrix.show()
|
||||
time.sleep(.1)
|
||||
|
||||
# track repitions
|
||||
rep_count -= 1
|
||||
|
||||
# play it again
|
||||
frame_count = 0
|
||||
|
||||
# A0/D1 pin has been touched
|
||||
# reset animation
|
||||
if touch.value:
|
||||
frame_count = 0
|
||||
rep_count = reps
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 76 KiB |
4
3D_Printed_LED-Animation_BMO/README.md
Normal file
4
3D_Printed_LED-Animation_BMO/README.md
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# 3D Printed LED-Animation BMO
|
||||
|
||||
Code to accompany this Adafruit tutorial:
|
||||
https://learn.adafruit.com/3d-printed-led-animation-bmo/overview
|
||||
95
3D_Printed_LED-Animation_BMO/bmo.h
Normal file
95
3D_Printed_LED-Animation_BMO/bmo.h
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
// Animation data for Trinket/Gemma + LED matrix backpack jewelry.
|
||||
#define REPS 255 // Number of times to repeat the animation loop (1-255)
|
||||
const uint8_t PROGMEM anim[] = {
|
||||
|
||||
B11111111, // 1 frame
|
||||
B10011001,
|
||||
B10011001,
|
||||
B11111111,
|
||||
B10000001,
|
||||
B11000011,
|
||||
B11100111,
|
||||
B11111111,
|
||||
25, // 0.25 second delay
|
||||
|
||||
B11111111, // 2 frame
|
||||
B10011001,
|
||||
B10011001,
|
||||
B11111111,
|
||||
B10111101,
|
||||
B10111101,
|
||||
B11000011,
|
||||
B11111111,
|
||||
25, // 0.25 second delay
|
||||
|
||||
B11111111, // 3 frame
|
||||
B10011001,
|
||||
B10011001,
|
||||
B11111111,
|
||||
B10000001,
|
||||
B11000011,
|
||||
B11100111,
|
||||
B11111111,
|
||||
25, // 0.25 second delay
|
||||
|
||||
B11111111, // 4 frame
|
||||
B10011001,
|
||||
B10011001,
|
||||
B11111111,
|
||||
B10111101,
|
||||
B10111101,
|
||||
B11000011,
|
||||
B11111111,
|
||||
25, // 0.25 second delay
|
||||
|
||||
B11111111, // 5 frame
|
||||
B10011001,
|
||||
B10011001,
|
||||
B11111111,
|
||||
B11111111,
|
||||
B11111111,
|
||||
B10000001,
|
||||
B11111111,
|
||||
25, // 0.25 second delay
|
||||
|
||||
B11111111, // 6 frame
|
||||
B10011001,
|
||||
B10011001,
|
||||
B11111111,
|
||||
B11100111,
|
||||
B11011011,
|
||||
B11100111,
|
||||
B11111111,
|
||||
25, // 0.25 second delay
|
||||
|
||||
B11111111, // 7 frame
|
||||
B10111101,
|
||||
B00011000,
|
||||
B10111101,
|
||||
B11100111,
|
||||
B11011011,
|
||||
B11100111,
|
||||
B11111111,
|
||||
25, // 0.25 second delay
|
||||
|
||||
B11111111, // 8 frame
|
||||
B11111111,
|
||||
B00011000,
|
||||
B11111111,
|
||||
B11100111,
|
||||
B11011011,
|
||||
B11100111,
|
||||
B11111111,
|
||||
25, // 0.25 second delay
|
||||
|
||||
B11111111, // 9 frame
|
||||
B10111101,
|
||||
B00011000,
|
||||
B10111101,
|
||||
B11100111,
|
||||
B11011011,
|
||||
B11100111,
|
||||
B11111111,
|
||||
25, // 0.25 second delay
|
||||
};
|
||||
|
||||
0
3D_Printed_LED_Fire_Horns/.gemma.test
Normal file
0
3D_Printed_LED_Fire_Horns/.gemma.test
Normal file
0
3D_Printed_LED_Fire_Horns/.trinket.test
Normal file
0
3D_Printed_LED_Fire_Horns/.trinket.test
Normal file
128
3D_Printed_LED_Fire_Horns/3D_Printed_LED_Fire_Horns.ino
Normal file
128
3D_Printed_LED_Fire_Horns/3D_Printed_LED_Fire_Horns.ino
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
// Fiery demon horns (rawr!) for Adafruit Trinket/Gemma.
|
||||
// Adafruit invests time and resources providing this open source code,
|
||||
// please support Adafruit and open-source hardware by purchasing
|
||||
// products from Adafruit!
|
||||
#include <Adafruit_NeoPixel.h>
|
||||
#include <avr/power.h>
|
||||
|
||||
#define N_HORNS 1
|
||||
#define N_LEDS 30 // Per horn
|
||||
#define PIN 0
|
||||
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(N_HORNS * N_LEDS, PIN);
|
||||
|
||||
// /\ -> Fire-like effect is the sum of multiple triangle
|
||||
// ____/ \____ waves in motion, with a 'warm' color map applied.
|
||||
#define N_WAVES 6 // Number of simultaneous waves (per horn)
|
||||
// Coordinate space for waves is 16x the pixel spacing,
|
||||
// allowing fixed-point math to be used instead of floats.
|
||||
struct {
|
||||
int16_t lower; // Lower bound of wave
|
||||
int16_t upper; // Upper bound of wave
|
||||
int16_t mid; // Midpoint (peak) ((lower+upper)/2)
|
||||
uint8_t vlower; // Velocity of lower bound
|
||||
uint8_t vupper; // Velocity of upper bound
|
||||
uint16_t intensity; // Brightness at peak
|
||||
} wave[N_HORNS][N_WAVES];
|
||||
long fade; // Decreases brightness as wave moves
|
||||
|
||||
// Gamma correction improves appearance of midrange colors
|
||||
const uint8_t gamma[] PROGMEM = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
|
||||
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
|
||||
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
|
||||
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
|
||||
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
|
||||
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
|
||||
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
|
||||
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
|
||||
90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,
|
||||
115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
|
||||
144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
|
||||
177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
|
||||
215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 };
|
||||
|
||||
static void random_wave(uint8_t h,uint8_t w) { // Randomize one wave struct
|
||||
wave[h][w].upper = -1; // Always start just below head of strip
|
||||
wave[h][w].lower = -16 * (3 + random(4)); // Lower end starts ~3-7 pixels back
|
||||
wave[h][w].mid = (wave[h][w].lower + wave[h][w].upper) / 2;
|
||||
wave[h][w].vlower = 3 + random(4); // Lower end moves at ~1/8 to 1/4 pixel/frame
|
||||
wave[h][w].vupper = wave[h][w].vlower + random(4); // Upper end moves a bit faster, spreading wave
|
||||
wave[h][w].intensity = 300 + random(600);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
uint8_t h, w;
|
||||
|
||||
randomSeed(analogRead(1));
|
||||
pixels.begin();
|
||||
for(h=0; h<N_HORNS; h++) {
|
||||
for(w=0; w<N_WAVES; w++) random_wave(h, w);
|
||||
}
|
||||
fade = 233 + N_LEDS / 2;
|
||||
if(fade > 255) fade = 255;
|
||||
|
||||
// A ~100 Hz timer interrupt on Timer/Counter1 makes everything run
|
||||
// at regular intervals, regardless of current amount of motion.
|
||||
#if F_CPU == 16000000L
|
||||
clock_prescale_set(clock_div_1);
|
||||
TCCR1 = _BV(PWM1A) | _BV(CS13) | _BV(CS11) | _BV(CS10); // 1:1024 prescale
|
||||
OCR1C = F_CPU / 1024 / 100 - 1;
|
||||
#else
|
||||
TCCR1 = _BV(PWM1A) | _BV(CS13) | _BV(CS11); // 1:512 prescale
|
||||
OCR1C = F_CPU / 512 / 100 - 1;
|
||||
#endif
|
||||
GTCCR = 0; // No PWM out
|
||||
TIMSK |= _BV(TOIE1); // Enable overflow interrupt
|
||||
}
|
||||
|
||||
void loop() { } // Not used -- everything's in interrupt below
|
||||
|
||||
ISR(TIMER1_OVF_vect) {
|
||||
uint8_t h, w, i, r, g, b;
|
||||
int16_t x;
|
||||
uint16_t sum;
|
||||
|
||||
for(h=0; h<N_HORNS; h++) { // For each horn...
|
||||
for(x=7, i=0; i<N_LEDS; i++, x+=16) { // For each LED along horn...
|
||||
for(sum=w=0; w<N_WAVES; w++) { // For each wave of horn...
|
||||
if((x < wave[h][w].lower) || (x > wave[h][w].upper)) continue; // Out of range
|
||||
if(x <= wave[h][w].mid) { // Lower half of wave (ramping up to peak brightness)
|
||||
sum += wave[h][w].intensity * (x - wave[h][w].lower) / (wave[h][w].mid - wave[h][w].lower);
|
||||
} else { // Upper half of wave (ramping down from peak)
|
||||
sum += wave[h][w].intensity * (wave[h][w].upper - x) / (wave[h][w].upper - wave[h][w].mid);
|
||||
}
|
||||
}
|
||||
// Now the magnitude (sum) is remapped to color for the LEDs.
|
||||
// A blackbody palette is used - fades white-yellow-red-black.
|
||||
if(sum < 255) { // 0-254 = black to red-1
|
||||
r = pgm_read_byte(&gamma[sum]);
|
||||
g = b = 0;
|
||||
} else if(sum < 510) { // 255-509 = red to yellow-1
|
||||
r = 255;
|
||||
g = pgm_read_byte(&gamma[sum - 255]);
|
||||
b = 0;
|
||||
} else if(sum < 765) { // 510-764 = yellow to white-1
|
||||
r = g = 255;
|
||||
b = pgm_read_byte(&gamma[sum - 510]);
|
||||
} else { // 765+ = white
|
||||
r = g = b = 255;
|
||||
}
|
||||
pixels.setPixelColor(h * N_LEDS + i, r, g, b);
|
||||
}
|
||||
|
||||
for(w=0; w<N_WAVES; w++) { // Update wave positions for each horn
|
||||
wave[h][w].lower += wave[h][w].vlower; // Advance lower position
|
||||
if(wave[h][w].lower >= (N_LEDS * 16)) { // Off end of strip?
|
||||
random_wave(h, w); // Yes, 'reboot' wave
|
||||
} else { // No, adjust other values...
|
||||
wave[h][w].upper += wave[h][w].vupper;
|
||||
wave[h][w].mid = (wave[h][w].lower + wave[h][w].upper) / 2;
|
||||
wave[h][w].intensity = (wave[h][w].intensity * fade) / 256; // Dimmer
|
||||
}
|
||||
}
|
||||
}
|
||||
pixels.show();
|
||||
}
|
||||
147
3D_Printed_LED_Fire_Horns/3D_Printed_LED_Fire_Horns.py
Normal file
147
3D_Printed_LED_Fire_Horns/3D_Printed_LED_Fire_Horns.py
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
# Fiery demon horns (rawr!) for Adafruit Trinket/Gemma.
|
||||
# Adafruit invests time and resources providing this open source code,
|
||||
# please support Adafruit and open-source hardware by purchasing
|
||||
# products from Adafruit!
|
||||
|
||||
import board
|
||||
import neopixel
|
||||
from analogio import AnalogIn
|
||||
# pylint: disable=global-statement
|
||||
|
||||
try:
|
||||
import urandom as random
|
||||
except ImportError:
|
||||
import random
|
||||
|
||||
# /\ -> Fire-like effect is the sum_total of multiple triangle
|
||||
# ____/ \____ waves in motion, with a 'warm' color map applied.
|
||||
n_horns = 1 # number of horns
|
||||
led_pin = board.D0 # which pin your pixels are connected to
|
||||
n_leds = 30 # number of LEDs per horn
|
||||
frames_per_second = 50 # animation frames per second
|
||||
brightness = 0 # current wave height
|
||||
fade = 0 # Decreases brightness as wave moves
|
||||
pixels = neopixel.NeoPixel(led_pin, n_leds, brightness=1, auto_write=False)
|
||||
offset = 0
|
||||
|
||||
# Coordinate space for waves is 16x the pixel spacing,
|
||||
# allowing fixed-point math to be used instead of floats.
|
||||
lower = 0 # lower bound of wave
|
||||
upper = 1 # upper bound of wave
|
||||
mid = 2 # midpoint (peak) ((lower+upper)/2)
|
||||
vlower = 3 # velocity of lower bound
|
||||
vupper = 4 # velocity of upper bound
|
||||
intensity = 5 # brightness at peak
|
||||
|
||||
y = 0
|
||||
brightness = 0
|
||||
count = 0
|
||||
|
||||
# initialize 3D list
|
||||
wave = [[0] * 6] * 6, [[0] * 6] * 6, [[0] * 6] * 6, [[0] * 6] * 6, [[0] * 6] * 6, [[0] * 6] * 6
|
||||
|
||||
# Number of simultaneous waves (per horn)
|
||||
n_waves = len(wave)
|
||||
|
||||
# Gamma-correction table
|
||||
gamma = [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
|
||||
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
|
||||
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
|
||||
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
|
||||
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
|
||||
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
|
||||
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
|
||||
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
|
||||
90, 92, 93, 95, 96, 98, 99, 101, 102, 104, 105, 107, 109, 110,
|
||||
112, 114, 115, 117, 119, 120, 122, 124, 126, 127, 129, 131, 133,
|
||||
135, 137, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158,
|
||||
160, 162, 164, 167, 169, 171, 173, 175, 177, 180, 182, 184, 186,
|
||||
189, 191, 193, 196, 198, 200, 203, 205, 208, 210, 213, 215, 218,
|
||||
220, 223, 225, 228, 231, 233, 236, 239, 241, 244, 247, 249, 252,
|
||||
255
|
||||
]
|
||||
|
||||
|
||||
def random_wave(he, wi):
|
||||
wave[he][wi][upper] = -1 # Always start below head of strip
|
||||
wave[he][wi][lower] = -16 * (3 + random.randint(0,4)) # Lower end starts ~3-7 pixels back
|
||||
wave[he][wi][mid] = (wave[he][wi][lower]+ wave[he][wi][upper]) / 2
|
||||
wave[he][wi][vlower] = 3 + random.randint(0,4) # Lower end moves at ~1/8 to 1/pixels
|
||||
wave[he][wi][vupper] = wave[he][wi][vlower]+ random.randint(0,4) # Upper end moves a bit faster
|
||||
wave[he][wi][intensity] = 300 + random.randint(0,600)
|
||||
|
||||
def setup():
|
||||
global fade
|
||||
|
||||
# Random number generator is seeded from an unused 'floating'
|
||||
# analog input - this helps ensure the random color choices
|
||||
# aren't always the same order.
|
||||
pin = AnalogIn(board.A0)
|
||||
random.seed(pin.value)
|
||||
pin.deinit()
|
||||
|
||||
for he in range(n_horns):
|
||||
for wi in range(n_waves):
|
||||
random_wave(he, wi)
|
||||
|
||||
fade = 233 + n_leds / 2
|
||||
|
||||
if fade > 233:
|
||||
fade = 233
|
||||
|
||||
setup()
|
||||
|
||||
while True:
|
||||
|
||||
h = w = i = r = g = b = 0
|
||||
x = 0
|
||||
|
||||
for h in range(n_horns): # For each horn...
|
||||
x = 7
|
||||
sum_total = 0
|
||||
for i in range(n_leds): # For each LED along horn...
|
||||
x += 16
|
||||
for w in range(n_waves): # For each wave of horn...
|
||||
if (x < wave[h][w][lower]) or (x > wave[h][w][upper]):
|
||||
continue # Out of range
|
||||
if x <= wave[h][w][mid]: # Lower half of wave (ramping up peak brightness)
|
||||
sum_top = wave[h][w][intensity] * (x - wave[h][w][lower])
|
||||
sum_bottom = (wave[h][w][mid] - wave[h][w][lower])
|
||||
sum_total += sum_top / sum_bottom
|
||||
else: # Upper half of wave (ramping down from peak)
|
||||
sum_top = wave[h][w][intensity] * (wave[h][w][upper] - x)
|
||||
sum_bottom = (wave[h][w][upper] - wave[h][w][mid])
|
||||
sum_total += sum_top / sum_bottom
|
||||
|
||||
sum_total = int(sum_total) # convert from decimal to whole number
|
||||
|
||||
# Now the magnitude (sum_total) is remapped to color for the LEDs.
|
||||
# A blackbody palette is used - fades white-yellow-red-black.
|
||||
if sum_total < 255: # 0-254 = black to red-1
|
||||
r = gamma[sum_total]
|
||||
g = b = 0
|
||||
elif sum_total < 510: # 255-509 = red to yellow-1
|
||||
r = 255
|
||||
g = gamma[sum_total - 255]
|
||||
b = 0
|
||||
elif sum_total < 765: # 510-764 = yellow to white-1
|
||||
r = g = 255
|
||||
b = gamma[sum_total - 510]
|
||||
else: # 765+ = white
|
||||
r = g = b = 255
|
||||
pixels[i] = (r, g, b)
|
||||
|
||||
for w in range(n_waves): # Update wave positions for each horn
|
||||
wave[h][w][lower] += wave[h][w][vlower] # Advance lower position
|
||||
if wave[h][w][lower] >= (n_leds * 16): # Off end of strip?
|
||||
random_wave(h, w) # Yes, 'reboot' wave
|
||||
else: # No, adjust other values...
|
||||
wave[h][w][upper] += wave[h][w][vupper]
|
||||
wave[h][w][mid] = (wave[h][w][lower] + wave[h][w][upper]) / 2
|
||||
wave[h][w][intensity] = (wave[h][w][intensity] * fade) / 256 # Dimmer
|
||||
|
||||
pixels.show()
|
||||
4
3D_Printed_LED_Fire_Horns/README.md
Normal file
4
3D_Printed_LED_Fire_Horns/README.md
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# 3D Printed LED Fire Horns
|
||||
|
||||
Code to accompany this tutorial:
|
||||
https://learn.adafruit.com/3d-printed-led-fire-horns/fire-code
|
||||
0
3D_Printed_LED_Microphone_Flag/.uno.test
Normal file
0
3D_Printed_LED_Microphone_Flag/.uno.test
Normal file
|
|
@ -27,42 +27,46 @@
|
|||
# Modified fromhere code by Greg Shakar
|
||||
# Ported to Circuit Python by Mikey Sklar
|
||||
|
||||
import time
|
||||
|
||||
import board
|
||||
import neopixel
|
||||
import time
|
||||
from analogio import AnalogIn
|
||||
import array
|
||||
|
||||
n_pixels = 16 # Number of pixels you are using
|
||||
mic_pin = AnalogIn(board.A1) # Microphone is attached to this analog pin
|
||||
led_pin = board.D1 # NeoPixel LED strand is connected to this pin
|
||||
sample_window = .1 # Sample window for average level
|
||||
peak_hang = 24 # Time of pause before peak dot falls
|
||||
peak_fall = 4 # Rate of falling peak dot
|
||||
input_floor = 10 # Lower range of analogRead input
|
||||
input_ceiling = 300 # Max range of analogRead input, the lower the value the more sensitive (1023 = max)
|
||||
n_pixels = 16 # Number of pixels you are using
|
||||
mic_pin = AnalogIn(board.A1) # Microphone is attached to this analog pin
|
||||
led_pin = board.D1 # NeoPixel LED strand is connected to this pin
|
||||
sample_window = .1 # Sample window for average level
|
||||
peak_hang = 24 # Time of pause before peak dot falls
|
||||
peak_fall = 4 # Rate of falling peak dot
|
||||
input_floor = 10 # Lower range of analogRead input
|
||||
# Max range of analogRead input, the lower the value the more sensitive
|
||||
# (1023 = max)
|
||||
input_ceiling = 300
|
||||
|
||||
peak = 16 # Peak level of column; used for falling dots
|
||||
peak = 16 # Peak level of column; used for falling dots
|
||||
sample = 0
|
||||
|
||||
dotcount = 0 # Frame counter for peak dot
|
||||
dothangcount = 0 # Frame counter for holding peak dot
|
||||
dotcount = 0 # Frame counter for peak dot
|
||||
dothangcount = 0 # Frame counter for holding peak dot
|
||||
|
||||
strip = neopixel.NeoPixel(led_pin, n_pixels, brightness=1, auto_write=False)
|
||||
|
||||
|
||||
def wheel(pos):
|
||||
# Input a value 0 to 255 to get a color value.
|
||||
# The colours are a transition r - g - b - back to r.
|
||||
if (pos < 0) or (pos > 255):
|
||||
if pos < 0 or pos > 255:
|
||||
return (0, 0, 0)
|
||||
if (pos < 85):
|
||||
return (int(pos * 3), int(255 - (pos*3)), 0)
|
||||
elif (pos < 170):
|
||||
if pos < 85:
|
||||
return (int(pos * 3), int(255 - (pos * 3)), 0)
|
||||
elif pos < 170:
|
||||
pos -= 85
|
||||
return (int(255 - pos*3), 0, int(pos*3))
|
||||
return (int(255 - pos * 3), 0, int(pos * 3))
|
||||
else:
|
||||
pos -= 170
|
||||
return (0, int(pos*3), int(255 - pos*3))
|
||||
return (0, int(pos * 3), int(255 - pos * 3))
|
||||
|
||||
|
||||
def remapRange(value, leftMin, leftMax, rightMin, rightMax):
|
||||
# this remaps a value fromhere original (left) range to new (right) range
|
||||
|
|
@ -76,91 +80,89 @@ def remapRange(value, leftMin, leftMax, rightMin, rightMax):
|
|||
# Convert the 0-1 range into a value in the right range.
|
||||
return int(rightMin + (valueScaled * rightSpan))
|
||||
|
||||
|
||||
def fscale(originalmin, originalmax, newbegin, newend, inputvalue, curve):
|
||||
originalrange = 0
|
||||
newrange = 0
|
||||
zerorefcurval = 0
|
||||
normalizedcurval = 0
|
||||
rangedvalue = 0
|
||||
invflag = 0
|
||||
|
||||
# condition curve parameter
|
||||
# limit range
|
||||
if (curve > 10):
|
||||
if curve > 10:
|
||||
curve = 10
|
||||
if (curve < -10):
|
||||
if curve < -10:
|
||||
curve = -10
|
||||
|
||||
# - invert and scale -
|
||||
# this seems more intuitive
|
||||
# - invert and scale -
|
||||
# this seems more intuitive
|
||||
# postive numbers give more weight to high end on output
|
||||
curve = (curve * -.1)
|
||||
curve = pow(10, curve) # convert linear scale into lograthimic exponent for other pow function
|
||||
curve = (curve * -.1)
|
||||
# convert linear scale into lograthimic exponent for other pow function
|
||||
curve = pow(10, curve)
|
||||
|
||||
# Check for out of range inputValues
|
||||
if (inputvalue < originalmin):
|
||||
if inputvalue < originalmin:
|
||||
inputvalue = originalmin
|
||||
|
||||
if (inputvalue > originalmax):
|
||||
if inputvalue > originalmax:
|
||||
inputvalue = originalmax
|
||||
|
||||
# Zero Refference the values
|
||||
originalrange = originalmax - originalmin
|
||||
|
||||
if (newend > newbegin):
|
||||
if newend > newbegin:
|
||||
newrange = newend - newbegin
|
||||
else:
|
||||
newrange = newbegin - newend
|
||||
invflag = 1
|
||||
|
||||
zerorefcurval = inputvalue - originalmin
|
||||
normalizedcurval = zerorefcurval / originalrange # normalize to 0 - 1 float
|
||||
# normalize to 0 - 1 float
|
||||
normalizedcurval = zerorefcurval / originalrange
|
||||
|
||||
# Check for originalMin > originalMax
|
||||
# -the math for all other cases
|
||||
# Check for originalMin > originalMax
|
||||
# -the math for all other cases
|
||||
# i.e. negative numbers seems to work out fine
|
||||
if (originalmin > originalmax ):
|
||||
return(0)
|
||||
if originalmin > originalmax:
|
||||
return 0
|
||||
|
||||
if (invflag == 0):
|
||||
rangedvalue = (pow(normalizedcurval, curve) * newrange) + newbegin
|
||||
else: # invert the ranges
|
||||
rangedvalue = newbegin - (pow(normalizedcurval, curve) * newrange);
|
||||
if invflag == 0:
|
||||
rangedvalue = (pow(normalizedcurval, curve) * newrange) + newbegin
|
||||
else: # invert the ranges
|
||||
rangedvalue = newbegin - (pow(normalizedcurval, curve) * newrange)
|
||||
|
||||
return rangedvalue
|
||||
|
||||
return(rangedvalue)
|
||||
|
||||
def drawLine(fromhere, to):
|
||||
|
||||
fromheretemp = 0
|
||||
|
||||
if (fromhere > to):
|
||||
if fromhere > to:
|
||||
fromheretemp = fromhere
|
||||
fromhere = to
|
||||
to = fromheretemp
|
||||
|
||||
for i in range(fromhere, to):
|
||||
strip[i] = (0,0,0)
|
||||
for index in range(fromhere, to):
|
||||
strip[index] = (0, 0, 0)
|
||||
|
||||
|
||||
while True:
|
||||
|
||||
time_start = time.monotonic() # current time used for sample window
|
||||
peaktopeak = 0 # peak-to-peak level
|
||||
time_start = time.monotonic() # current time used for sample window
|
||||
peaktopeak = 0 # peak-to-peak level
|
||||
signalmax = 0
|
||||
signalmin = 1023
|
||||
signalmin = 1023
|
||||
c = 0
|
||||
y = 0
|
||||
|
||||
# collect data for length of sample window (in seconds)
|
||||
while ( ( time.monotonic() - time_start ) < sample_window):
|
||||
while (time.monotonic() - time_start) < sample_window:
|
||||
|
||||
sample = mic_pin.value / 64 # convert to arduino 10-bit [1024] fromhere 16-bit [65536]
|
||||
# convert to arduino 10-bit [1024] fromhere 16-bit [65536]
|
||||
sample = mic_pin.value / 64
|
||||
|
||||
if (sample < 1024): # toss out spurious readings
|
||||
if sample < 1024: # toss out spurious readings
|
||||
|
||||
if (sample > signalmax):
|
||||
signalmax = sample # save just the max levels
|
||||
elif (sample < signalmin):
|
||||
signalmin = sample # save just the min levels
|
||||
if sample > signalmax:
|
||||
signalmax = sample # save just the max levels
|
||||
elif sample < signalmin:
|
||||
signalmin = sample # save just the min levels
|
||||
|
||||
peaktopeak = signalmax - signalmin # max - min = peak-peak amplitude
|
||||
|
||||
|
|
@ -171,11 +173,11 @@ while True:
|
|||
# Scale the input logarithmically instead of linearly
|
||||
c = fscale(input_floor, input_ceiling, (n_pixels - 1), 0, peaktopeak, 2)
|
||||
|
||||
if (c < peak):
|
||||
peak = c # keep dot on top
|
||||
dothangcount = 0 # make the dot hang before falling
|
||||
if c < peak:
|
||||
peak = c # keep dot on top
|
||||
dothangcount = 0 # make the dot hang before falling
|
||||
|
||||
if (c <= n_pixels): # fill partial column with off pixels
|
||||
if c <= n_pixels: # fill partial column with off pixels
|
||||
drawLine(n_pixels, n_pixels - int(c))
|
||||
|
||||
# Set the peak dot to match the rainbow gradient
|
||||
|
|
@ -184,8 +186,9 @@ while True:
|
|||
strip.write()
|
||||
|
||||
# Frame based peak dot animation
|
||||
if(dothangcount > peak_hang): # Peak pause length
|
||||
if(++dotcount >= peak_fall): # Fall rate
|
||||
if dothangcount > peak_hang: # Peak pause length
|
||||
dotcount += 1
|
||||
if dotcount >= peak_fall: # Fall rate
|
||||
peak += 1
|
||||
dotcount = 0
|
||||
else:
|
||||
|
|
|
|||
0
3D_Printed_NeoPixel_Gas_Mask/.gemma.test
Normal file
0
3D_Printed_NeoPixel_Gas_Mask/.gemma.test
Normal file
|
|
@ -1,55 +1,58 @@
|
|||
import time
|
||||
|
||||
import board
|
||||
import neopixel
|
||||
import time
|
||||
|
||||
try:
|
||||
import urandom as random # for v1.0 API support
|
||||
import urandom as random # for v1.0 API support
|
||||
except ImportError:
|
||||
import random
|
||||
import random
|
||||
|
||||
numpix = 24 # Number of NeoPixels
|
||||
numpix = 24 # Number of NeoPixels
|
||||
pixpin = board.D0 # Pin where NeoPixels are connected
|
||||
strip = neopixel.NeoPixel(pixpin, numpix, brightness=0.3)
|
||||
strip = neopixel.NeoPixel(pixpin, numpix, brightness=0.3)
|
||||
|
||||
mode = 0 # Current animation effect
|
||||
offset = 0 # Position of spinner animation
|
||||
color = [255, 0, 0] # RGB color - red
|
||||
mode = 0 # Current animation effect
|
||||
offset = 0 # Position of spinner animation
|
||||
color = [255, 0, 0] # RGB color - red
|
||||
prevtime = time.monotonic() # Time of last animation mode switch
|
||||
|
||||
while True: # Loop forever...
|
||||
|
||||
if mode == 0: # Random sparkles - lights just one LED at a time
|
||||
i = random.randint(0, numpix - 1) # Choose random pixel
|
||||
strip[i] = color # Set it to current color
|
||||
strip.write() # Refresh LED states
|
||||
# Set same pixel to "off" color now but DON'T refresh...
|
||||
# it stays on for now...bot this and the next random
|
||||
# pixel will be refreshed on the next pass.
|
||||
strip[i] = [0,0,0]
|
||||
time.sleep(0.008) # 8 millisecond delay
|
||||
elif mode == 1: # Spinny wheels
|
||||
# A little trick here: pixels are processed in groups of 8
|
||||
# (with 2 of 8 on at a time), NeoPixel rings are 24 pixels
|
||||
# (8*3) and 16 pixels (8*2), so we can issue the same data
|
||||
# to both rings and it appears correct and contiguous
|
||||
# (also, the pixel order is different between the two ring
|
||||
# types, so we get the reversed motion on #2 for free).
|
||||
for i in range(numpix): # For each LED...
|
||||
if ((offset + i) & 7) < 2: # 2 pixels out of 8...
|
||||
strip[i] = color # are set to current color
|
||||
else:
|
||||
strip[i] = [0,0,0] # other pixels are off
|
||||
strip.write() # Refresh LED states
|
||||
time.sleep(0.04) # 40 millisecond delay
|
||||
offset += 1 # Shift animation by 1 pixel on next frame
|
||||
if offset >= 8: offset = 0
|
||||
# Additional animation modes could be added here!
|
||||
if mode == 0: # Random sparkles - lights just one LED at a time
|
||||
i = random.randint(0, numpix - 1) # Choose random pixel
|
||||
strip[i] = color # Set it to current color
|
||||
strip.write() # Refresh LED states
|
||||
# Set same pixel to "off" color now but DON'T refresh...
|
||||
# it stays on for now...bot this and the next random
|
||||
# pixel will be refreshed on the next pass.
|
||||
strip[i] = [0, 0, 0]
|
||||
time.sleep(0.008) # 8 millisecond delay
|
||||
elif mode == 1: # Spinny wheels
|
||||
# A little trick here: pixels are processed in groups of 8
|
||||
# (with 2 of 8 on at a time), NeoPixel rings are 24 pixels
|
||||
# (8*3) and 16 pixels (8*2), so we can issue the same data
|
||||
# to both rings and it appears correct and contiguous
|
||||
# (also, the pixel order is different between the two ring
|
||||
# types, so we get the reversed motion on #2 for free).
|
||||
for i in range(numpix): # For each LED...
|
||||
if ((offset + i) & 7) < 2: # 2 pixels out of 8...
|
||||
strip[i] = color # are set to current color
|
||||
else:
|
||||
strip[i] = [0, 0, 0] # other pixels are off
|
||||
strip.write() # Refresh LED states
|
||||
time.sleep(0.04) # 40 millisecond delay
|
||||
offset += 1 # Shift animation by 1 pixel on next frame
|
||||
if offset >= 8:
|
||||
offset = 0
|
||||
# Additional animation modes could be added here!
|
||||
|
||||
t = time.monotonic() # Current time in seconds
|
||||
if (t - prevtime) >= 8: # Every 8 seconds...
|
||||
mode += 1 # Advance to next mode
|
||||
if mode > 1: # End of modes?
|
||||
mode = 0 # Start over from beginning
|
||||
# Rotate color R->G->B
|
||||
color = [ color[2], color[0], color[1] ]
|
||||
strip.fill([0,0,0]) # Turn off all pixels
|
||||
prevtime = t # Record time of last mode change
|
||||
t = time.monotonic() # Current time in seconds
|
||||
if (t - prevtime) >= 8: # Every 8 seconds...
|
||||
mode += 1 # Advance to next mode
|
||||
if mode > 1: # End of modes?
|
||||
mode = 0 # Start over from beginning
|
||||
# Rotate color R->G->B
|
||||
color = [color[2], color[0], color[1]]
|
||||
strip.fill([0, 0, 0]) # Turn off all pixels
|
||||
prevtime = t # Record time of last mode change
|
||||
|
|
|
|||
0
3D_Printed_NeoPixel_Ring_Hair_Dress/.gemma.test
Normal file
0
3D_Printed_NeoPixel_Ring_Hair_Dress/.gemma.test
Normal file
|
|
@ -1,56 +1,62 @@
|
|||
#
|
||||
# 3D_Printed_NeoPixel_Ring_Hair_Dress.py
|
||||
#
|
||||
# this was ported to CircuitPython from the 'Gemma Hoop Animator'
|
||||
# this was ported to CircuitPython from the 'Gemma Hoop Animator'
|
||||
#
|
||||
# https://github.com/HerrRausB/GemmaHoopAnimator
|
||||
#
|
||||
# unless you # don't like the preset animations or find a
|
||||
# unless you # don't like the preset animations or find a
|
||||
# major bug, you don't need tochange anything here
|
||||
#
|
||||
import time
|
||||
|
||||
import board
|
||||
import neopixel
|
||||
import time
|
||||
|
||||
try:
|
||||
import urandom as random # for v1.0 API support
|
||||
import urandom as random # for v1.0 API support
|
||||
except ImportError:
|
||||
import random
|
||||
import random
|
||||
from analogio import AnalogIn
|
||||
|
||||
# available actions
|
||||
ACT_NOP = 0x00 # all leds off, do nothing
|
||||
ACT_SIMPLE_RING = 0x01 # all leds on
|
||||
ACT_CYCLING_RING_ACLK = 0x02 # anti clockwise cycling colors
|
||||
ACT_CYCLING_RING_CLKW = 0x04 # clockwise cycling colors
|
||||
ACT_WHEEL_ACLK = 0x08 # anti clockwise spinning wheel
|
||||
ACT_WHEEL_CLKW = 0x10 # clockwise spinning wheel
|
||||
ACT_SPARKLING_RING = 0x20 # sparkling effect
|
||||
ACT_NOP = 0x00 # all leds off, do nothing
|
||||
ACT_SIMPLE_RING = 0x01 # all leds on
|
||||
ACT_CYCLING_RING_ACLK = 0x02 # anti clockwise cycling colors
|
||||
ACT_CYCLING_RING_CLKW = 0x04 # clockwise cycling colors
|
||||
ACT_WHEEL_ACLK = 0x08 # anti clockwise spinning wheel
|
||||
ACT_WHEEL_CLKW = 0x10 # clockwise spinning wheel
|
||||
ACT_SPARKLING_RING = 0x20 # sparkling effect
|
||||
|
||||
numpix = 16 # total number of NeoPixels
|
||||
pixel_output = board.D0 # pin where NeoPixels are connected
|
||||
analog_input = board.A0 # needed to seed the random generator
|
||||
strip = neopixel.NeoPixel(pixel_output, numpix, brightness=.3, auto_write=False)
|
||||
numpix = 16 # total number of NeoPixels
|
||||
pixel_output = board.D0 # pin where NeoPixels are connected
|
||||
analog_input = board.A0 # needed to seed the random generator
|
||||
strip = neopixel.NeoPixel(pixel_output, numpix,
|
||||
brightness=.3, auto_write=False)
|
||||
|
||||
# available color generation methods
|
||||
COL_RANDOM = 0x40 # colors will be generated randomly
|
||||
COL_SPECTRUM = 0x80 # colors will be set as cyclic spectral wipe
|
||||
COL_RANDOM = 0x40 # colors will be generated randomly
|
||||
COL_SPECTRUM = 0x80 # colors will be set as cyclic spectral wipe
|
||||
|
||||
# specifiyng the action list
|
||||
action_duration = 0 # the action's overall duration in milliseconds (be careful not
|
||||
# to use values > 2^16-1 - roughly one minute :-)
|
||||
# the action's overall duration in milliseconds (be careful not
|
||||
action_duration = 0
|
||||
# to use values > 2^16-1 - roughly one minute :-)
|
||||
|
||||
action_and_color_gen = 1 # the color generation method
|
||||
action_and_color_gen = 1 # the color generation method
|
||||
|
||||
action_step_duration = 2 # the duration of each action step rsp. the delay of the main
|
||||
# loop in milliseconds - thus, controls the action speed (be
|
||||
# careful not to use values > 2^16-1 - roughly one minute :-)
|
||||
# the duration of each action step rsp. the delay of the main
|
||||
action_step_duration = 2
|
||||
# loop in milliseconds - thus, controls the action speed (be
|
||||
# careful not to use values > 2^16-1 - roughly one minute :-)
|
||||
|
||||
color_granularity = 3 # controls the increment of the R, G, and B portions of the
|
||||
# rsp. color. 1 means the increment is 0,1,2,3,..., 10 means
|
||||
# the increment is 0,10,20,... don't use values > 255, and note
|
||||
# that even values > 127 wouldn't make much sense...
|
||||
color_granularity = 3 # controls the increment of the R, G, and B
|
||||
# portions of the rsp. color. 1 means the increment is 0,1,2,3,...,
|
||||
# 10 means the increment is 0,10,20,... don't use values > 255, and
|
||||
# note that even values > 127 wouldn't make much sense...
|
||||
|
||||
color_interval = 4 # controls the speed of color changing independently from action
|
||||
# controls the speed of color changing independently from action
|
||||
color_interval = 4
|
||||
|
||||
# general global variables
|
||||
color = 0
|
||||
|
|
@ -65,7 +71,7 @@ curr_action = 0
|
|||
curr_color_gen = COL_RANDOM
|
||||
idx = 0
|
||||
offset = 0
|
||||
number_of_actions = 31
|
||||
number_of_actions = 31
|
||||
curr_action_idx = 0
|
||||
curr_color_granularity = 1
|
||||
spectrum_part = 0
|
||||
|
|
@ -74,111 +80,139 @@ spectrum_part = 0
|
|||
# this array variable must be called theactionlist !!!
|
||||
#
|
||||
# valid actions are:
|
||||
# ACT_NOP simply do nothing and switch everything off
|
||||
# ACT_SIMPLE_RING all leds on
|
||||
# ACT_CYCLING_RING_ACLK anti clockwise cycling colors
|
||||
# ACT_CYCLING_RING_CLKW clockwise cycling colors acording
|
||||
# ACT_WHEEL_ACLK anti clockwise spinning wheel
|
||||
# ACT_WHEEL_CLKW clockwise spinning wheel
|
||||
# ACT_SPARKLING_RING sparkling effect
|
||||
#
|
||||
# ACT_NOP simply do nothing and switch everything off
|
||||
# ACT_SIMPLE_RING all leds on
|
||||
# ACT_CYCLING_RING_ACLK anti clockwise cycling colors
|
||||
# ACT_CYCLING_RING_CLKW clockwise cycling colors acording
|
||||
# ACT_WHEEL_ACLK anti clockwise spinning wheel
|
||||
# ACT_WHEEL_CLKW clockwise spinning wheel
|
||||
# ACT_SPARKLING_RING sparkling effect
|
||||
#
|
||||
# valid color options are:
|
||||
# COL_RANDOM colors will be selected randomly, which might
|
||||
# be not very sufficient due to well known
|
||||
# limitations of the random generation algorithm
|
||||
# COL_SPECTRUM colors will be set as cyclic spectral wipe
|
||||
# R -> G -> B -> R -> G -> B -> R -> ...
|
||||
# COL_RANDOM colors will be selected randomly, which might
|
||||
# be not very sufficient due to well known
|
||||
# limitations of the random generation algorithm
|
||||
# COL_SPECTRUM colors will be set as cyclic spectral wipe
|
||||
# R -> G -> B -> R -> G -> B -> R -> ...
|
||||
|
||||
# action action name & action step color color change
|
||||
# duration color generation method duration granularity interval
|
||||
# action action name & action step color color change
|
||||
# duration color generation method duration granularity interval
|
||||
theactionlist = [
|
||||
[ 5, ACT_SPARKLING_RING | COL_RANDOM, 0.01, 25, 1 ],
|
||||
[ 2, ACT_CYCLING_RING_CLKW | COL_RANDOM, 0.02, 1, 0.005 ],
|
||||
[ 5, ACT_SPARKLING_RING | COL_RANDOM, 0.01, 25, 1 ],
|
||||
[ 2, ACT_CYCLING_RING_ACLK | COL_RANDOM, 0.02, 1, 0.005 ],
|
||||
[ 5, ACT_SPARKLING_RING | COL_RANDOM, 0.01, 25, 1 ],
|
||||
[ 2.5, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.25, 20, 0.020 ],
|
||||
[ 1, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.50, 1, 0.020 ],
|
||||
[ .750, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.075, 1, 0.020 ],
|
||||
[ .500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.100, 1, 0.020 ],
|
||||
[ .500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.125, 1, 0.020 ],
|
||||
[ .500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.150, 1, 0.050 ],
|
||||
[ .500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.175, 1, 0.100 ],
|
||||
[ .500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.200, 1, 0.200 ],
|
||||
[ .750, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.225, 1, 0.250 ],
|
||||
[ 1, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.250, 1, 0.350 ],
|
||||
[ 30, ACT_SIMPLE_RING | COL_SPECTRUM, 0.050, 1, 0.010 ],
|
||||
[ 2.5, ACT_WHEEL_ACLK | COL_SPECTRUM, 0.010, 1, 0.010 ],
|
||||
[ 2.5, ACT_WHEEL_ACLK | COL_SPECTRUM, 0.015, 1, 0.020 ],
|
||||
[ 2, ACT_WHEEL_ACLK | COL_SPECTRUM, 0.025, 1, 0.030 ],
|
||||
[ 1, ACT_WHEEL_ACLK | COL_SPECTRUM, 0.050, 1, 0.040 ],
|
||||
[ 1, ACT_WHEEL_ACLK | COL_SPECTRUM, 0.075, 1, 0.040 ],
|
||||
[ 1, ACT_WHEEL_ACLK | COL_SPECTRUM, 0.100, 1, 0.050 ],
|
||||
[ .500, ACT_WHEEL_ACLK | COL_SPECTRUM, 0.125, 1, 0.060 ],
|
||||
[ .500, ACT_WHEEL_CLKW | COL_SPECTRUM, 0.125, 5, 0.050 ],
|
||||
[ 1, ACT_WHEEL_CLKW | COL_SPECTRUM, 0.100, 10, 0.040 ],
|
||||
[ 1.5, ACT_WHEEL_CLKW | COL_SPECTRUM, 0.075, 15, 0.030 ],
|
||||
[ 2, ACT_WHEEL_CLKW | COL_SPECTRUM, 0.050, 20, 0.020 ],
|
||||
[ 2.5, ACT_WHEEL_CLKW | COL_SPECTRUM, 0.025, 25, 0.010 ],
|
||||
[ 3, ACT_WHEEL_CLKW | COL_SPECTRUM, 0.010, 30, 0.005 ],
|
||||
[ 5, ACT_SPARKLING_RING | COL_RANDOM, 0.010, 25, 1 ],
|
||||
[ 5, ACT_NOP, 0, 0, 0 ]
|
||||
[5, ACT_SPARKLING_RING | COL_RANDOM, 0.01, 25, 1],
|
||||
[2, ACT_CYCLING_RING_CLKW | COL_RANDOM,
|
||||
0.02, 1, 0.005],
|
||||
[5, ACT_SPARKLING_RING | COL_RANDOM, 0.01, 25, 1],
|
||||
[2, ACT_CYCLING_RING_ACLK | COL_RANDOM,
|
||||
0.02, 1, 0.005],
|
||||
[5, ACT_SPARKLING_RING | COL_RANDOM, 0.01, 25, 1],
|
||||
[2.5, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
|
||||
0.25, 20, 0.020],
|
||||
[1, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
|
||||
0.50, 1, 0.020],
|
||||
[.750, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
|
||||
0.075, 1, 0.020],
|
||||
[.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
|
||||
0.100, 1, 0.020],
|
||||
[.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
|
||||
0.125, 1, 0.020],
|
||||
[.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
|
||||
0.150, 1, 0.050],
|
||||
[.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
|
||||
0.175, 1, 0.100],
|
||||
[.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
|
||||
0.200, 1, 0.200],
|
||||
[.750, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
|
||||
0.225, 1, 0.250],
|
||||
[1, ACT_CYCLING_RING_CLKW | COL_SPECTRUM,
|
||||
0.250, 1, 0.350],
|
||||
[30, ACT_SIMPLE_RING | COL_SPECTRUM,
|
||||
0.050, 1, 0.010],
|
||||
[2.5, ACT_WHEEL_ACLK | COL_SPECTRUM,
|
||||
0.010, 1, 0.010],
|
||||
[2.5, ACT_WHEEL_ACLK | COL_SPECTRUM,
|
||||
0.015, 1, 0.020],
|
||||
[2, ACT_WHEEL_ACLK | COL_SPECTRUM,
|
||||
0.025, 1, 0.030],
|
||||
[1, ACT_WHEEL_ACLK | COL_SPECTRUM,
|
||||
0.050, 1, 0.040],
|
||||
[1, ACT_WHEEL_ACLK | COL_SPECTRUM,
|
||||
0.075, 1, 0.040],
|
||||
[1, ACT_WHEEL_ACLK | COL_SPECTRUM,
|
||||
0.100, 1, 0.050],
|
||||
[.500, ACT_WHEEL_ACLK | COL_SPECTRUM,
|
||||
0.125, 1, 0.060],
|
||||
[.500, ACT_WHEEL_CLKW | COL_SPECTRUM,
|
||||
0.125, 5, 0.050],
|
||||
[1, ACT_WHEEL_CLKW | COL_SPECTRUM,
|
||||
0.100, 10, 0.040],
|
||||
[1.5, ACT_WHEEL_CLKW | COL_SPECTRUM,
|
||||
0.075, 15, 0.030],
|
||||
[2, ACT_WHEEL_CLKW | COL_SPECTRUM,
|
||||
0.050, 20, 0.020],
|
||||
[2.5, ACT_WHEEL_CLKW | COL_SPECTRUM,
|
||||
0.025, 25, 0.010],
|
||||
[3, ACT_WHEEL_CLKW | COL_SPECTRUM,
|
||||
0.010, 30, 0.005],
|
||||
[5, ACT_SPARKLING_RING | COL_RANDOM, 0.010, 25, 1],
|
||||
[5, ACT_NOP, 0, 0, 0]
|
||||
]
|
||||
|
||||
|
||||
# pylint: disable=global-statement
|
||||
def nextspectrumcolor():
|
||||
global spectrum_part, color_idx, curr_color_granularity, color
|
||||
|
||||
|
||||
# spectral wipe from green to red
|
||||
if (spectrum_part == 2):
|
||||
if spectrum_part == 2:
|
||||
color = (color_idx, 0, 255-color_idx)
|
||||
color_idx += curr_color_granularity
|
||||
if (color_idx > 255):
|
||||
if color_idx > 255:
|
||||
spectrum_part = 0
|
||||
color_idx = 0
|
||||
|
||||
# spectral wipe from blue to green
|
||||
elif (spectrum_part == 1):
|
||||
elif spectrum_part == 1:
|
||||
color = (0, 255 - color_idx, color_idx)
|
||||
color_idx += curr_color_granularity
|
||||
if (color_idx > 255):
|
||||
if color_idx > 255:
|
||||
spectrum_part = 2
|
||||
color_idx = 0
|
||||
|
||||
# spectral wipe from red to blue
|
||||
elif (spectrum_part == 0 ):
|
||||
elif spectrum_part == 0:
|
||||
color = (255 - color_idx, color_idx, 0)
|
||||
color_idx += curr_color_granularity
|
||||
if (color_idx > 255):
|
||||
if color_idx > 255:
|
||||
spectrum_part = 1
|
||||
color_idx = 0
|
||||
|
||||
|
||||
def nextrandomcolor():
|
||||
global color
|
||||
|
||||
# granularity = 1 --> [0 .. 255] * 1 --> 0,1,2,3 ... 255
|
||||
# granularity = 10 --> [0 .. 25] * 10 --> 0,10,20,30 ... 250
|
||||
# granularity = 100 --> [0 .. 2] * 100 --> 0,100, 200 (boaring...)
|
||||
random_red = random.randint(0, int (256 / curr_color_granularity))
|
||||
random_red = random.randint(0, int(256 / curr_color_granularity))
|
||||
random_red *= curr_color_granularity
|
||||
|
||||
random_green = random.randint(0, int (256 / curr_color_granularity))
|
||||
random_green = random.randint(0, int(256 / curr_color_granularity))
|
||||
random_green *= curr_color_granularity
|
||||
|
||||
random_blue = random.randint(0, int (256 / curr_color_granularity))
|
||||
random_blue = random.randint(0, int(256 / curr_color_granularity))
|
||||
random_blue *= curr_color_granularity
|
||||
|
||||
color = (random_red, random_green, random_blue)
|
||||
|
||||
|
||||
def nextcolor():
|
||||
# save some RAM for more animation actions
|
||||
if (curr_color_gen & COL_RANDOM):
|
||||
nextrandomcolor()
|
||||
else:
|
||||
if curr_color_gen & COL_RANDOM:
|
||||
nextrandomcolor()
|
||||
else:
|
||||
nextspectrumcolor()
|
||||
|
||||
def setup():
|
||||
|
||||
def setup():
|
||||
# fingers corssed, the seeding makes sense to really get random colors...
|
||||
apin = AnalogIn(analog_input)
|
||||
random.seed(apin.value)
|
||||
|
|
@ -187,53 +221,58 @@ def setup():
|
|||
# let's go!
|
||||
nextcolor()
|
||||
strip.write()
|
||||
|
||||
|
||||
|
||||
setup()
|
||||
|
||||
while True: # Loop forever...
|
||||
|
||||
# do we need to load the next action?
|
||||
if ( (time.monotonic() - action_timer) > curr_action_duration ):
|
||||
curr_action_duration = theactionlist[curr_action_idx][action_duration]
|
||||
curr_action = theactionlist[curr_action_idx][action_and_color_gen] & 0x3F
|
||||
curr_action_step_duration = theactionlist[curr_action_idx][action_step_duration]
|
||||
curr_color_gen = theactionlist[curr_action_idx][action_and_color_gen] & 0xC0
|
||||
curr_color_granularity = theactionlist[curr_action_idx][color_granularity]
|
||||
curr_color_interval = theactionlist[curr_action_idx][color_interval]
|
||||
if (time.monotonic() - action_timer) > curr_action_duration:
|
||||
current_action = theactionlist[curr_action_idx]
|
||||
|
||||
curr_action_duration = current_action[action_duration]
|
||||
curr_action = current_action[action_and_color_gen] & 0x3F
|
||||
curr_action_step_duration = current_action[action_step_duration]
|
||||
curr_color_gen = current_action[action_and_color_gen] & 0xC0
|
||||
curr_color_granularity = current_action[color_granularity]
|
||||
curr_color_interval = current_action[color_interval]
|
||||
curr_action_idx += 1
|
||||
|
||||
# take care to rotate the action list!
|
||||
curr_action_idx %= number_of_actions
|
||||
action_timer = time.monotonic()
|
||||
|
||||
action_timer = time.monotonic()
|
||||
|
||||
# do we need to change to the next color?
|
||||
if ((time.monotonic() - color_timer) > curr_color_interval):
|
||||
if (time.monotonic() - color_timer) > curr_color_interval:
|
||||
nextcolor()
|
||||
color_timer = time.monotonic()
|
||||
color_timer = time.monotonic()
|
||||
|
||||
# do we need to step up the current action?
|
||||
if ((time.monotonic() - action_step_timer) > curr_action_step_duration):
|
||||
if (time.monotonic() - action_step_timer) > curr_action_step_duration:
|
||||
|
||||
if (curr_action):
|
||||
if curr_action:
|
||||
|
||||
if (curr_action == ACT_NOP):
|
||||
is_act_cycling = (ACT_CYCLING_RING_ACLK or ACT_CYCLING_RING_CLKW)
|
||||
|
||||
if curr_action == ACT_NOP:
|
||||
# rather trivial even tho this will be repeated as long as the
|
||||
# NOP continues - i could have prevented it from repeating
|
||||
# unnecessarily, but that would mean more code and less
|
||||
# space for more actions within the animation
|
||||
for i in range(0, numpix):
|
||||
strip[i] = (0,0,0)
|
||||
strip[i] = (0, 0, 0)
|
||||
|
||||
elif (curr_action == ACT_SIMPLE_RING):
|
||||
elif curr_action == ACT_SIMPLE_RING:
|
||||
# even more trivial - just set the new color, if there is one
|
||||
for i in range(0, numpix):
|
||||
strip[i] = color
|
||||
|
||||
elif ( curr_action == (ACT_CYCLING_RING_ACLK or ACT_CYCLING_RING_CLKW)):
|
||||
elif curr_action == is_act_cycling:
|
||||
# spin the ring clockwise or anti clockwise
|
||||
if (curr_action == ACT_CYCLING_RING_ACLK):
|
||||
if curr_action == ACT_CYCLING_RING_ACLK:
|
||||
idx += 1
|
||||
else:
|
||||
else:
|
||||
idx -= 1
|
||||
|
||||
# prevent overflows or underflows
|
||||
|
|
@ -242,27 +281,27 @@ while True: # Loop forever...
|
|||
# set the new color, if there is one
|
||||
strip[idx] = color
|
||||
|
||||
elif (curr_action == ACT_WHEEL_ACLK or ACT_WHEEL_CLKW):
|
||||
elif curr_action == ACT_WHEEL_ACLK or ACT_WHEEL_CLKW:
|
||||
# switch on / off the appropriate pixels according to
|
||||
# the current offset
|
||||
for idx in range(0, numpix):
|
||||
if ( ((offset + idx) & 7 ) < 2 ):
|
||||
if ((offset + idx) & 7) < 2:
|
||||
strip[idx] = color
|
||||
else:
|
||||
strip[idx] = (0,0,0)
|
||||
strip[idx] = (0, 0, 0)
|
||||
|
||||
# advance the offset and thus, spin the wheel
|
||||
if (curr_action == ACT_WHEEL_CLKW):
|
||||
if curr_action == ACT_WHEEL_CLKW:
|
||||
offset += 1
|
||||
else:
|
||||
else:
|
||||
offset -= 1
|
||||
|
||||
# prevent overflows or underflows
|
||||
offset %= numpix
|
||||
|
||||
elif (curr_action == ACT_SPARKLING_RING):
|
||||
|
||||
elif curr_action == ACT_SPARKLING_RING:
|
||||
# switch current pixel off
|
||||
strip[idx] = (0,0,0)
|
||||
strip[idx] = (0, 0, 0)
|
||||
# pick a new pixel
|
||||
idx = random.randint(0, numpix)
|
||||
# set new pixel to the current color
|
||||
|
|
|
|||
0
3D_Printed_Unicorn_Horn/.gemma.test
Normal file
0
3D_Printed_Unicorn_Horn/.gemma.test
Normal file
|
|
@ -1,8 +1,9 @@
|
|||
from digitalio import DigitalInOut, Direction
|
||||
import board
|
||||
import neopixel
|
||||
import time
|
||||
|
||||
import board
|
||||
import neopixel
|
||||
from digitalio import DigitalInOut, Direction
|
||||
|
||||
pixpin = board.D1
|
||||
numpix = 8
|
||||
|
||||
|
|
@ -11,32 +12,37 @@ led.direction = Direction.OUTPUT
|
|||
|
||||
strip = neopixel.NeoPixel(pixpin, numpix, brightness=1, auto_write=True)
|
||||
|
||||
|
||||
def wheel(pos):
|
||||
# Input a value 0 to 255 to get a color value.
|
||||
# The colours are a transition r - g - b - back to r.
|
||||
if (pos < 0) or (pos > 255):
|
||||
return (0, 0, 0)
|
||||
if (pos < 85):
|
||||
if pos < 85:
|
||||
return (int(pos * 3), int(255 - (pos*3)), 0)
|
||||
elif (pos < 170):
|
||||
elif pos < 170:
|
||||
pos -= 85
|
||||
return (int(255 - pos*3), 0, int(pos*3))
|
||||
return (int(255 - pos * 3), 0, int(pos * 3))
|
||||
else:
|
||||
pos -= 170
|
||||
return (0, int(pos*3), int(255 - pos*3))
|
||||
return (0, int(pos * 3), int(255 - pos * 3))
|
||||
|
||||
|
||||
def rainbow_cycle(wait):
|
||||
for j in range(255*5):
|
||||
for j in range(255 * 5):
|
||||
for i in range(len(strip)):
|
||||
idx = int ((i * 256 / len(strip)) + j)
|
||||
idx = int((i * 256 / len(strip)) + j)
|
||||
strip[i] = wheel(idx & 255)
|
||||
time.sleep(wait)
|
||||
|
||||
|
||||
def rainbow(wait):
|
||||
for j in range(255):
|
||||
for i in range(len(strip)):
|
||||
idx = int (i+j)
|
||||
idx = int(i + j)
|
||||
strip[i] = wheel(idx & 255)
|
||||
time.sleep(wait)
|
||||
|
||||
|
||||
while True:
|
||||
rainbow_cycle(0.05)
|
||||
|
|
|
|||
BIN
ABC_Soundboards_for_NeoTrellis/animals/01.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/01.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/02.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/02.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/03.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/03.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/04.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/04.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/05.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/05.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/06.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/06.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/A.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/A.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/B.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/B.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/C.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/C.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/D.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/D.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/E.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/E.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/F.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/F.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/G.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/G.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/H.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/H.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/I.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/I.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/J.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/J.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/K.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/K.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/L.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/L.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/M.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/M.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/N.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/N.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/O.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/O.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/P.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/P.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/Q.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/Q.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/R.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/R.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/S.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/S.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/T.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/T.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/U.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/U.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/V.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/V.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/W.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/W.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/X.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/X.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/Y.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/Y.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/animals/Z.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/animals/Z.wav
Normal file
Binary file not shown.
189
ABC_Soundboards_for_NeoTrellis/code.py
Normal file
189
ABC_Soundboards_for_NeoTrellis/code.py
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
# Talking A, B, Cs Soundboards: Animal ABCs and "E is for Electronics" ABCs
|
||||
|
||||
import time
|
||||
import board
|
||||
import audioio
|
||||
import adafruit_fancyled.adafruit_fancyled as fancy
|
||||
import adafruit_trellism4
|
||||
|
||||
# Custom colors for keys
|
||||
RED = 0xFF0000
|
||||
MAROON = 0xFF0044
|
||||
ORANGE = 0xFF6600
|
||||
YELLOW = 0xFFFF00
|
||||
BROWN = 0x8B4513
|
||||
GREEN = 0x008000
|
||||
AQUA = 0x33ff33
|
||||
TEAL = 0x66ffff
|
||||
BLUE = 0x0000FF
|
||||
NAVY = 0x24248f
|
||||
PURPLE = 0x660066
|
||||
PINK = 0xFF66B3
|
||||
WHITE = 0xFFFFFF
|
||||
EXTRA = 0x888888
|
||||
|
||||
# Select the folder for the ABC files, only define one,
|
||||
# the other line should have a # to comment it out
|
||||
#SAMPLE_FOLDER = "/animals/"
|
||||
SAMPLE_FOLDER = "/electronics/"
|
||||
|
||||
# This soundboard can select up to *32* sound clips! each one has a filename
|
||||
# which will be inside the SAMPLE_FOLDER above, and a *color* in a tuple ()
|
||||
SAMPLES = [("A.wav", RED),
|
||||
("B.wav", MAROON),
|
||||
("C.wav", ORANGE),
|
||||
("D.wav", YELLOW),
|
||||
("E.wav", BROWN),
|
||||
("F.wav", GREEN),
|
||||
("G.wav", AQUA),
|
||||
("H.wav", TEAL),
|
||||
("I.wav", BLUE),
|
||||
("J.wav", NAVY),
|
||||
("K.wav", PURPLE),
|
||||
("L.wav", PINK),
|
||||
("M.wav", RED),
|
||||
("N.wav", MAROON),
|
||||
("O.wav", ORANGE),
|
||||
("P.wav", YELLOW),
|
||||
("Q.wav", BROWN),
|
||||
("R.wav", GREEN),
|
||||
("S.wav", AQUA),
|
||||
("T.wav", TEAL),
|
||||
("U.wav", BLUE),
|
||||
("V.wav", NAVY),
|
||||
("W.wav", PURPLE),
|
||||
("X.wav", PINK),
|
||||
("Y.wav", RED),
|
||||
("Z.wav", MAROON),
|
||||
("01.wav", EXTRA), # Keys beyond the 26 alphabetic keys
|
||||
("02.wav", EXTRA),
|
||||
("03.wav", EXTRA),
|
||||
("04.wav", EXTRA),
|
||||
("05.wav", EXTRA),
|
||||
("06.wav", EXTRA)]
|
||||
|
||||
# For the intro, pick any number of colors to make a fancy gradient!
|
||||
INTRO_SWIRL = [RED, GREEN, BLUE]
|
||||
# The color for the pressed key
|
||||
SELECTED_COLOR = 0x333300
|
||||
|
||||
PLAY_SAMPLES_ON_START = False # Will not play all the sounds on start
|
||||
|
||||
# Our keypad + NeoPixel driver
|
||||
trellis = adafruit_trellism4.TrellisM4Express(rotation=0)
|
||||
|
||||
# Play the welcome wav (if its there)
|
||||
with audioio.AudioOut(board.A1, right_channel=board.A0) as audio:
|
||||
try:
|
||||
f = open(SAMPLE_FOLDER+SAMPLES[27][0], "rb") # Use 02.wav as welcome
|
||||
wave = audioio.WaveFile(f)
|
||||
audio.play(wave)
|
||||
swirl = 0 # we'll swirl through the colors in the gradient
|
||||
while audio.playing:
|
||||
for i in range(32):
|
||||
palette_index = ((swirl+i) % 32) / 32
|
||||
color = fancy.palette_lookup(INTRO_SWIRL, palette_index)
|
||||
# display it!
|
||||
trellis.pixels[(i%8, i//8)] = color.pack()
|
||||
swirl += 1
|
||||
time.sleep(0.005)
|
||||
f.close()
|
||||
# just hold a moment
|
||||
time.sleep(0.5)
|
||||
except OSError:
|
||||
# no biggie, they could have deleted it
|
||||
pass
|
||||
|
||||
# Parse the first file to figure out what format it's in
|
||||
channel_count = None
|
||||
bits_per_sample = None
|
||||
sample_rate = None
|
||||
with open(SAMPLE_FOLDER+SAMPLES[0][0], "rb") as f:
|
||||
wav = audioio.WaveFile(f)
|
||||
print("%d channels, %d bits per sample, %d Hz sample rate " %
|
||||
(wav.channel_count, wav.bits_per_sample, wav.sample_rate))
|
||||
|
||||
# Audio playback object - we'll go with either mono or stereo depending on
|
||||
# what we see in the first file
|
||||
if wav.channel_count == 1:
|
||||
audio = audioio.AudioOut(board.A1)
|
||||
elif wav.channel_count == 2:
|
||||
audio = audioio.AudioOut(board.A1, right_channel=board.A0)
|
||||
else:
|
||||
raise RuntimeError("Must be mono or stereo waves!")
|
||||
|
||||
# Turn on, maybe play all of the buttons
|
||||
for i, v in enumerate(SAMPLES):
|
||||
filename = SAMPLE_FOLDER+v[0]
|
||||
try:
|
||||
with open(filename, "rb") as f:
|
||||
wav = audioio.WaveFile(f)
|
||||
print(filename,
|
||||
"%d channels, %d bits per sample, %d Hz sample rate " %
|
||||
(wav.channel_count, wav.bits_per_sample, wav.sample_rate))
|
||||
if wav.channel_count != channel_count:
|
||||
pass
|
||||
if wav.bits_per_sample != bits_per_sample:
|
||||
pass
|
||||
if wav.sample_rate != sample_rate:
|
||||
pass
|
||||
trellis.pixels[(i%8, i//8)] = v[1]
|
||||
if PLAY_SAMPLES_ON_START:
|
||||
audio.play(wav)
|
||||
while audio.playing:
|
||||
pass
|
||||
except OSError:
|
||||
# File not found! skip to next
|
||||
pass
|
||||
|
||||
def stop_playing_sample(playback_details):
|
||||
print("playing: ", playback_details)
|
||||
audio.stop()
|
||||
trellis.pixels[playback_details['neopixel_location']] = playback_details['neopixel_color']
|
||||
playback_details['file'].close()
|
||||
playback_details['voice'] = None
|
||||
|
||||
current_press = set()
|
||||
currently_playing = {'voice' : None}
|
||||
last_samplenum = None
|
||||
while True:
|
||||
pressed = set(trellis.pressed_keys)
|
||||
# if pressed:
|
||||
# print("Pressed:", pressed)
|
||||
|
||||
just_pressed = pressed - current_press
|
||||
just_released = current_press - pressed
|
||||
|
||||
# if just_pressed:
|
||||
# print("Just pressed", just_pressed)
|
||||
for down in just_pressed:
|
||||
sample_num = down[1]*8 + down[0]
|
||||
print(sample_num)
|
||||
try:
|
||||
filename = SAMPLE_FOLDER+SAMPLES[sample_num][0]
|
||||
f = open(filename, "rb")
|
||||
wav = audioio.WaveFile(f)
|
||||
|
||||
# is something else playing? interrupt it!
|
||||
if currently_playing['voice'] != None:
|
||||
print("Interrupt")
|
||||
stop_playing_sample(currently_playing)
|
||||
|
||||
trellis.pixels[down] = SELECTED_COLOR
|
||||
audio.play(wav)
|
||||
# voice, neopixel tuple, color, and sample, file handle
|
||||
currently_playing = {
|
||||
'voice': 0,
|
||||
'neopixel_location': down,
|
||||
'neopixel_color': SAMPLES[sample_num][1],
|
||||
'sample_num': sample_num,
|
||||
'file': f}
|
||||
except OSError:
|
||||
pass # File not found! skip to next
|
||||
|
||||
# check if any samples are done
|
||||
if not audio.playing and currently_playing['voice'] != None:
|
||||
stop_playing_sample(currently_playing)
|
||||
|
||||
time.sleep(0.01) # a little delay here helps avoid debounce annoyances
|
||||
current_press = pressed
|
||||
BIN
ABC_Soundboards_for_NeoTrellis/electronics/01.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/01.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/02.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/02.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/03.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/03.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/04.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/04.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/05.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/05.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/06.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/06.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/A.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/A.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/B.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/B.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/C.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/C.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/D.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/D.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/E.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/E.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/F.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/F.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/G.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/G.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/H.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/H.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/I.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/I.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/J.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/J.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/K.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/K.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/L.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/L.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/M.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/M.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/N.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/N.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/O.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/O.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/P.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/P.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/Q.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/Q.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/R.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/R.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/S.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/S.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/T.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/T.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/U.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/U.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/V.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/V.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/W.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/W.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/X.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/X.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/Y.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/Y.wav
Normal file
Binary file not shown.
BIN
ABC_Soundboards_for_NeoTrellis/electronics/Z.wav
Normal file
BIN
ABC_Soundboards_for_NeoTrellis/electronics/Z.wav
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue