Before you Start
If this is your first time using Pro Trinket, pause for a sec and head over to the Pro Trinket Intro guide. That will walk you through getting your Arduino IDE set up and the Adafruit boards installed. Once you can upload sample code to the Pro Trinket and everything appears to be working, come on back here.
FastLED Library
You will also need to install the FastLED library in Arduino (Sketch > Include Library > Manage Libraries...
)
Upload Code
This code is based on Mark Miller's sample beat8 code for the FastLED library. It creates a moving pixel with a comet tail that moves in a sinwave pattern around the neopixel strip.
When I press the button, the lights cycle through all the runes for a few seconds and then stop in a random spot, lighting up one (or sometimes two) of the layers of acrylic and highlighting a specific rune or "bound" rune combination (if it lands on a corner).
The lit pixels can be controlled for speed, brightness, hue, and fade rate (via the fading "comet tail" effect). The sinwave code "beatsin8" effectively mixes all these variables so that each button press gives me a totally unique experience -- one press, the pixels might cycle bright and fast, the next they cycle dim and slow, change colors quickly or subtly, or any of a vast number of combinations.
This makes for a feeling that the device is "listening" to the user and giving each button press due consideration before deciding on a message to relay.
// Viking Rune Artifact // by Erin St. Blaine // for Adafruit Industries // Based on code by Marc Miller, March 2017 // Full tutorial at https://learn.adafruit.com/glowing-viking-rune-artifact/introduction // Pro Trinket: https://www.adafruit.com/products/2000 // Skinny Neopixels: https://www.adafruit.com/products/2970 //*************************************************************** #include "FastLED.h" #define LED_TYPE WS2812 #define LED_PIN 3 #define BUTTON_PIN 4 #define BUTTON_LIGHT_PIN 5 #define NUM_LEDS 24 #define COLOR_ORDER GRB CRGB leds[NUM_LEDS]; uint8_t moveSpeed;// Random number for movement speed - higher number cycles faster uint8_t fadeRate; // Use lower value to give a fading tail. const uint16_t startDelay = 100; // Number of milliseconds before re-start int analogSeedPin = 9; // Any un-used analog pin. Used for generating seed for random16. int analogSeedPinB = 10; // Any un-used analog pin. Used for generating seed for random16. bool oldState = HIGH; static boolean frozen = true; // [Initially set true!] uint8_t gHue = 0; // Used to cycle through rainbow. uint8_t BRIGHTNESS = 200; unsigned long timeDelay = startDelay; unsigned long freezeTime = 10000000; // Just something really large to prevent triggering on startup //--------------------------------------------------------------- void setup() { Serial.begin(115200); // Allows serial monitor output (check baud rate) //delay(3000); // 3 second delay FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip); FastLED.setBrightness(BRIGHTNESS); pinMode(BUTTON_PIN, INPUT_PULLUP); pinMode(BUTTON_LIGHT_PIN, OUTPUT); digitalWrite(BUTTON_LIGHT_PIN, HIGH); // turn on pullup resistors// set pin to output } //--------------------------------------------------------------- void loop() { EVERY_N_MILLISECONDS(random(1,8)) { gHue++;} // Cycle through the rainbow randomly // Get current button state. bool newState = digitalRead(BUTTON_PIN); // Check if state changed from high to low (button press). if (newState == LOW && oldState == HIGH) { // Short delay to debounce button. delay(20); // Check if button is still low after debounce. newState = digitalRead(BUTTON_PIN); if (newState == LOW) { frozen=false; //unfreeze and start animation } } // Set the last button state to the old state. oldState = newState; timeDelay = startDelay; if (frozen) { // [FROZEN] // This if statement delays the start of the moving pixel. if (millis() > timeDelay) { frozen = true; // toggle frozen variable uint16_t seed = random16_get_seed(); seed = seed + analogRead(analogSeedPin) + analogRead(analogSeedPinB); // create a random seed random16_add_entropy(seed); seed = random16_get_seed(); freezeTime = random16(2000,6000); // set range of cycle times here moveSpeed= 5; //movement speed variable BRIGHTNESS = random(200,255); //randomize brightness fadeRate = 20; // change this to change tail length Serial.print("freezeTime = "); Serial.print(freezeTime/1000.0); Serial.println(" seconds."); freezeTime = millis() + freezeTime; } }//end_of_FROZEN if (!frozen) { // [IS NOT FROZEN] beat8_tail(); // Subroutine to move the pixel! } FastLED.show(); // Display the pixels. // Check to see if the random freeze time has been reached. // If true then stop the animation. if (millis() > freezeTime){ frozen = true; // toggle frozen variable timeDelay = millis() + startDelay; // set new start time freezeTime = millis() + 1000000; // To prevent re-triggering } }//end main loop //=============================================================== void beat8_tail() { EVERY_N_MILLISECONDS( 3 ) { fadeToBlackBy( leds, NUM_LEDS, fadeRate); // Fade out pixels. } uint16_t pos = beatsin8(moveSpeed, 100, 255) % NUM_LEDS; // modulo the position to be within NUM_LEDS leds[pos] = CHSV( gHue, 255, BRIGHTNESS); }
To change the way your LEDs act, play with the variables and random numbers in these lines of code:
freezeTime = random16(2000,6000); // set range of cycle times here moveSpeed= 5; //movement speed variable BRIGHTNESS = random(200,255); //randomize brightness fadeRate = 20; // change this to change tail length
-
freezeTime
How long the animation runs before freezing. Right now it's set to a random time between 2 and 6 seconds. -
moveSpeed
make the dot move faster or slower -
BRIGHTNESS
- I've randomized a bit to add interest and texture -
fadeRate
this controls the length of the tail, or, how many LEDs light up at once.
Page last edited March 11, 2017
Text editor powered by tinymce.