/*
Rough working version of TRON Legacy Identiy Disc Code
Custom Disc Prop
by zook_one //:LDSO http://www.ldso.net
FYI there is still a lot of junk code in here to pull out...
Big thanks to Adafruit and rest of the Arduino Community for sharing so much information and helpful code examples!
Thanks to Canobi for help in sourcing SoundFX clips
Sample video of this code in action can be viewed here: http://youtu.be/8lgh8ytL7jk
IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
and minimize distance between Arduino and first pixel. Avoid connecting
on a live circuit...if you must, connect GND first.
*/
#include <Adafruit_NeoPixel.h> //needed for the NeoPixel Strips
#include <Wire.h> //needed for the motor control
#include <Adafruit_Sensor.h> //needed for the motor control Unified Sensor Libary for the compass/accel
#include <Adafruit_LSM303_U.h> //needed for the motor control Libary for the compass/accel
#include <WTV20SDBreakout.h> //library for the sound module
/* Assign a unique ID to this sensor at the same time */
Adafruit_LSM303_Mag_Unified mag = Adafruit_LSM303_Mag_Unified(12345);
// constants won't change. They're used here to
// set pin numbers:
int busyPin = 4; // The pin number of the sound module busy pin.
int dataPin = 5; // The pin number of the sound module data pin.
int clockPin = 6; // The pin number of the sound module clock pin.
int resetPin = 7; // The pin number of the sound module reset pin.
int motorPin = 10; // Pin out for the small vibrating motor
int ledPin = 13; //Pin out for (4) four Disc Read Mode LEDs
#define PIN_inner 8 // the digital pin the data line of the inner ring NeoPixel is connected to
#define PIN_outer 9 // the digital pin the data line of the outer blade NeoPixel is connected to
// variables will change:
int buttonPushCounter = 0; // counter for the number of button presses
int modeCounter = 0; // counter for the number of button presses
int buttonState = 0; // variable for reading the disc mode pushbutton status
int lastButtonState = 0; // previous state of the button
volatile int state = LOW; //Interrupt Code State
// Modifed NeoPixel sample for the holiday craft project
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip_inner = Adafruit_NeoPixel(16, PIN_inner, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip_outer = Adafruit_NeoPixel(38, PIN_outer, NEO_GRB + NEO_KHZ800);
#define hi_cyan strip_outer.Color(25, 200, 200) //defines color of outer ring (R,G,B), Brightness) from 0 to 255
#define hi_white strip_outer.Color(210, 210, 210) //defines color of outer ring "flashes" (R,G,B), Brightness) from 0 to 255
WTV20SDBreakout WTV20SDBreakout(resetPin,clockPin,dataPin,busyPin) ; //sound module setup
void setup() {
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the motor pin as an output:
pinMode(motorPin, OUTPUT);
attachInterrupt(2, my_interrupt_handler, FALLING);
//Initializes the sound module.
WTV20SDBreakout.reset();
WTV20SDBreakout.volume(3); //sets the volume for the sound module
strip_inner.begin();
strip_inner.show(); // Initialize all pixels to 'off'
strip_outer.begin();
strip_outer.show(); // Initialize all pixels to 'off'
}
void loop() {
int mode = modeCounter;
switch (mode) {
case 0: // power up disc
Serial.print("mode number: ");
Serial.println(modeCounter);
innerRing(strip_inner.Color( 110, 155, 150)); //defines color of inner ring (R,G,B), Brightness) from 0 to 255
modeCounter++;
break;
case 1: // Resting On Mode
Serial.print("mode number: ");
Serial.println(modeCounter);
analogWrite(motorPin, 0);
strip_outer.show(); // Initialize all pixels to 'off'
break;
case 2: // initial blade activation - push directly to loop effect- case 2
Serial.print("mode number: ");
Serial.println(modeCounter);
WTV20SDBreakout.asyncPlayVoice(0); //Plays audio file number 1
colorWipe_On(hi_cyan, 10); // Cyan
modeCounter++;
//WTV20SDBreakout.asyncPlayVoice(1);
break;
case 3: // blade loop effect
Serial.print("mode number: ");
Serial.println(modeCounter);
//WTV20SDBreakout.asyncPlayVoice(1); //Plays audio file number 1
//delay(5000);
theaterChase(strip_outer.Color( 25, 200, 200), 10); // Cyan
//strip_outer.show(); // Initialize all pixels to 'off'
mag.begin();
sensors_event_t event;
mag.getEvent(&event);
/* Display the results (magnetic vector values are in micro-Tesla (uT)) */
Serial.print("X: "); Serial.print(event.magnetic.x); Serial.print(" ");
Serial.print("Y: "); Serial.print(event.magnetic.y); Serial.print(" ");
Serial.print("Z: "); Serial.print(event.magnetic.z); Serial.print(" ");Serial.println("uT");
//delay(100);
if (event.magnetic.z <= 0)
{
analogWrite(motorPin, (event.magnetic.z *-2));
}
else
{
analogWrite(motorPin, (event.magnetic.z * 2));
}
break;
case 4: // blade power down
Serial.print("mode number: ");
Serial.println(modeCounter);
modeCounter++;
WTV20SDBreakout.asyncPlayVoice(2); //Plays audio file number 1
colorWipe(hi_white, 2); // White
colorWipe(hi_cyan, 1); // Cyan
reverseColorWipe(strip_outer.Color(0, 0, 0), 100);
break;
}
delay(1); // delay in between reads for stability
}
// fade_up - fade up to the given color
//void fade_up(int num_steps, int wait, int R, int G, int B) {
//uint16_t i, j;
//for (i=0; i<num_steps; i++) {
//for(j=0; j<strip.numPixels(); j++) {
//strip.setPixelColor(j, strip.Color(R * i / num_steps, G * i / num_steps, B * i / num_steps));
//}
//strip.show();
//delay(wait);
//}
//} // fade_up
void my_interrupt_handler()
{
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis();
// If interrupts come faster than 200ms, assume it's a bounce and ignore
if (interrupt_time - last_interrupt_time > 200)
{
digitalWrite(ledPin, state);
modeCounter++;
if (modeCounter >= 3){
//WTV20SDBreakout.pauseVoice();
//delay (10);
//WTV20SDBreakout.asyncPlayVoice(2); //Plays audio file number 2
//colorWipe(hi_white, 2); // White
//colorWipe(hi_cyan, 1); // Cyan
//reverseColorWipe(strip_outer.Color(0, 0, 0), 100);
//strip_outer.show(); // Initialize all pixels to 'off'
modeCounter = 4;
}
//if (modeCounter > 4){
//modeCounter = 4;
//}
Serial.print("mode number: ");
Serial.println(modeCounter);
Serial.print("interrupt worked");
}
last_interrupt_time = interrupt_time;
}
//void stateChange()
//{
//state = !state;
//digitalWrite(ledPin, state);
//modeCounter++;
//Serial.print("mode number: ");
//Serial.println(modeCounter);
//}
void innerRing(uint32_t c){
//inner strip start
//strip_inner.show();
//delay (2000);
//strip_inner.setBrightness(100);
strip_inner.setPixelColor(0, c);
strip_inner.setPixelColor(1, c);
strip_inner.show();
delay (500);
strip_inner.setPixelColor(2, c);
strip_inner.setPixelColor(3, c);
strip_inner.show();
delay (500);
strip_inner.setPixelColor(4, c);
strip_inner.setPixelColor(5, c);
strip_inner.show();
delay (500);
strip_inner.setPixelColor(6, c);
strip_inner.setPixelColor(7, c);
strip_inner.show();
delay (500);
strip_inner.setPixelColor(8, c);
strip_inner.setPixelColor(9, c);
strip_inner.show();
delay (500);
strip_inner.setPixelColor(10, c);
strip_inner.setPixelColor(11, c);
strip_inner.show();
delay (500);
strip_inner.setPixelColor(12, c);
strip_inner.setPixelColor(13, c);
strip_inner.show();
delay (500);
strip_inner.setPixelColor(14, c);
strip_inner.setPixelColor(15, c);
strip_inner.show();
delay (500);
strip_inner.setPixelColor(16, c);
strip_inner.setPixelColor(17, c);
strip_inner.show();
delay (500);
strip_inner.setPixelColor(18, c);
strip_inner.setPixelColor(19, c);
strip_inner.show();
delay (500);
strip_inner.setPixelColor(20, c);
strip_inner.setPixelColor(21, c);
strip_inner.show();
delay (500);
strip_inner.setPixelColor(22, c);
strip_inner.setPixelColor(23, c);
strip_inner.show();
delay (500);
strip_inner.setPixelColor(24, c);
strip_inner.setPixelColor(25, c);
strip_inner.show();
delay (500);
strip_inner.setPixelColor(26, c);
strip_inner.setPixelColor(27, c);
strip_inner.show();
//delay (500);
//strip_inner.setPixelColor(28, 0, 0, 255);
//strip_inner.setPixelColor(29, 0, 0, 255);
//strip_inner.show();
//delay (500);
//strip_inner.show();
//delay (2000);
//inner strip end
}
//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
for (int j=0; j<20; j++) { //do 1000 cycles of chasing
for (int q=0; q < 3; q++) {
for (int i=0; i < strip_outer.numPixels(); i=i+3) {
strip_outer.setPixelColor(i+q, c); //turn every third pixel on
}
strip_outer.show();
delay(wait);
for (int i=0; i < strip_outer.numPixels(); i=i+3) {
strip_outer.setPixelColor(i+q, 0); //turn every third pixel off
delay(2);
}
}
}
}
//while (WTV20SDBreakout.playVoice(2));
//}
// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip_outer.numPixels(); i++) {
strip_outer.setPixelColor(i, c);
strip_outer.show();
delay(wait);
}
}
// Fill the dots one after the other with a color
void colorWipe_On(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip_outer.numPixels(); i++) {
strip_outer.setPixelColor(i, c);
delay(10);
strip_outer.show();
delay(wait);
}
}
void reverseColorWipe(uint32_t c, uint8_t wait)
{
for(int16_t i=(strip_outer.numPixels()-1); i>=0; i--)
{
strip_outer.setPixelColor(i, c);
strip_outer.show();
modeCounter = 1;
delay(5);
}
}