re-add deleted files

This commit is contained in:
lady ada 2020-12-02 12:18:44 -05:00
parent 2226008a1f
commit d08cd1718c
8 changed files with 682 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

View file

@ -0,0 +1,106 @@
import time
import board
import neopixel
pixel_count = 6 # Number of NeoPixels
pixel_pin = board.D1 # Pin where NeoPixels are connected
speed = .1 # Animation speed (in seconds).
# This is how long to spend in a single animation frame.
# Higher values are slower.
# Good values to try are 400, 200, 100, 50, 25, etc.
animation = 0 # Type of animation, can be one of these values:
# 0 - Solid color pulse
# 1 - Moving color pulse
color_steps = 8 # Number of steps in the animation.
brightness = 1.0 # 0-1, higher number is brighter
# Adjacent colors (on color wheel).
# red yellow
color_animation = ([255, 0, 0], [255, 36, 0], [255, 72, 0], [255, 109, 0],
[255, 145, 0], [255, 182, 0], [255, 218, 0], [255, 255, 0])
# Adjacent colors
#([255, 0, 0], [255, 36, 0], [255, 72, 0], [255, 109, 0],
# [255, 145, 0], [255, 182, 0], [255, 218, 0], [255, 255, 0]) # red yellow
#([255, 255, 0], [218, 255, 0], [182, 255, 0], [145, 255, 0],
# [109, 255, 0], [72, 255, 0], [36, 255, 0], [0, 255, 0]) # yello green
#([0, 255, 0], [0, 255, 36], [0, 255, 72], [0, 255, 109],
# [0, 255, 145], [0, 255, 182], [0, 255, 218], [0, 255, 255]) # green cyan
#([0, 255, 255], [0, 218, 255], [0, 182, 255], [0, 145, 255],
# [0, 109, 255], [0, 72, 255], [0, 36, 255], [0, 0, 255]) # cyan blue
#([0, 0, 255], [36, 0, 255], [72, 0, 255], [109, 0, 255],
# [145, 0, 255], [182, 0, 255], [218, 0, 255], [255, 0, 255]) # blue magenta
#([255, 0, 255], [255, 0, 218], [255, 0, 182], [255, 0, 145],
# [255, 0, 109], [255, 0, 72], [255, 0, 36], [255, 0, 0]) # magenta red
# Complimentary colors
#([255, 0, 0], [218, 36, 36], [182, 72, 72], [145, 109, 109],
# [109, 145, 145], [72, 182, 182], [36, 218, 218], [0, 255, 255]) # red cyan
#([255, 255, 0], [218, 218, 36], [182, 182, 72], [145, 145, 109],
# [109, 109, 145], [72, 72, 182], [36, 36, 218], [0, 0, 255]) # yellow blue
#([0, 255, 0], [36, 218, 36], [72, 182, 72], [109, 145, 109],
# [145, 109, 145], [182, 72, 182], [218, 36, 218], [255, 0, 255]) # green magenta
# Other combos
#([255, 0, 0], [218, 36, 0], [182, 72, 0], [145, 109, 0],
# [109, 145, 0], [72, 182, 0], [36, 218, 0], [0, 255, 0]) # red green
#([255, 255, 0], [218, 255, 36], [182, 255, 72], [145, 255, 109],
# [109, 255, 145], [72, 255, 182], [36, 255, 218], [0, 255, 255]) # yellow cyan
#([0, 255, 0], [0, 218, 36], [0, 182, 72], [0, 145, 109],
# [0, 109, 145], [0, 72, 182], [0, 36, 218], [0, 0, 255]) # green blue
#([0, 255, 255], [36, 218, 255], [72, 182, 255], [109, 145, 255],
# [145, 109, 255], [182, 72, 255], [218, 36, 255], [255, 0, 255]) # cyan magenta
#([0, 0, 255], [36, 0, 218], [72, 0, 182], [109, 0, 145],
# [145, 0, 109], [182, 0, 72], [218, 0, 36], [255, 0, 0]) # blue red
#([255, 0, 255], [255, 36, 218], [255, 72, 182], [255, 109, 145],
# [255, 145, 109], [255, 182, 72], [255, 218, 36], [255, 255, 0]) # magenta yellow
# Solid colors fading to dark
#([255, 0, 0], [223, 0, 0], [191, 0, 0], [159, 0, 0],
# [127, 0, 0], [95, 0, 0], [63, 0, 0], [31, 0, 0]) # red
#([255, 153, 0], [223, 133, 0], [191, 114, 0], [159, 95, 0],
# [127, 76, 0], [95, 57, 0], [63, 38, 0], [31, 19, 0]) # orange
#([255, 255, 0], [223, 223, 0], [191, 191, 0], [159, 159, 0],
# [127, 127, 0], [95, 95, 0], [63, 63, 0], [31, 31, 0]) # yellow
#([0, 255, 0], [0, 223, 0], [0, 191, 0], [0, 159, 0],
# [0, 127, 0], [0, 95, 0], [0, 63, 0], [0, 31, 0]) # green
#([0, 0, 255], [0, 0, 223], [0, 0, 191], [0, 0, 159],
# [0, 0, 127], [0, 0, 95], [0, 0, 63], [0, 0, 31]) # blue
#([75, 0, 130], [65, 0, 113], [56, 0, 97], [46, 0, 81],
# [37, 0, 65], [28, 0, 48], [18, 0, 32], [9, 0, 16]) # indigo
#([139, 0, 255], [121, 0, 223], [104, 0, 191], [86, 0, 159],
# [69, 0, 127], [52, 0, 95], [34, 0, 63], [17, 0, 31]) # violet
#([255, 255, 255], [223, 223, 223], [191, 191, 191], [159, 159, 159],
# [127, 127, 127], [95, 95, 95], [63, 63, 63], [31, 31, 31]) # white
#([255, 0, 0], [255, 153, 0], [255, 255, 0], [0, 255, 0],
# [0, 0, 255], [75, 0, 130], [139, 0, 255], [255, 255, 255]) # rainbow colors
# Global state used by the sketch
strip = neopixel.NeoPixel(pixel_pin, pixel_count, brightness=1, auto_write=False)
while True: # Loop forever...
# Main loop will update all the pixels based on the animation.
for i in range(pixel_count):
# Animation 0, solid color pulse of all pixels.
if animation == 0:
current_step = (time.monotonic() / speed) % (color_steps * 2 - 2)
if current_step >= color_steps:
current_step = color_steps - (current_step - (color_steps - 2))
# Animation 1, moving color pulse. Use position to change brightness.
elif animation == 1:
current_step = (time.monotonic() / speed + i) % (color_steps * 2 - 2)
if current_step >= color_steps:
current_step = color_steps - (current_step - (color_steps - 2))
strip[i] = color_animation[int(current_step)]
# Show the updated pixels.
strip.show()

View file

@ -0,0 +1,111 @@
// Techno-Tiki RGB LED Torch (without IR Remote Control)
// Created by Tony DiCola
//
// See guide at: https://learn.adafruit.com/techno-tiki-rgb-led-torch/overview
//
// Released under a MIT license: http://opensource.org/licenses/MIT
#include <Adafruit_NeoPixel.h>
// Sketch configuration:
#define PIXEL_PIN 1 // Pin connected to the NeoPixel strip.
#define PIXEL_COUNT 6 // Number of NeoPixels.
#define PIXEL_TYPE NEO_GRB + NEO_KHZ800 // Type of NeoPixel. Keep this the default
// if unsure. See the NeoPixel library examples
// for more explanation and other possible values.
#define SPEED_MS 100 // Animation speed (in milliseconds). This is how
// long to spend in a single animation frame. Higher
// values are slower. Good values to try are 400, 200,
// 100, 50, 25, etc.
#define ANIMATION 0 // Type of animation, can be one of these values:
// 0 - Solid color pulse
// 1 - Moving color pulse
// Color animation values. Each value is a 24-bit RGB color value that will be displayed
// at that current step in the animation. Make sure only ONE row is uncommented below!
const int colorSteps = 8; // Number of steps in the animation.
const uint32_t colorAnimation[colorSteps] PROGMEM =
// Complimentary colors
//{ 0xFF0000, 0xDA2424, 0xB64848, 0x916D6D, 0x6D9191, 0x48B6B6, 0x24DADA, 0x00FFFF }; // Red-cyan
//{ 0xFFFF00, 0xDADA24, 0xB6B648, 0x91916D, 0x6D6D91, 0x4848B6, 0x2424DA, 0x0000FF }; // Yellow-blue
//{ 0x00FF00, 0x24DA24, 0x48B648, 0x6D916D, 0x916D91, 0xB648B6, 0xDA24DA, 0xFF00FF }; // Green-magenta
// Adjacent colors (on color wheel).
{ 0xFF0000, 0xFF2400, 0xFF4800, 0xFF6D00, 0xFF9100, 0xFFB600, 0xFFDA00, 0xFFFF00 }; // Red-yellow
//{ 0xFFFF00, 0xDAFF00, 0xB6FF00, 0x91FF00, 0x6DFF00, 0x48FF00, 0x24FF00, 0x00FF00 }; // Yellow-green
//{ 0x00FF00, 0x00FF24, 0x00FF48, 0x00FF6D, 0x00FF91, 0x00FFB6, 0x00FFDA, 0x00FFFF }; // Green-cyan
//{ 0x00FFFF, 0x00DAFF, 0x00B6FF, 0x0091FF, 0x006DFF, 0x0048FF, 0x0024FF, 0x0000FF }; // Cyan-blue
//{ 0x0000FF, 0x2400FF, 0x4800FF, 0x6D00FF, 0x9100FF, 0xB600FF, 0xDA00FF, 0xFF00FF }; // Blue-magenta
//{ 0xFF00FF, 0xFF00DA, 0xFF00B6, 0xFF0091, 0xFF006D, 0xFF0048, 0xFF0024, 0xFF0000 }; // Magenta-red
// Other combos.
//{ 0xFF0000, 0xDA2400, 0xB64800, 0x916D00, 0x6D9100, 0x48B600, 0x24DA00, 0x00FF00 }; // Red-green
//{ 0xFFFF00, 0xDAFF24, 0xB6FF48, 0x91FF6D, 0x6DFF91, 0x48FFB6, 0x24FFDA, 0x00FFFF }; // Yellow-cyan
//{ 0x00FF00, 0x00DA24, 0x00B648, 0x00916D, 0x006D91, 0x0048B6, 0x0024DA, 0x0000FF }; // Green-blue
//{ 0x00FFFF, 0x24DAFF, 0x48B6FF, 0x6D91FF, 0x916DFF, 0xB648FF, 0xDA24FF, 0xFF00FF }; // Cyan-magenta
//{ 0x0000FF, 0x2400DA, 0x4800B6, 0x6D0091, 0x91006D, 0xB60048, 0xDA0024, 0xFF0000 }; // Blue-red
//{ 0xFF00FF, 0xFF24DA, 0xFF48B6, 0xFF6D91, 0xFF916D, 0xFFB648, 0xFFDA24, 0xFFFF00 }; // Magenta-yellow
// Solid colors fading to dark.
//{ 0xFF0000, 0xDF0000, 0xBF0000, 0x9F0000, 0x7F0000, 0x5F0000, 0x3F0000, 0x1F0000 }; // Red
//{ 0xFF9900, 0xDF8500, 0xBF7200, 0x9F5F00, 0x7F4C00, 0x5F3900, 0x3F2600, 0x1F1300 }; // Orange
//{ 0xFFFF00, 0xDFDF00, 0xBFBF00, 0x9F9F00, 0x7F7F00, 0x5F5F00, 0x3F3F00, 0x1F1F00 }; // Yellow
//{ 0x00FF00, 0x00DF00, 0x00BF00, 0x009F00, 0x007F00, 0x005F00, 0x003F00, 0x001F00 }; // Green
//{ 0x0000FF, 0x0000DF, 0x0000BF, 0x00009F, 0x00007F, 0x00005F, 0x00003F, 0x00001F }; // Blue
//{ 0x4B0082, 0x410071, 0x380061, 0x2E0051, 0x250041, 0x1C0030, 0x120020, 0x090010 }; // Indigo
//{ 0x8B00FF, 0x7900DF, 0x6800BF, 0x56009F, 0x45007F, 0x34005F, 0x22003F, 0x11001F }; // Violet
//{ 0xFFFFFF, 0xDFDFDF, 0xBFBFBF, 0x9F9F9F, 0x7F7F7F, 0x5F5F5F, 0x3F3F3F, 0x1F1F1F }; // White
// Rainbow colors.
//{ 0xFF0000, 0xFF9900, 0xFFFF00, 0x00FF00, 0x0000FF, 0x4B0082, 0x8B00FF, 0xFFFFFF };
// Global state used by the sketch:
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);
void setup(void) {
// Initialize and clear the NeoPixel strip.
strip.begin();
strip.clear();
strip.show(); // Initialize all pixels to 'off'
}
void loop(void) {
// Main loop will update all the pixels based on the animation.
for (int i = 0; i < PIXEL_COUNT; ++i) {
switch (ANIMATION) {
case 0:
{
// Animation 0, solid color pulse of all pixels.
uint8_t currentStep = (millis()/SPEED_MS)%(colorSteps*2-2);
if (currentStep >= colorSteps) {
currentStep = colorSteps-(currentStep-(colorSteps-2));
}
// Note that colors are stored in flash memory so they need to be read
// using the pgmspace.h functions.
uint32_t color = pgm_read_dword_near(&colorAnimation[currentStep]);
strip.setPixelColor(i, color);
break;
}
case 1:
{
// Animation 1, moving color pulse. Use position to change brightness.
uint8_t currentStep = (millis()/SPEED_MS+i)%(colorSteps*2-2);
if (currentStep >= colorSteps) {
currentStep = colorSteps-(currentStep-(colorSteps-2));
}
// Note that colors are stored in flash memory so they need to be read
// using the pgmspace.h functions.
uint32_t color = pgm_read_dword_near(&colorAnimation[currentStep]);
strip.setPixelColor(i, color);
break;
}
}
}
// Show the updated pixels.
strip.show();
}

