Merge remote-tracking branch 'adafruit/master' into freq_gen
This commit is contained in:
commit
d6ea9560f8
6 changed files with 231 additions and 11 deletions
|
|
@ -16,15 +16,20 @@ import time
|
||||||
import busio
|
import busio
|
||||||
import board
|
import board
|
||||||
import adafruit_lis3dh
|
import adafruit_lis3dh
|
||||||
import simpleio
|
import pulseio
|
||||||
|
from adafruit_motor import servo
|
||||||
|
|
||||||
|
|
||||||
# Setup accelerometer
|
# Setup accelerometer
|
||||||
i2c = busio.I2C(board.ACCELEROMETER_SCL, board.ACCELEROMETER_SDA)
|
i2c = busio.I2C(board.ACCELEROMETER_SCL, board.ACCELEROMETER_SDA)
|
||||||
sensor = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x19)
|
sensor = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x19)
|
||||||
|
|
||||||
# Setup servos
|
# Setup servos
|
||||||
left_ear = simpleio.Servo(board.A1)
|
left_pwm = pulseio.PWMOut(board.A1, frequency=50)
|
||||||
right_ear = simpleio.Servo(board.A2)
|
right_pwm = pulseio.PWMOut(board.A2, frequency=50)
|
||||||
|
|
||||||
|
left_ear = servo.Servo(left_pwm)
|
||||||
|
right_ear = servo.Servo(right_pwm)
|
||||||
|
|
||||||
#initialize things
|
#initialize things
|
||||||
left_ear.angle = 0
|
left_ear.angle = 0
|
||||||
|
|
|
||||||
148
NeoPixel_Cyber_Falls_Wig/NeoPixel_Cyber_Falls_Wig.ino
Normal file
148
NeoPixel_Cyber_Falls_Wig/NeoPixel_Cyber_Falls_Wig.ino
Normal file
|
|
@ -0,0 +1,148 @@
|
||||||
|
// 'Cyber falls' sketch, adapted from code for Firewalker sneakers.
|
||||||
|
// Creates a fiery rain-like effect on multiple NeoPixel strips.
|
||||||
|
// Requires Adafruit Trinket and NeoPixel strips. Strip length is
|
||||||
|
// inherently limited by Trinket RAM and processing power; this is
|
||||||
|
// written for five 15-pixel strands, which are paired up per pin
|
||||||
|
// for ten 15-pixel strips total.
|
||||||
|
|
||||||
|
#include <Adafruit_NeoPixel.h>
|
||||||
|
#include <avr/power.h>
|
||||||
|
|
||||||
|
uint8_t gamma[] PROGMEM = { // Gamma correction table for LED brightness
|
||||||
|
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 };
|
||||||
|
|
||||||
|
#define STRIPLEN 15 // Length of LED strips
|
||||||
|
#define MAXDROPS 5 // Max concurrent 'raindrops'
|
||||||
|
#define N_STRIPS 5 // Connect strips to pins 0 to (N_STRIPS-1)
|
||||||
|
|
||||||
|
Adafruit_NeoPixel strip = Adafruit_NeoPixel(STRIPLEN, 0);
|
||||||
|
|
||||||
|
// Everything's declared volatile because state changes inside
|
||||||
|
// an interrupt routine.
|
||||||
|
volatile struct {
|
||||||
|
uint8_t strip;
|
||||||
|
int16_t pos;
|
||||||
|
uint8_t speed;
|
||||||
|
uint16_t brightness;
|
||||||
|
} drop[MAXDROPS];
|
||||||
|
volatile uint8_t
|
||||||
|
nDrops = 0, // Number of 'active' raindrops
|
||||||
|
prevStrip = 255; // Last selected strip
|
||||||
|
volatile uint16_t
|
||||||
|
countdown = 0; // Time to next raindrop
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
|
||||||
|
// Set up Timer/Counter1 for ~30 Hz interrupt
|
||||||
|
#if F_CPU == 16000000L
|
||||||
|
clock_prescale_set(clock_div_1);
|
||||||
|
TCCR1 = _BV(PWM1A) |_BV(CS13) | _BV(CS12); // 1:2048 prescale
|
||||||
|
#else
|
||||||
|
TCCR1 = _BV(PWM1A) |_BV(CS13) | _BV(CS11) | _BV(CS10); // 1:1024 prescale
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Turn strips off ASAP (must follow clock_prescale_set)
|
||||||
|
strip.begin();
|
||||||
|
for(uint8_t s=0; s<N_STRIPS; s++) {
|
||||||
|
strip.setPin(s);
|
||||||
|
strip.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finish timer/counter setup
|
||||||
|
OCR1C = 255; // ~30 Hz
|
||||||
|
GTCCR = 0; // No PWM out
|
||||||
|
TIMSK |= _BV(TOIE1); // Enable overflow interrupt
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() { } // Not used -- everything's in interrupt below
|
||||||
|
|
||||||
|
// A timer interrupt is used so that everything runs at regular
|
||||||
|
// intervals, regardless of current amount of motion.
|
||||||
|
ISR(TIMER1_OVF_vect) {
|
||||||
|
|
||||||
|
uint16_t mag[STRIPLEN];
|
||||||
|
uint8_t s, d, p, r, g, b;
|
||||||
|
int mx1, m, level;
|
||||||
|
|
||||||
|
if(countdown == 0) { // Time to launch new drop?
|
||||||
|
if(nDrops < MAXDROPS-1) { // Is there space for one in the list?
|
||||||
|
do {
|
||||||
|
s = random(N_STRIPS);
|
||||||
|
} while(s == prevStrip); // Don't repeat prior strip
|
||||||
|
drop[nDrops].strip = prevStrip = s;
|
||||||
|
drop[nDrops].pos = -32; // Start off top of strip
|
||||||
|
drop[nDrops].speed = 1 + random(3);
|
||||||
|
drop[nDrops].brightness = 250 + random(520);
|
||||||
|
nDrops++;
|
||||||
|
countdown = 9 + random(28); // Time to launch next one
|
||||||
|
}
|
||||||
|
} else countdown--;
|
||||||
|
|
||||||
|
|
||||||
|
for(s=0; s<N_STRIPS; s++) { // For each strip...
|
||||||
|
memset(mag, 0, sizeof(mag)); // Clear magnitude table
|
||||||
|
|
||||||
|
// Render active drops for this strip into magnitude table
|
||||||
|
for(d=0; d<nDrops; d++) {
|
||||||
|
if(drop[d].strip == s) {
|
||||||
|
for(p=0; p<STRIPLEN; p++) { // For each pixel...
|
||||||
|
mx1 = (p << 2) - drop[d].pos; // Position of LED along wave
|
||||||
|
if((mx1 <= 0) || (mx1 >= 32)) continue; // Out of range
|
||||||
|
if(mx1 > 24) { // Rising edge of wave; ramp up fast (2 px)
|
||||||
|
m = ((long)drop[d].brightness * (long)(32 - mx1)) >> 4;
|
||||||
|
} else { // Falling edge of wave; fade slow (6 px)
|
||||||
|
m = ((long)drop[d].brightness * (long)mx1) / 24;
|
||||||
|
}
|
||||||
|
mag[p] += m; // Accumulate result in magnitude buffer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remap magnitude table to RGB for strand
|
||||||
|
for(p=0; p<STRIPLEN; p++) { // For each pixel in strip
|
||||||
|
level = mag[p]; // Pixel magnitude (brightness)
|
||||||
|
if(level < 255) { // 0-254 = black to green-1
|
||||||
|
r = b = 0;
|
||||||
|
g = pgm_read_byte(&gamma[level]);
|
||||||
|
} else if(level < 510) { // 255-509 = green to yellow-1
|
||||||
|
r = pgm_read_byte(&gamma[level - 255]);
|
||||||
|
g = 255;
|
||||||
|
b = 0;
|
||||||
|
} else if(level < 765) { // 510-764 = yellow to white-1
|
||||||
|
r = g = 255;
|
||||||
|
b = pgm_read_byte(&gamma[level - 510]);
|
||||||
|
} else { // 765+ = white
|
||||||
|
r = g = b = 255;
|
||||||
|
}
|
||||||
|
strip.setPixelColor(p, r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
strip.setPin(s); // Select output pin
|
||||||
|
strip.show(); // Strips don't need to refresh in sync
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move 'active' drops
|
||||||
|
for(d=0; d<nDrops; d++) {
|
||||||
|
drop[d].pos += drop[d].speed;
|
||||||
|
if(drop[d].pos >= (STRIPLEN * 4)) { // Off end?
|
||||||
|
// Remove drop from list (move last one to this place)
|
||||||
|
memcpy((void *)&drop[d], (void *)&drop[nDrops-1], sizeof(drop[0]));
|
||||||
|
nDrops--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
57
NeoPixel_Cyber_Falls_Wig/NeoPixel_Cyber_Falls_Wig.py
Normal file
57
NeoPixel_Cyber_Falls_Wig/NeoPixel_Cyber_Falls_Wig.py
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
# 'Cyber falls' sketch
|
||||||
|
# Creates a fiery rain-like effect on multiple NeoPixel strips.
|
||||||
|
# Requires Adafruit Trinket and NeoPixel strips. Strip length is
|
||||||
|
# inherently limited by Trinket RAM and processing power; this is
|
||||||
|
# written for five 15-pixel strands, which are paired up per pin
|
||||||
|
# for ten 15-pixel strips total.
|
||||||
|
|
||||||
|
import time
|
||||||
|
import board
|
||||||
|
import neopixel
|
||||||
|
import adafruit_fancyled.adafruit_fancyled as fancy
|
||||||
|
|
||||||
|
num_leds = 15 # number of LEDs per strip
|
||||||
|
saturation = 255 # 0-255, 0 is pure white, 255 is fully saturated color
|
||||||
|
blend = True # color blending between palette indices
|
||||||
|
brightness = 0.5 # half brightness the range is 0.0 - 1.0
|
||||||
|
concurrent = 3 # number of LEDs on at a time
|
||||||
|
on_time = 0.04 # 0.04 seconds == 40 milliseconds
|
||||||
|
|
||||||
|
# NeoPixel objects using all five Trinket M0 GPIO pins 0-4
|
||||||
|
drop0 = neopixel.NeoPixel(board.D0, num_leds)
|
||||||
|
drop1 = neopixel.NeoPixel(board.D1, num_leds)
|
||||||
|
drop2 = neopixel.NeoPixel(board.D2, num_leds)
|
||||||
|
drop3 = neopixel.NeoPixel(board.D3, num_leds)
|
||||||
|
drop4 = neopixel.NeoPixel(board.D4, num_leds)
|
||||||
|
|
||||||
|
# list of neopixel strips
|
||||||
|
drop_list = [drop0, drop1, drop2, drop3, drop4]
|
||||||
|
|
||||||
|
def led_drops(strip):
|
||||||
|
|
||||||
|
# FancyLED allows for mixing colors with palettes
|
||||||
|
palette = [fancy.CRGB(200, 255, 200), # lighter (more white) green
|
||||||
|
fancy.CRGB(0, 255, 0)] # full green
|
||||||
|
|
||||||
|
for i in range(num_leds):
|
||||||
|
# FancyLED can handle the gamma adjustment, brightness and RGB settings
|
||||||
|
color = fancy.palette_lookup(palette, i / num_leds)
|
||||||
|
color = fancy.gamma_adjust(color, brightness=brightness)
|
||||||
|
strip[i] = color.pack()
|
||||||
|
|
||||||
|
# turn off the LEDs as we go for raindrop effect
|
||||||
|
if i >= concurrent:
|
||||||
|
strip[i - concurrent] = (0,0,0)
|
||||||
|
|
||||||
|
if i >= num_leds - 1:
|
||||||
|
for j in range(concurrent,-1,-1):
|
||||||
|
strip[i-j] = (0,0,0)
|
||||||
|
time.sleep(on_time)
|
||||||
|
|
||||||
|
time.sleep(on_time)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
|
||||||
|
# loop through each neopixel strip in our list
|
||||||
|
for drops in drop_list:
|
||||||
|
led_drops(drops)
|
||||||
4
NeoPixel_Cyber_Falls_Wig/README.md
Normal file
4
NeoPixel_Cyber_Falls_Wig/README.md
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
# NeoPixel Cyber Falls Wig
|
||||||
|
|
||||||
|
Code to accompany this tutorial:
|
||||||
|
https://learn.adafruit.com/neopixel-cyber-falls
|
||||||
|
|
@ -17,7 +17,8 @@ import math
|
||||||
import array
|
import array
|
||||||
import board
|
import board
|
||||||
import audiobusio
|
import audiobusio
|
||||||
import simpleio
|
import pulseio
|
||||||
|
from adafruit_motor import servo
|
||||||
from adafruit_circuitplayground.express import cpx
|
from adafruit_circuitplayground.express import cpx
|
||||||
|
|
||||||
# Exponential scaling factor.
|
# Exponential scaling factor.
|
||||||
|
|
@ -30,9 +31,11 @@ NUM_SAMPLES = 90
|
||||||
|
|
||||||
# the trigger threshhold
|
# the trigger threshhold
|
||||||
THRESHOLD = 6
|
THRESHOLD = 6
|
||||||
|
left_pwm = pulseio.PWMOut(board.A1, frequency=50)
|
||||||
|
right_pwm = pulseio.PWMOut(board.A2, frequency=50)
|
||||||
|
|
||||||
left_ear = simpleio.Servo(board.A1)
|
left_ear = servo.Servo(left_pwm)
|
||||||
right_ear = simpleio.Servo(board.A2)
|
right_ear = servo.Servo(right_pwm)
|
||||||
|
|
||||||
cpx.pixels.fill((0, 0, 0))
|
cpx.pixels.fill((0, 0, 0))
|
||||||
left_ear.angle = 0
|
left_ear.angle = 0
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,19 @@
|
||||||
|
# Trinket Gemma Servo Control
|
||||||
|
# for Adafruit M0 boards
|
||||||
|
|
||||||
import board
|
import board
|
||||||
import simpleio
|
import pulseio
|
||||||
|
from adafruit_motor import servo
|
||||||
from analogio import AnalogIn
|
from analogio import AnalogIn
|
||||||
|
|
||||||
# servo pin for the M0 boards:
|
# servo pin for the M0 boards:
|
||||||
servo = simpleio.Servo(board.A2)
|
pwm = pulseio.PWMOut(board.A2, duty_cycle=2 ** 15, frequency=50)
|
||||||
|
my_servo = servo.Servo(pwm)
|
||||||
angle = 0
|
angle = 0
|
||||||
|
|
||||||
# potentiometer
|
# potentiometer
|
||||||
trimpot = AnalogIn(board.A1) # pot pin for servo control
|
trimpot = AnalogIn(board.A1) # pot pin for servo control
|
||||||
|
|
||||||
|
|
||||||
def remap_range(value, left_min, left_max, right_min, right_max):
|
def remap_range(value, left_min, left_max, right_min, right_max):
|
||||||
# this remaps a value from original (left) range to new (right) range
|
# this remaps a value from original (left) range to new (right) range
|
||||||
# Figure out how 'wide' each range is
|
# Figure out how 'wide' each range is
|
||||||
|
|
@ -25,5 +29,4 @@ def remap_range(value, left_min, left_max, right_min, right_max):
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
angle = remap_range(trimpot.value, 0, 65535, 0, 180)
|
angle = remap_range(trimpot.value, 0, 65535, 0, 180)
|
||||||
servo.angle = angle
|
my_servo.angle = angle
|
||||||
# time.sleep(0.05)
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue