// Iron Man Repulsor triggered by Accelerometer_v1.0
// Bodged together by ShaunDarkLord
// WaveHC code borrowed from Adafruit Industries WaveHC library
// examples (indicated below).
//***************************************************************************
// Example code from wavehc_play6.ino as part of WaveHC Library
//***************************************************************************
#include <FatReader.h>
#include <SdReader.h>
#include <avr/pgmspace.h>
#include "WaveUtil.h"
#include "WaveHC.h"
SdReader card; // This object holds the information for the card
FatVolume vol; // This holds the information for the partition on the card
FatReader root; // This holds the information for the filesystem on the card
FatReader f; // This holds the information for the file we're play
WaveHC wave; // This is the only wave (audio) object, since we will only play one at a time
#define DEBOUNCE 100 // button debouncer
//***************************************************************************
// Inputs and Outputs
int GloveLED = 6; // Pin connected to the repulsor light
const int TiltSensor = A1; // Pin connected to the Accelerometer axis we wish to use.
// Defined variables
int PowerUpAngle = 410; // Angle at which the powerup sequence is triggered
int FireAngle = 400; // ANgle at which the fire sequence is triggered
const String Angle = "Angle: "; // Used in serial output for displaying current angle.
const String BVal = "Brightness: "; // Used in serial output for displaying current brightness.
long POWERUP_SFX_LENGTH = 1080; // Power Up wav file length
long POWERDWN_SFX_LENGTH = 1250; // Power Down wav file length
int brightness = 0; // how bright the LED is
int fadeAmount = 5; // how many points to fade the LED by
int idlebrightness = 10; // how bright the idle LED is
int powerupbrightness = 125; // how bright the powerup LED is
int maxbrightness = 255; // maximum brightness
int fadeValue = 0; // fade value for timed event
long currTime = 0; // current time
long prevTime = 0; // previous time
long timeDivision = 0; // clip length in milliseconds divided by the target brightness
// Defined states
#define S_STARTUP 1
#define S_INIT 2
#define S_ONLINE 3
#define S_IDLE 4
#define S_POWERUP 5
#define S_FIRE 6
#define S_POWERDN 7
static int state = S_STARTUP; // initial state is 1, the "startup" state.
// Setup
void setup() {
Serial.begin(9600); // Setup serial port
//***************************************************************************
// Example code from wavehc_play6.ino as part of WaveHC Library
//***************************************************************************
putstring_nl("WaveHC with 6 buttons");
putstring("Free RAM: "); // This can help with debugging, running out of RAM is bad
// Set the output pins for the DAC control. This pins are defined in the library
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
// enable pull-up resistors on switch pins (analog inputs)
digitalWrite(14, HIGH);
digitalWrite(15, HIGH);
digitalWrite(16, HIGH);
digitalWrite(17, HIGH);
digitalWrite(18, HIGH);
digitalWrite(19, HIGH);
if (!card.init()) { //play with 8 MHz spi (default faster!)
putstring_nl("Card init. failed!"); // Something went wrong, lets print out why
sdErrorCheck();
while(1); // then 'halt' - do nothing!
}
// enable optimize read - some cards may timeout. Disable if you're having problems
card.partialBlockRead(true);
// Now we will look for a FAT partition!
uint8_t part;
for (part = 0; part < 5; part++) { // we have up to 5 slots to look in
if (vol.init(card, part))
break; // we found one, lets bail
}
if (part == 5) { // if we ended up not finding one :(
putstring_nl("No valid FAT partition!");
sdErrorCheck(); // Something went wrong, lets print out why
while(1); // then 'halt' - do nothing!
}
// Lets tell the user about what we found
putstring("Using partition ");
Serial.print(part, DEC);
putstring(", type is FAT");
Serial.println(vol.fatType(),DEC); // FAT16 or FAT32?
Serial.println();
// Try to open the root directory
if (!root.openRoot(vol)) {
putstring_nl("Can't open root dir!"); // Something went wrong,
while(1); // then 'halt' - do nothing!
}
//***************************************************************************
//Setup IO
pinMode(GloveLED, OUTPUT); // Pin connected to the repulsor light
pinMode(TiltSensor, INPUT); // Pin connected to the Accelerometer axis we wish to use.
Serial.print("INTIT STATE: ");
Serial.println(state);
Serial.print("Setup Complete"); // Display on console that this sectio is complete
Serial.println();
}
// Loop
void loop() {
switch(state)
{
case S_STARTUP: // Begin Startup state
playcomplete("Import.wav"); //play the J.A.R.V.I.S. "Importing Preferences" sound effect
delay(1000);
Serial.print("Startup Complete");
Serial.println();
state = S_INIT;
break; // End Startup state
case S_INIT: // Begin init state
// set the brightness of pin 9:
analogWrite(GloveLED, brightness);
// change the brightness for next time through the loop:
brightness = brightness + fadeAmount;
Serial.print(BVal + brightness);
Serial.println();
// stop fading up when idlebrightness is reached
if (brightness >= idlebrightness) {
Serial.print("INIT complete");
Serial.println();
state = S_ONLINE;
}
// wait for 30 milliseconds to see the dimming effect
delay(30);
break; // End init state
case S_ONLINE:
{ // Begin online state
playcomplete("Online.wav"); //play the J.A.R.V.I.S. "Online and Ready" sound effect
delay(500);
state = S_IDLE;
break; // End online state
case S_IDLE: // Begin idle state
if (analogRead(TiltSensor) < PowerUpAngle) {
Serial.print("Powering Up");
Serial.println();
state = S_POWERUP;
}
else{
Serial.print(Angle + analogRead(TiltSensor));
Serial.println();
delay(200);
}
}
break; // End idle state
case S_POWERUP: // Begin powerup state
playfile("PWRUP1.WAV");
//fade up the LED
brightness = idlebrightness; // set the initial fade brightness
currTime = millis(); // set the current time
prevTime = currTime;
timeDivision = POWERUP_SFX_LENGTH/(powerupbrightness-idlebrightness); //clip length in milliseconds divided by the target brightness
Serial.print(timeDivision);
while (wave.isplaying)
{
// fade in from min to max over length of clip:
currTime = millis();
if(currTime-prevTime >= timeDivision)
{
brightness +=1;
Serial.print(BVal + brightness);
Serial.println();
// update glove LEDs
if(brightness <= powerupbrightness)
analogWrite(GloveLED, brightness);
prevTime = currTime;
}
}
// Move to firing state
Serial.print("Powered Up and waiting for action");
Serial.println();
state = S_FIRE;
break; // End powerup state
case S_FIRE: // Begin fire state
// Interupt powerup if hand lowered
if (analogRead(TiltSensor) > PowerUpAngle) {
Serial.print("Whoops");
Serial.println();
wave.stop();
delay(1000);
state = S_POWERDN;
}
if (analogRead(TiltSensor) < FireAngle) {
Serial.print("Firing");
Serial.println();
brightness = maxbrightness;
analogWrite(GloveLED, brightness);
playcomplete("FIRE1.WAV");
analogWrite(GloveLED, powerupbrightness); // Reduce brightness after firing
}
break; // End fire state
case S_POWERDN:
{ // Begin powerdn state
Serial.print("Powering Down");
Serial.println();
delay(500);
playfile("PWRDOWN1.WAV");
brightness = powerupbrightness; // set the initial fade brightness
currTime = millis(); // set the current time
prevTime = currTime;
timeDivision = POWERDWN_SFX_LENGTH/(powerupbrightness-idlebrightness); //clip length in milliseconds divided by the target brightness
while (wave.isplaying)
{
// fade in from min to max over length of clip:
currTime = millis();
if(currTime-prevTime >= timeDivision)
{
brightness -=1;
Serial.print(BVal + brightness);
Serial.println();
// update glove LEDs
if(brightness > idlebrightness)
analogWrite(GloveLED, brightness);
prevTime = currTime;
// Interupt powerdn if hand raised
//if (analogRead(TiltSensor) < GloveAngle) {
// Serial.print("Firing Again");
// wave.stop();
// state = S_FIRE;
//}
}
}
// Move back to idle state
Serial.print("Powered down");
Serial.println();
state = S_IDLE;
}
break; // End powerdn state
}
}
//----------------------------------------------------------------------------
//
/// sdErrorCheck
///
/// @desc
//----------------------------------------------------------------------------
void sdErrorCheck(void)
{
if (!card.errorCode()) return;
putstring("\n\rSD I/O error: ");
Serial.print(card.errorCode(), HEX);
putstring(", ");
Serial.println(card.errorData(), HEX);
while(1);
}
//----------------------------------------------------------------------------
//
/// playcomplete
///
/// @desc Plays a full file from beginning to end with no pause.
///
/// @param name
//----------------------------------------------------------------------------
void playcomplete(char *name)
{
// call our helper to find and play this name
playfile(name);
while (wave.isplaying)
{
}
// now its done playing
}
//----------------------------------------------------------------------------
//
/// playfile
///
/// @desc
///
/// @param name
//----------------------------------------------------------------------------
void playfile(char *name)
{
// see if the wave object is currently doing something
if (wave.isplaying) {// already playing something, so stop it!
wave.stop(); // stop it
}
// look in the root directory and open the file
if (!f.open(root, name)) {
putstring("Couldn't open file ");
Serial.print(name);
return;
}
// OK read the file and turn it into a wave object
if (!wave.create(f)) {
putstring_nl("Not a valid WAV");
return;
}
// ok time to play! start playback
putstring("Playing ");
Serial.print(name);
wave.play();
}
//***************************************************************************