View file

@ -0,0 +1,194 @@
# Techno-Tiki RGB LED Torch with IR Remote Control
# Created by Tony DiCola for Arduino
# Ported to CircuitPython by Mikey Sklar
#
# See guide at: https://learn.adafruit.com/techno-tiki-rgb-led-torch
#
# Released under a MIT license: http://opensource.org/licenses/MIT
import time
import board
import neopixel
import adafruit_irremote
import pulseio
# pylint: disable=global-statement
pixel_pin = board.D1 # Pin where NeoPixels are connected
pixel_count = 6 # Number of NeoPixels
speed = .1 # Animation speed (in seconds).
# This is how long to spend in a single animation frame.
# Higher values are slower.
# Good values to try are 400, 200, 100, 50, 25, etc.
animation = 1 # Type of animation, can be one of these values:
# 0 - Solid color pulse
# 1 - Moving color pulse
brightness = 1.0 # 0-1, higher number is brighter
ir_code_min = 60
ir_code_max = 70
pulsein = pulseio.PulseIn(board.D2, maxlen=100, idle_state=True)
decoder = adafruit_irremote.GenericDecode()
# Adafruit IR Remote Codes:
# Button Code Button Code
# ----------- ------ ------ -----
# VOL-: 255 0/10+: 207
# Play/Pause: 127 1: 247
# VOL+: 191 2: 119
# SETUP: 223 3: 183
# STOP/MODE: 159 4: 215
# UP: 95 5: 87
# DOWN: 79 6: 151
# LEFT: 239 7: 231
# RIGHT: 175 8: 103
# ENTER/SAVE: 111 9: 167
# Back: 143
color_change = 175 # Button that cycles through color animations.
animation_change = 239 # Button that cycles through animation types (only two supported).
speed_change = 95 # Button that cycles through speed choices.
power_off = 255 # Button that turns off the pixels.
power_on = 191 # Button that turns on the pixels. Must be pressed twice to register!
# Build lookup table/palette for the color animations so they aren't computed at runtime.
# The colorPalette two-dimensional array below has a row for each color animation and a column
# for each step within the animation. Each value is a 24-bit RGB color. By looping through
# the columns of a row the colors of pixels will animate.
color_steps = 8 # Number of steps in the animation.
color_count = 23 # number of columns/steps
color_palette = [
# Complimentary colors
([255, 0, 0], [218, 36, 36], [182, 72, 72], [145, 109, 109],
[109, 145, 145], [72, 182, 182], [36, 218, 218], [0, 255, 255]), # red cyan
([255, 255, 0], [218, 218, 36], [182, 182, 72], [145, 145, 109],
[109, 109, 145], [72, 72, 182], [36, 36, 218], [0, 0, 255]), # yellow blue
([0, 255, 0], [36, 218, 36], [72, 182, 72], [109, 145, 109],
[145, 109, 145], [182, 72, 182], [218, 36, 218], [255, 0, 255]), # green magenta
# Adjacent colors (on color wheel).
([255, 255, 0], [218, 255, 0], [182, 255, 0], [145, 255, 0],
[109, 255, 0], [72, 255, 0], [36, 255, 0], [0, 255, 0]), # yello green
([0, 255, 0], [0, 255, 36], [0, 255, 72], [0, 255, 109],
[0, 255, 145], [0, 255, 182], [0, 255, 218], [0, 255, 255]), # green cyan
([0, 255, 255], [0, 218, 255], [0, 182, 255], [0, 145, 255],
[0, 109, 255], [0, 72, 255], [0, 36, 255], [0, 0, 255]), # cyan blue
([0, 0, 255], [36, 0, 255], [72, 0, 255], [109, 0, 255],
[145, 0, 255], [182, 0, 255], [218, 0, 255], [255, 0, 255]), # blue magenta
([255, 0, 255], [255, 0, 218], [255, 0, 182], [255, 0, 145],
[255, 0, 109], [255, 0, 72], [255, 0, 36], [255, 0, 0]), # magenta red
# Other combos
([255, 0, 0], [218, 36, 0], [182, 72, 0], [145, 109, 0],
[109, 145, 0], [72, 182, 0], [36, 218, 0], [0, 255, 0]), # red green
([255, 255, 0], [218, 255, 36], [182, 255, 72], [145, 255, 109],
[109, 255, 145], [72, 255, 182], [36, 255, 218], [0, 255, 255]), # yellow cyan
([0, 255, 0], [0, 218, 36], [0, 182, 72], [0, 145, 109],
[0, 109, 145], [0, 72, 182], [0, 36, 218], [0, 0, 255]), # green blue
([0, 255, 255], [36, 218, 255], [72, 182, 255], [109, 145, 255],
[145, 109, 255], [182, 72, 255], [218, 36, 255], [255, 0, 255]), # cyan magenta
([0, 0, 255], [36, 0, 218], [72, 0, 182], [109, 0, 145],
[145, 0, 109], [182, 0, 72], [218, 0, 36], [255, 0, 0]), # blue red
([255, 0, 255], [255, 36, 218], [255, 72, 182], [255, 109, 145],
[255, 145, 109], [255, 182, 72], [255, 218, 36], [255, 255, 0]), # magenta yellow
# Solid colors fading to dark.
([255, 0, 0], [223, 0, 0], [191, 0, 0], [159, 0, 0],
[127, 0, 0], [95, 0, 0], [63, 0, 0], [31, 0, 0]), # red
([255, 153, 0], [223, 133, 0], [191, 114, 0], [159, 95, 0],
[127, 76, 0], [95, 57, 0], [63, 38, 0], [31, 19, 0]), # orange
([255, 255, 0], [223, 223, 0], [191, 191, 0], [159, 159, 0],
[127, 127, 0], [95, 95, 0], [63, 63, 0], [31, 31, 0]), # yellow
([0, 255, 0], [0, 223, 0], [0, 191, 0], [0, 159, 0],
[0, 127, 0], [0, 95, 0], [0, 63, 0], [0, 31, 0]), # green
([0, 0, 255], [0, 0, 223], [0, 0, 191], [0, 0, 159],
[0, 0, 127], [0, 0, 95], [0, 0, 63], [0, 0, 31]), # blue
([75, 0, 130], [65, 0, 113], [56, 0, 97], [46, 0, 81],
[37, 0, 65], [28, 0, 48], [18, 0, 32], [9, 0, 16]), # indigo
([139, 0, 255], [121, 0, 223], [104, 0, 191], [86, 0, 159],
[69, 0, 127], [52, 0, 95], [34, 0, 63], [17, 0, 31]), # violet
([255, 255, 255], [223, 223, 223], [191, 191, 191], [159, 159, 159],
[127, 127, 127], [95, 95, 95], [63, 63, 63], [31, 31, 31]), # white
([255, 0, 0], [255, 153, 0], [255, 255, 0], [0, 255, 0],
[0, 0, 255], [75, 0, 130], [139, 0, 255], [255, 255, 255]) # rainbow colors
]
# List of animations speeds (in seconds). This is how long an animation spends before
# changing to the next step. Higher values are slower.
speeds = [.4, .2, .1, .05, .025]
# Global state used by the sketch
strip = neopixel.NeoPixel(pixel_pin, pixel_count, brightness=brightness, auto_write=False)
color_index = 0
animation_index = 0
speed_index = 2
def read_NEC():
# Check if a NEC IR remote command is the correct length.
# Save the third decoded value as our unique identifier.
pulses = decoder.read_pulses(pulsein, max_pulse=5000)
command = None
try:
if len(pulses) >= ir_code_min and len(pulses) <= ir_code_max:
code = decoder.decode_bits(pulses)
if len(code) > 3:
command = code[2]
except adafruit_irremote.IRNECRepeatException: # Catches the repeat signal
pass
except adafruit_irremote.IRDecodeException: # Failed to decode
pass
return command
def handle_remote():
global color_index, animation_index, speed_index
ir_code = read_NEC()
if ir_code is None:
time.sleep(.1)
return
if ir_code == color_change:
color_index = (color_index + 1) % color_count
elif ir_code == animation_change:
animation_index = (animation_index + 1) % 2
elif ir_code == speed_change:
speed_index = (speed_index + 1) % 5
elif ir_code == power_off:
strip.fill([0, 0, 0])
strip.show()
while True: # Loop forever...
# Main loop will update all the pixels based on the animation.
for i in range(pixel_count):
# Animation 0, solid color pulse of all pixels.
if animation_index == 0:
current_step = (time.monotonic() / speeds[speed_index]) % (color_steps * 2 - 2)
if current_step >= color_steps:
current_step = color_steps - (current_step - (color_steps - 2))
# Animation 1, moving color pulse. Use position to change brightness.
elif animation == 1:
current_step = (time.monotonic() / speeds[speed_index] + i) % (color_steps * 2 - 2)
if current_step >= color_steps:
current_step = color_steps - (current_step - (color_steps - 2))
strip[i] = color_palette[int(color_index)][int(current_step)]
# Next check for any IR remote commands.
handle_remote()
# Show the updated pixels.
strip.show()
# Next check for any IR remote commands.
handle_remote()

View file

@ -0,0 +1,271 @@
// Techno-Tiki RGB LED Torch with IR Remote Control
// Created by Tony DiCola
//
// See guide at: https://learn.adafruit.com/techno-tiki-rgb-led-torch/overview
//
// Released under a MIT license: http://opensource.org/licenses/MIT
#include <avr/power.h>
#include <avr/sleep.h>
#include <Adafruit_NeoPixel.h>
// Sketch configuration:
#define PIXEL_PIN 1 // Pin connected to the NeoPixel strip.
#define PIXEL_COUNT 6 // Number of NeoPixels. At most only about 100 pixels
// can be used at a time before it will take too long
// to update the pixels and IR remote codes might be
// missed.
#define PIXEL_TYPE NEO_GRB + NEO_KHZ800 // Type of NeoPixel. Keep this the default
// if unsure. See the NeoPixel library examples
// for more explanation and other possible values.
#define IR_PIN 2 // Pin connected to the IR receiver.
// Adafruit IR Remote Codes:
// Button Code Button Code
// ----------- ------ ------ -----
// VOL-: 0x0000 0/10+: 0x000C
// Play/Pause: 0x0001 1: 0x0010
// VOL+: 0x0002 2: 0x0011
// SETUP: 0x0004 3: 0x0012
// STOP/MODE: 0x0006 4: 0x0014
// UP: 0x0005 5: 0x0015
// DOWN: 0x000D 6: 0x0016
// LEFT: 0x0008 7: 0x0018
// RIGHT: 0x000A 8: 0x0019
// ENTER/SAVE: 0x0009 9: 0x001A
// Back: 0x000E
#define COLOR_CHANGE 0x000A // Button that cycles through color animations.
#define ANIMATION_CHANGE 0x0008 // Button that cycles through animation types (only two supported).
#define SPEED_CHANGE 0x0005 // Button that cycles through speed choices.
#define POWER_OFF 0x0000 // Button that turns off/sleeps the pixels.
#define POWER_ON 0x0002 // Button that turns on the pixels. Must be pressed twice to register!
// Build lookup table/palette for the color animations so they aren't computed at runtime.
// The colorPalette two-dimensional array below has a row for each color animation and a column
// for each step within the animation. Each value is a 24-bit RGB color. By looping through
// the columns of a row the colors of pixels will animate.
const int colorSteps = 8; // Number of rows/animations.
const int colorCount = 24; // Number of columns/steps.
const uint32_t colorPalette[colorCount][colorSteps] PROGMEM = {
// Complimentary colors
{ 0xFF0000, 0xDA2424, 0xB64848, 0x916D6D, 0x6D9191, 0x48B6B6, 0x24DADA, 0x00FFFF }, // Red-cyan
{ 0xFFFF00, 0xDADA24, 0xB6B648, 0x91916D, 0x6D6D91, 0x4848B6, 0x2424DA, 0x0000FF }, // Yellow-blue
{ 0x00FF00, 0x24DA24, 0x48B648, 0x6D916D, 0x916D91, 0xB648B6, 0xDA24DA, 0xFF00FF }, // Green-magenta
// Adjacent colors (on color wheel).
{ 0xFF0000, 0xFF2400, 0xFF4800, 0xFF6D00, 0xFF9100, 0xFFB600, 0xFFDA00, 0xFFFF00 }, // Red-yellow
{ 0xFFFF00, 0xDAFF00, 0xB6FF00, 0x91FF00, 0x6DFF00, 0x48FF00, 0x24FF00, 0x00FF00 }, // Yellow-green
{ 0x00FF00, 0x00FF24, 0x00FF48, 0x00FF6D, 0x00FF91, 0x00FFB6, 0x00FFDA, 0x00FFFF }, // Green-cyan
{ 0x00FFFF, 0x00DAFF, 0x00B6FF, 0x0091FF, 0x006DFF, 0x0048FF, 0x0024FF, 0x0000FF }, // Cyan-blue
{ 0x0000FF, 0x2400FF, 0x4800FF, 0x6D00FF, 0x9100FF, 0xB600FF, 0xDA00FF, 0xFF00FF }, // Blue-magenta
{ 0xFF00FF, 0xFF00DA, 0xFF00B6, 0xFF0091, 0xFF006D, 0xFF0048, 0xFF0024, 0xFF0000 }, // Magenta-red
// Other combos.
{ 0xFF0000, 0xDA2400, 0xB64800, 0x916D00, 0x6D9100, 0x48B600, 0x24DA00, 0x00FF00 }, // Red-green
{ 0xFFFF00, 0xDAFF24, 0xB6FF48, 0x91FF6D, 0x6DFF91, 0x48FFB6, 0x24FFDA, 0x00FFFF }, // Yellow-cyan
{ 0x00FF00, 0x00DA24, 0x00B648, 0x00916D, 0x006D91, 0x0048B6, 0x0024DA, 0x0000FF }, // Green-blue
{ 0x00FFFF, 0x24DAFF, 0x48B6FF, 0x6D91FF, 0x916DFF, 0xB648FF, 0xDA24FF, 0xFF00FF }, // Cyan-magenta
{ 0x0000FF, 0x2400DA, 0x4800B6, 0x6D0091, 0x91006D, 0xB60048, 0xDA0024, 0xFF0000 }, // Blue-red
{ 0xFF00FF, 0xFF24DA, 0xFF48B6, 0xFF6D91, 0xFF916D, 0xFFB648, 0xFFDA24, 0xFFFF00 }, // Magenta-yellow
// Solid colors fading to dark.
{ 0xFF0000, 0xDF0000, 0xBF0000, 0x9F0000, 0x7F0000, 0x5F0000, 0x3F0000, 0x1F0000 }, // Red
{ 0xFF9900, 0xDF8500, 0xBF7200, 0x9F5F00, 0x7F4C00, 0x5F3900, 0x3F2600, 0x1F1300 }, // Orange
{ 0xFFFF00, 0xDFDF00, 0xBFBF00, 0x9F9F00, 0x7F7F00, 0x5F5F00, 0x3F3F00, 0x1F1F00 }, // Yellow
{ 0x00FF00, 0x00DF00, 0x00BF00, 0x009F00, 0x007F00, 0x005F00, 0x003F00, 0x001F00 }, // Green
{ 0x0000FF, 0x0000DF, 0x0000BF, 0x00009F, 0x00007F, 0x00005F, 0x00003F, 0x00001F }, // Blue
{ 0x4B0082, 0x410071, 0x380061, 0x2E0051, 0x250041, 0x1C0030, 0x120020, 0x090010 }, // Indigo
{ 0x8B00FF, 0x7900DF, 0x6800BF, 0x56009F, 0x45007F, 0x34005F, 0x22003F, 0x11001F }, // Violet
{ 0xFFFFFF, 0xDFDFDF, 0xBFBFBF, 0x9F9F9F, 0x7F7F7F, 0x5F5F5F, 0x3F3F3F, 0x1F1F1F }, // White
// Rainbow colors.
{ 0xFF0000, 0xFF9900, 0xFFFF00, 0x00FF00, 0x0000FF, 0x4B0082, 0x8B00FF, 0xFFFFFF }
};
// List of animations speeds (in milliseconds). This is how long an animation spends before
// changing to the next step. Higher values are slower.
const uint16_t speeds[5] = { 400, 200, 100, 50, 25 };
// Global state used by the sketch:
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);
volatile bool receiverFell = false;
uint8_t colorIndex = 0;
uint8_t animationIndex = 0;
uint8_t speedIndex = 2;
void setup(void) {
// Setup IR receiver pin as an input.
pinMode(IR_PIN, INPUT);
// Initialize and clear the NeoPixel strip.
strip.begin();
strip.clear();
strip.show(); // Initialize all pixels to 'off'
// Enable an interrupt that's called when the IR receiver pin signal falls
// from high to low. This indicates a remote control code being received.
attachInterrupt(0, receiverFalling, FALLING);
}
void loop(void) {
// Main loop will first update all the pixels based on the current animation.
for (int i = 0; i < PIXEL_COUNT; ++i) {
switch (animationIndex) {
case 0:
{
// Animation 0, solid color pulse of all pixels.
uint8_t currentStep = (millis()/speeds[speedIndex])%(colorSteps*2-2);
if (currentStep >= colorSteps) {
currentStep = colorSteps-(currentStep-(colorSteps-2));
}
// Note that colors are stored in flash memory so they need to be read
// using the pgmspace.h functions.
uint32_t color = pgm_read_dword_near(&colorPalette[colorIndex][currentStep]);
strip.setPixelColor(i, color);
break;
}
case 1:
{
// Animation 1, moving color pulse. Use position to change brightness.
uint8_t currentStep = (millis()/speeds[speedIndex]+i)%(colorSteps*2-2);
if (currentStep >= colorSteps) {
currentStep = colorSteps-(currentStep-(colorSteps-2));
}
// Note that colors are stored in flash memory so they need to be read
// using the pgmspace.h functions.
uint32_t color = pgm_read_dword_near(&colorPalette[colorIndex][currentStep]);
strip.setPixelColor(i, color);
break;
}
}
}
// Next check for any IR remote commands.
handleRemote();
// Show the updated pixels.
strip.show();
// Again check for IR remote commands.
handleRemote();
}
void receiverFalling() {
// Interrupt function that's called when the IR receiver pin falls from high to
// low and indicates the start of an IR command being received. Note that
// interrupts need to be very fast and perform as little processing as possible.
// This just sets a global variable which the main loop will periodically check
// and perform appropriate IR command decoding when necessary.
receiverFell = true;
}
bool readNEC(uint16_t* result) {
// Check if a NEC IR remote command can be read and decoded from the IR receiver.
// If the command is decoded then the result is stored in the provided pointer and
// true is returned. Otherwise if the command was not decoded then false is returned.
// First check that a falling signal was detected and start reading pulses.
if (!receiverFell) {
return false;
}
// Read the first pulse with a large timeout since it's 9ms long, then
// read subsequent pulses with a shorter 2ms timeout.
uint32_t durations[33];
durations[0] = pulseIn(IR_PIN, HIGH, 20000);
for (uint8_t i = 1; i < 33; ++i) {
durations[i] = pulseIn(IR_PIN, HIGH, 5000);
}
// Reset any state changed by the interrupt.
receiverFell = false;
// Check the received pulses are in a NEC format.
// First verify the initial pulse is around 4.5ms long.
if ((durations[0] < 4000) || (durations[1] > 5000)) {
return false;
}
// Now read the bits from subsequent pulses. Stop if any were a timeout (0 value).
uint8_t data[4] = {0};
for (uint8_t i=0; i<32; ++i) {
if (durations[1+i] == 0) {
return false; // Timeout
}
uint8_t b = durations[1+i] < 1000 ? 0 : 1;
data[i/8] |= b << (i%8);
}
// Verify bytes and their inverse match. Use the same two checks as the NEC IR remote
// library here: https://github.com/adafruit/Adafruit-NEC-remote-control-library
if ((data[0] == (~data[1] & 0xFF)) && (data[2] == (~data[3] & 0xFF))) {
*result = data[0] << 8 | data[2];
return true;
}
else if ((data[0] == 0) && (data[1] == 0xBF) && (data[2] == (~data[3] & 0xFF))) {
*result = data[2];
return true;
}
else {
// Something didn't match, fail!
return false;
}
}
void handleRemote() {
// Check if an IR remote code was received and perform the appropriate action.
// First read a code.
uint16_t irCode;
if (!readNEC(&irCode)) {
return;
}
switch(irCode) {
case COLOR_CHANGE:
// Color change command, increment the current color animation and wrap
// back to zero when past the end.
colorIndex = (colorIndex+1)%colorCount;
break;
case ANIMATION_CHANGE:
// Animation change command, increment the current animation type and wrap
// back to zero when past the end.
animationIndex = (animationIndex+1)%2;
break;
case SPEED_CHANGE:
// Speed change command, increment the current speed and wrap back to zero
// when past the end.
speedIndex = (speedIndex+1)%5;
break;
case POWER_OFF:
// Enter full power down sleep mode.
// First turn off the NeoPixels.
strip.clear();
strip.show();
while (true) {
// Next disable the current falling interrupt and enable a low value interrupt.
// This is required because the ATtiny85 can't wake from a falling interrupt
// and instead can only wake from a high or low value interrupt.
detachInterrupt(0);
attachInterrupt(0, receiverFalling, LOW);
// Now enter full power down sleep mode.
power_all_disable();
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_mode();
// Processor is currently asleep and will wake up when the IR receiver pin
// is at a low value (i.e. when a IR command is received).
// Sleep resumes here. When awake power everything back up.
power_all_enable();
// Re-enable the falling interrupt.
detachInterrupt(0);
attachInterrupt(0, receiverFalling, FALLING);
// Now wait up to 1 second for a second power on command to be received.
// This is necessary because the first power on command will wake up the CPU
// but happens a little too quickly to be reliably read.
for (int i=0; i<200; ++i) {
uint16_t irCode;
if ((readNEC(&irCode) == 1) && (irCode == POWER_ON)) {
// Second power on command was received, jump out of the power on loop and
// return to normal operation.
return;
}
delay(5);
}
// If no power on command was received within 1 second of awaking then the
// code will loop back to the top and go to sleep again.
}
}
}