Monday, April 16, 2012

The Wonderboy - "Sweet Spot"

There is a part of the baseball bat called the "sweet spot."  It's that magical place on the bat, where a "combination of factors (physics and all that) results in a maximum response for a given amount of effort."  When you swing a bat and it connects with the baseball at the sweet spot, you hear a clear crack, the bat doesn't vibrate, and the ball soars beautifully through the air.  It's an awesome feeling, like everything has come together at the right moment.

I have found the "sweet spot" of my interactive exhibit design project.  It has taken all semester, in which I spent innumerable hours Google searching Arduino code and brought me nearly to tears of frustration at times.  But after taking all of the hardware and the working code I described in my last post about the Wonderboy and loading it onto my batting helmet, I am finally there.  I'm amazed at how closely my finished project resembles the original idea of a "history appliance" I had at the beginning of the semester.  The final product is definitely a home run, if I do say so myself!

I made a brief video demonstrating how all the hardware attached to the batting helmet for the finished product:  


I've admitted several times that these courses - digital history/interactive exhibit design - have taken me further outside my academic comfort zone than I've ever been before.  It made me recognize one of the biggest lessons that grad school has taught me - don't be afraid to try new things, stretch yourself, step outside your comfort zone.  I'm still amazed at the technical things I accomplished this semester with no background in programming at all.  If you would have told me last year I'd be doing all this, I'm not sure I would have believed you.  It just goes to show that you should never stop trying new things, or pigeon-hole yourself.

My classmate Dave summed up our lessons very well, when he talked about "The Nine Letters, or Three Laws, of the Digital Historian" - do-it-yourself (DIY), steal from others (SFO), and share with others (SWO).  I certainly tried to do all of those things this semester.  Though perhaps I did more stealing than sharing, I'm hoping that perhaps my lessons, trials, and tribulations will be of assistance to someone, someday.

So it is with a bit of a heavy heart that I dismantle the Wonderboy, and return the guts of my project to my professor Bill.  It will be forever immortalized in pictures of my classmates willing to put it on and give it a try:

Douglas

Matt

Lindsay
 
Sushima

Finally, if you are interested, here is the Arduino code I used to program my final project:

int IRpin = 0;  // analog pin for reading the IR sensor
int val = 0;       // analog pin for reading the IR sensor

#include "WaveHC.h"
#include <FatReader.h>
#include <SdReader.h>
#include <avr/pgmspace.h>
#include "WaveUtil.h"

WaveHC wave;      // This is the only wave (audio) object, since we will only play one at a time
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

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);
}

void setup() {
  Serial.begin(9600);                             // start the serial port
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
   
  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!
  }
   
  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?

  // 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!
  }
}

void loop() {
   val = analogRead(IRpin);
  Serial.println(val);                       // print the distance
 
  
if(val > 60 && val < 128){
  playcomplete("SCHMIDT.WAV");
  }
else{
  //do nothing
  }
  delay(50);

val = analogRead(IRpin);
  Serial.println(val);                       // print the distance

if(val > 129 && val < 196){
  playcomplete("VENTURA.WAV");
  }
else{
  //do nothing
  }
   delay(50);

val = analogRead(IRpin);
  Serial.println(val); 
  // print the distance

if(val > 197 && val < 264){
  playcomplete("BONDS.WAV");
  }
else{
  //do nothing
  }
 delay(50);
   
val = analogRead(IRpin);
  Serial.println(val);                       // print the distance
   
if(val > 265 && val < 332){
  playcomplete("CURTIS.WAV");
  }
else{
  //do nothing
   }
  delay(50);

val = analogRead(IRpin);
  Serial.println(val);                       // print the distance
   
if(val > 333 && val < 400){
  playcomplete("CARTER.WAV");
  }
else{
  //do nothing
  }
  delay(50);
}


// Plays a full file from beginning to end with no pause.
 void playcomplete(char *name) {
  // call our helper to find and play this name
  playfile(name);
  while (wave.isplaying) {
  // do nothing while its playing
  }
  // now its done playing
}
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
  wave.play();
}

No comments:

Post a Comment