Showing posts with label halloween. Show all posts
Showing posts with label halloween. Show all posts

Wednesday, November 9, 2016

Halloween Candy Cauldron V3.1

V3.1 in the enclosure. Ignore the external speaker--it's a vestige. Ready to tidy up for V4.
As I said in my last post on this project, all that was left to do was tidy up the connections and enclose the electronics. I decided that the enclosure I was using was too big. The reason it was too big was that I had the project on a breadboard instead of soldering the components to a PCB. I have always wondered why places like Radio Shack that sell enclosures and PCBs don't sell PCBs that fit in the enclosures--with mounting holes and screws.  So, I went looking and found this enclosure with matching PCB and a battery compartment. A little pricey, but good quality and they have a variety of sizes and features. (I'm using the term PCB to include proto boards here.) Follow-up note: I found that the soldering pads on the pcb were insufficient.  I'll accept blame for my soldering technique, but I had more trouble with this than any other I've worked with.

Since the new enclosure was a little smaller, I decided to use an  +Arduino Pro Mini (actually an Arducam clone) instead of the +Adafruit Industries Pro Trinket.  It's a little smaller, and I had a few in inventory. It needs an FTDI to serial module to program, but I was using one anyway for the Trinket to be able to use the serial monitor.

The code compiled with no changes.  (See link to last post in opening sentence to see code.) In order to upload to the board, the IDE required some changes (to point to the right board--Nano, not mini), and the USB Port needed a tweak in Windows Device Manager (I'm on Windows 10). Arduino.cc has a clear and concise getting started article describing this better than I can.

Interrupt

Note that the interrupt code also works as-is.  I need to work on the program to make the sleep more useful. As you can see in the video (the blue LED is on when it's sleeping), it doesn't sleep much, I'm using the Echo pin on the HC-SR04 sensor to wake it up. I put it to sleep at the top of the loop, then wait for Echo to go LOW or HIGH. It works the same either way, at least to the naked eye.

I used LOW because IDLE is the only mode that can be woken from anything other than LOW, and I wanted to be able to play with other modes. I'm thinking about using an inverter so I can set the interrupt on LOW, but have the pin go LOW when the Echo pin goes HIGH. +Home DIY Electronics has a good article on interrupts and the HC-SR04.

Since the sensor is ranging constantly, it wakes up pretty quickly. If I try to put it in power down mode, it does not wake up (maybe because the sensor shuts down?):  The LED indicating sleep stays on and no gesture will wake it up. There are 5 sleep modes and these are only the 2 extremes. I will play with some of the intermediate modes--next year, or the next time I'm playing with interrupts on an AVR board.

Construction
  1. Test the mini
    Since I changed boards, I needed to upload the code, wire the circuit on a breadboard, and test. As described above, all was well.
  2. Prep the enclosure
    In this design, the speaker and the battery are now inside the enclosure, I only need holes to bring in wires from the switch and from the HC-SR04. I also drilled 7 holes to let the sound out, places where I planned to put the speaker.
  3. Design the board layout
    I needed to mount the Pro Mini, then find room for the amplifier and Micro SD Reader.  This required some planning, so I simulated with header pins on the PCB and marked where I would place the components.  All the components had male headers attached, because I originally set set this up for a breadboard, so I soldered the headers to the printed side of the board.
  4. Wire the busses
    I created power and ground busses on the inside edge of the board, next to the battery, using tinned copper bus wire. The board has pairs of adjacent rows of connected holes, so I used two of these pairs (one row for each bus, each adjacent row for connections to the circuit).  The power rail is supplied from the voltage regulator circuit 5V output, and the ground from the 9V battery's negative lead. The positive lead from the battery goes to a 2-wire JST connector, which mates to another connector with leads going to a toggle switch. The other lead from the case (with the + from the battery) is the 9V input to the voltage regulator.
  5. Test the Voltage Regulator Circuit
    Since I have habit of messing up connections, and power is a key part of this, I wanted to be sure that I was getting 5V out of this part of the circuit before completing the soldering. When I got it right (after some stupid soldering tricks), I was ready to move on.
  6. Mount the components
    All the components had male headers attached, because I originally set set this up for a breadboard, so I soldered the headers to the printed side of the board. I also added an LED and resistor for visual representation of the sleep mode (the code for this was already included, so what the heck).
  7. Test the circuit
    Before fastening the circuit board to the enclosure, make sure everything works.  Here's where I ran into trouble.  I worked the continuity function of my multi-meter extensively. I thought I had everything in order, but it failed. I went back to a version of the sketch that had serial commands for testing in it, and saw that the SD board was not initializing.  I rechecked the connections, checked the SD card to see if it could be read, and then got drastic:  clipped the jumpers from the mini to the SD reader, and connected them via alligator leads to another reader.  Still not initializing, so I was pretty sure it was my connections.  One more continuity test revealed a problem with one of the jumpers. I re-soldered, put it back together, and it worked. Stupid soldering tricks, indeed!
    Working circuit, mounted. Clockwise from upper left: Adafruit Class D Mono Amp (wires to speaker), voltage regulator circuit, indicator LED and resistor, Pro Mini, Micro SD Card Reader. Yellow and green wires go to HC-SR04, red and black wires on right are power to HC-SR04 (red and black) and from 9V battery and switch (black and gray). 
  8. Put it in the box
    See photo at the top of this post.  Enclosing was a matter of adding screws in the prepared holes to secure the PCB, then passing the 4 wires to the HC-SR04 through one hole and the battery connection through another, position the speaker under the holes, and closing the box.
  9. Video
    Available on Youtube (my channel)



Wednesday, October 19, 2016

Halloween Candy Cauldron V3

Cauldron V3 in-process.
The large speaker will be removed--replaced by the small green on in the enclosure.
The red FTDI Friend and USB cable are there for programming.
We'll shorten the wires, neaten it up, and put the cover on the enclosure.
The red LED is for testing--turned on before sleeping, turned off on waking.

When last we looked a this (last Halloween), I was having trouble making the electronics small. To recap, I started out with an +Arduino Uno, an SD card shield, +Adafruit Industries class D mono amp, and an HC-SR04 Ultrasonic Sensor.  Then someone reaches in to grab a piece of candy, the sensor reacts, code on the arduino then chooses one of nine sounds to play, via the amp and an 8 Ohm speaker.

Objective

The big issue is that the electronics are loose in the bottom of the cauldron, so I wanted to use a smaller board and smaller SD breakout (like a MicroSD), and put the whole thing in an enclosure. I tried the Adafruit Pro Trinket 5V last year and ran out of time before I could get it to work.

Turns out this was a stupid wiring trick. The circuit is powered by a 9V battery, run through a 7805 5V Voltage Regulator circuit.  The dumb thing I did last year was connect the BAT pin on the Trinket to the battery.  I'm not sure what, if anything, else I did wrong (I may have also connected that same pin to the 5V rail), but this year I connected the BAT pin to the 5V rail. Last year I got only static, this year it works. In both cases I powered the peripherals from the 5V rail (output of the VR circuit), to provide enough current, since the Trinket's 5V pin provides 150mA max.

Further, I wanted to put the Trinket to sleep while waiting for trick-or-treaters to save battery.

Video

Interrupts

Sleep mode turned out to be simple, but required some learning.  As described in this post on interrupts on the M0, I just completed my first successful Arduino project using interrupts.  So, I started with a __WFI(); instruction to wait for an interrupt. It turns out that different processors use different instructions, since interrupts are so hardware dependent, so this did not compile.

My main source of information was here. The avr\sleep.h library (which does not work with the M0), was the key, since the main differences between the 2 processor families is how you put the processor to sleep, and the sleep modes. On the M0, the top of loop tested to see if one of our interrupts had been fired, and if not issued a wfi--back to sleep.  If so, go on to process In the case of the Trinket, also at the top of loop, we attached the interrupt, enabled sleep, went to sleep, and on waking, disabled sleep and detached the interrupt. The code:
//*****sleep**************************
    digitalWrite(ledPin, HIGH);  //turn on the LED (testing)
    attachInterrupt(digitalPinToInterrupt(echoPin), echoISR, HIGH); //attach interrupt
    sleep_enable();          // enables the sleep bit in the mcucr register
    sleep_mode();            // here the device is actually put to sleep!!
//***********************************/

//wait here for echoPin interrupt--ignore all others
//*****wake up************************
    sleep_disable();         // first thing after waking from sleep: disable sleep...
    detachInterrupt(digitalPinToInterrupt(echoPin));      // disables interrupt because pin stays high
//***********************************/

echoPin is Trinket pin 3, the only one that sees interrupts
echoISR just sets a volatile boolean, handIn
The next code tests handIn to see if it was set, meaning that we woke up because of the interrupt we care about, then goes on to reset the boolean and process.

In set up, we enabled interrupts ("interrupts();") and set the sleep mode ("set_sleep_mode(SLEEP_MODE_IDLE);"). According to the article cited above, IDLE is the only mode that can be awakened by a mode other than LOW, and I thought since we want to be interrupted when echoPin goes HIGH, we're stuck with it, even though it saves the least power of all modes.

However, some experimentation yielded that LOW works similarly to HIGH on the attachInterrupt.  I tried SLEEP_MODE_PWR_DOWN, AND it seemed to sleep a little more, but the board hung with regularity, so I went back to IDLE.

I'm sure there are more and better ways to do this, but this is working for me.

Other Enhancements

I was never happy with how the code looked, There's a lot of function-specific processing that made the loop long. So, I broke out the code to calculate the distance based on the sensor pin values and the code to choose which sound to play and put them in functions.  Not rocket science, but good programming practice.

I replaced the 3.5" speaker with a 1.5". That allowed me to enclosed the speaker in the box, reducing wires. I also made it a little quieter--young trick-or-treaters don't like the loud version. Yes I know I can control the volume on the amp, but this works well.

Fritzing Diagram


Code

/*2014-10-05 Virgil Machine Halloween Candy Dish: Play random sound when kid (or greedy adult) reaches into bowl

2016-10-18 V3 VM  never got Trinket to work last year, this week I did (stupid wiring trick)
 also replaced external speaker with a 1.5" that dit in the enclosure
 Added interrupt  handling to put it to sleep to save battery (thanks to http://playground.arduino.cc/Learning/ArduinoSleepCode)
 had  to change echoPin to #3--only pin on Trinket that is interruptable; changed trigPin to 4 to be
side-by-side for wiring, added ledPin for testing
Also, put the song selection/playing and distance calculation code in functions to make loop more readable.

2015-10-14 V2 VM change to Pro Trinket from Uno to put the circuit in an enclosure
 Echo to 6 (Pro Trinket does not have pin 7)

2014-10-05 VM HC_SR04 Distance sensor code added
Neeed to modify pins for Halloween (13&12 used by SPI)

2014-04-26 VM Downloaded from Instructables
 HC-SR04 Ping distance sensor]
 VCC to arduino 5v GND to arduino GND
 Echo to Arduino pin 13 Trig to Arduino pin 12 (used 8&7 instead--need SPI pins for SD reader)
*/

/******* see virgilmachine.blogspot.com*****/

/*includes*/
#include    //SPI library
#include     //SD card library
#include //library for playing sound
#include  //sleep functions
#include  //interrupt functions

/*constants*/
#define SD_ChipSelectPin 10
#define echoPin 3 //so we can have an interrupt (D3 is the only one)
#define trigPin 4 //to be next to echo for wiring
#define ledPin  5

/*variables*/
int song = 0;   // song number for random function
volatile boolean handIn = false; //variables in ISR need to be volatile
/*objects*/
TMRpcm speaker;   // create an object for use in this sketch


void echoISR() //ISR for distrance sensor
{
    handIn = true;  //someone put his or her hand in
}

void setup(){
  randomSeed(analogRead(0));  //initialize random (A0 unconected)
  pinMode(trigPin, OUTPUT);   //pins for distance sensor
  pinMode(echoPin, INPUT);
  pinMode(ledPin, OUTPUT);   //LED fot testing
  digitalWrite(ledPin, LOW);  //default to off
  speaker.speakerPin = 9; //output to amp
  speaker.loop(0); //2014-10-05 do not play repeatedly
//  Serial.begin(9600); //Serial is for testing--comment to reduce time/power consumption
  if (!SD.begin(SD_ChipSelectPin))
     {  // see if the card is present and can be initialized:
//Serial.println("SD not initialized");
      return;   // don't do anything more if not
      }
//   else
//      {
//       Serial.println("SD initialized");
     //
//     }  
  speaker.volume(1);
//  speaker.setVolume(7);   //attempt to increase volume

interrupts(); //enable interrupts (should not need to do this, but just for drill...)
set_sleep_mode(SLEEP_MODE_IDLE);   // sleep mode is set here
//set_sleep_mode(SLEEP_MODE_PWR_DOWN);   // PWR_DOWN hangs periodically
}

void loop() {

//*****sleep**************************
    digitalWrite(ledPin, HIGH);  //turn on the LED (testing)
    attachInterrupt(digitalPinToInterrupt(echoPin), echoISR, LOW); //attach interrupt
    sleep_enable();          // enables the sleep bit in the mcucr register
    sleep_mode();            // here the device is actually put to sleep!!
//***********************************/

//wait here for echoPin interrupt--ignore all others
//*****wake up************************
    sleep_disable();         // first thing after waking from sleep: disable sleep...
    detachInterrupt(digitalPinToInterrupt(echoPin));      // disables interrupt because pin stays high
//***********************************/
  while (handIn) {   //someone wants candy, hcsr04 interrupted
    digitalWrite(ledPin, LOW);  //turn off LED (testing)
    handIn=(!handIn); //reset the boolean
//2014-10-05 If distance is <8in cm="" hand="" his="" in="" nbsp="" p="" put="" someone="">//2016-10-18 (the getDistance function calculates that)
    if (getDistance() < 20)
    {
      playSong(); //function to select and play a random song
    } //distance
      delay(2500);  //give the song a chance to play
  } //while

} //loop

void playSong() {
        song = random(1,10); //get random number from 1 to 9
//      Serial.print("song: "); //for testing
//      Serial.println(song); //for testing
      switch (song) {
        case 1:
          speaker.play("1.wav");
          break;
        case 2:
          speaker.play("2.wav");
          break;
        case 3:
          speaker.play("3.wav");
          break;
        case 4:
          speaker.play("4.wav");
          break;
        case 5:
          speaker.play("5.wav");
          break;
        case 6:
          speaker.play("6.wav");
          break;
        case 7:
          speaker.play("7.wav");
          break;
        case 8:
          speaker.play("8.wav");
          break;
        case 9:
          speaker.play("9.wav");
          break;
      } //switch/case
} //playSong

long getDistance() {
  long duration, distance;
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
//trigPin must me high for 10 microsecs to do ranging
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
//duration is the time between pings of the sensor  in microseconds as returned on echoPin
  duration = pulseIn(echoPin, HIGH);
//duration is a round-trip, so divide by 2; speed of sound is 29.1 cm/microsec, so distance is in cm
  distance = (duration/2) / 29.1;
  return distance;
} //getDistance  


Thursday, October 29, 2015

Halloween Candy Cauldron V2.1 upGRADE

Forget all that stuff in my last post about what I cooked.  I went back to the Uno version, really at a loss about why everything stopped working.  I decided to check power, first on the 5V rails--no power!  Then, I check what was coming from the 5V pin on the Uno. Nothing.  The only answer (other than a cooked Uno, which I did not believe) was a bad jumper wire.  Sure enough, I did continuity tests on the wires and one was bad.  I replaced them and it worked. So, the sensor and amp are both fine.



I went back to the Trinket.  It's putting out static only.  Same sensor, same amp. So, maybe I cooked the Trinket.  I'll have to decide whether I want to solder up another Trinket and perhaps sacrifice it this year or wait until next. As for now, I've spent a WHOLE LOT OF TIME working on something that already worked,  I have the bigger cauldron, and I have a switch, and it works again.

My other upgrade for next year is to put the Trinket--or Uno if I can't get the Trinket to work--into low-power mode while it's dormant to save battery and avoid having to turn it on and off so much. I've just learned how to do that in concept and this appears to be a good application.

So. I can take it to work tomorrow to entertain my co-workers. Since Halloween is a Saturday, I'll decide then if I want to spend more time (and maybe money) getting the Trinket version to work again.

I feel much better! On to 3.0!


Halloween Candy Cauldron V2.1 (update,not upgrade--more of a downgrade)

I was having a problem with my candy cauldron: the Pro Trinket was resetting at random intervals, and the circuit would not resume unless I powered off and back on.

I surmised that the problem was power.  I was powering the 5V rails from the 5V pin on the Trinket. (This worked on the Uno, but maybe the Trinket doesn't put out as much current).  So, I took the 9V Vcc to the BAT and GND pins of the Trinket, then to the IN and GND pins of an LM7805 voltage regulator, and powered the 5V rails from the OUT pin on the LM7805.

All was good. No more reset.  I took the cauldron to a meeting in the morning and had fun.

Then I got greedy. The cauldron is very small, which limits the candy.  It's limited anyway, and in addition if candy is piled too high the sensor sees it and sets off sounds. Also, there was a sound problem: since the HC-SR04 sensor is ultrasonic, if the sound being played is long the sensor detects it and plays the next sound even if no one reaches in, and will continue until it gets to a shorter sound. For example: the howl is long but the cackle is short--if the randomizer selects the howl, it will play at least one additional sound until it gets one like the cackle; if it selects the cackle, it plays only that one sound. I had put in a 5 second delay to wait for the sounds dissipate, but that wasn't enough for all sounds and I didn't want to make it longer because that makes the candy grabbers wait too long.

So, I got a bigger cauldron and that worked fine--briefly. It played only one sound at a time since there is more room for the sound to dissipate. Then the problems: I do not know what happened, but it started producing static only and resetting--at first randomly and then continuously, then stopped producing sound altogether.  I thought I might have cooked the Trinket, but it doesn't work on the Uno either. The sensor is not registering, so I probably cooked my last one. According to my meter, there is a signal on the speaker pin when there is supposed to be, so I may have cooked the amp too. I swapped that out, with no success...but the amp I swapped to was the one I thought was cooked earlier but discovered I wired it wrong--maybe I really did cook it. I have more, but I need to solder on headers and a terminal block before testing.

So, I don't know if I'll be ready for Halloween.  If I get the amp to work I may invest in a retail HC-SR04 at Radio Shack while I wait for my $0.88 ones to arrive from China.

I'm not happy.

Monday, October 26, 2015

Halloween Candy Cauldron V2.0

Last year I was enticed into a Halloween Project.  I was working on my donkey, which involved sound, at the same time many of  the +Adafruit Industries  weekly #ShowandTell and #WearableWednesday projects had a Halloween theme, and of course there's the #electroninchalloween hashtag.

So, I came up with the idea of a candy dish that made Halloween-ey sounds when someone reaches in for candy. It was a big hit with adults, but kids less impressed.  I realized that I had some design flaws.

Here's my appearance on the Adafruit Show and Tell, while I was still working on the SD card reader. It should start just before my section (after you skip the ad), but if not, I start at about minute 18.

First, I did not enclose the circuitry, so aggressive candy grabbers could introduce failure (adults were bigger offenders here).  Second, I wanted to use the +SeeedStudio SD Card Shield, which meant I needed to include an Arduino Uno. That was fine, because the shield sits on top of the Uno and the Adafruit Class D Amp uses 5V. Most SD card readers, particularly MicroSDs, want 3.3V.  I could do this off the Uno, but I needed another approach if I wanted to use a different board with one voltage level or the other.

I had a Adafruit Pro Trinket (5V) around, so I decided to use it.   I need the Pro Trinket as opposed to Trinket, because the smaller (non-Pro) version doesn't have enough pins to support SPI, which I need for the SD card.  I does not have a digital pin #7, which I was using for the Echo Pin on the ultrasonic sensor, so I has to change that to #6. Fortunately, I also had an LC Studios SD Card Reader that accepted 5V or 3.3V. That simplified matters, avoiding a voltage regulator and  logic level converter (which I have, but simpler is better),  The Pro Trinket can be powered from up to 16V, so I'll bring 9V  into it and power a 5V rail from the Trinket.

See issues, below,  I had 2 of the LC Studios boards. One would not work at all.  The other I got to work with the Uno but not with the Trinket. So, I ordered an Adafruit Micro SD Breakout Board. More expensive, but it works--and I am supporting a my favorite supplier.

Now I needed an enclosure.  This is a case where a 3D Printer would be really handy so I could design my own (I'm working on that).  Stock enclosures almost always have standoffs in the wrong places, so at best the standoffs are useless and at worst are in the way and have to be cut out, AND they're never exactly the right size.

To recap last year's project, I had:
Ultrasonic Distance Sensor and 3" speaker from a defunct clock radio as peripherals, with an Arduino Uno, SD card shield, and an amp--all loose in the bottom of the cauldron (except the speaker and sensor). The battery was external.

The changes are:
  1. add an enclosure; mine is 5" X 1.75" X 2.5"--bigger than I really need but everything fits, including a half-sized breadboard
  2. change from the Uno to a 5V Pro Trinket
  3. use a MicroSD reader instead of the SD shield
  4. I considered a circuit board or perma-proto), but decided to keep the half-sized breadboard for modularity and simplicity
  5. move the battery into the enclosure and use a switch to power on/off (last year I had the 9V battery outside the cauldron, inside a switched battery holder
  6. as noted below, I used long header pins to connect components to the breadboard
  7. change the pin assignment for the Echo Pin from 7 to 6
I will need to connect 8 wires from the enclosure: 4 to the distance sensor,  2 to the speaker, and 2 from the battery to the switch so I'll need to have holes in the enclosure and devise a way to connect them (short of hardwiring). I have some Radio Shack RCA phono plugs and jacks for the speaker, and holes for the sensor wires and power wires. I will use JST connectors for the power and sensor wires.
Since I'm keeping the breadboard, I can use long header pins in the breadboard, and just plug the JST female ends into them.

Everything else is as in V1.

Issues along the way:

After I got an SD card reader that worked (see above), I had it all working.  Then I must have messed up a connection, because I was getting no sound. I suspected that the HC-SR04 was cooked, so I put on my FTDI board so I could use the serial monitor to see the testing messages I put in the code. Sure enough, it was not registering.  I had 2 more, so I swapped one in. same result.  Swapped the other in--all is well.  I knew I would need more, and my options were 2 for $9 at amazon or $0.88 each off ebay. I ordered 5, If one works I break even with Amazon.  

Next problem:  still no sound. I check every connection and reran everything, so I concluded that the amp was bad too (this happened in another project with the same amp).  I ordered 4 more. As soon as they arrived I soldered the header and terminal block and swapped it in.  No sound. I turned the volume to see if that was the problem,  Just in case, I checked the wiring again. Sure enough, the wire that was supposed to connect A- to GND was misplaced. I moved it and tiedd again. Still no sound. Remembering that I had adjusted the volume, I turned it back. Sure enough, I had turned it down earlier, so now its all good.

New circuit:


Parts

  1. enclosure (mine is 5"L X 1.75"H X 2.5"W)--I don't remember where I got it, but Radio Shack has several that are close, so does Micro Center
  2. half-sized breadboard
  3. Adafruit Pro Trinket (5V)
  4. Adafruit Micro SD Breakout Board
  5. HC-SR04 Ultrasonic sensor (link for example--it can be found for
  6. Adafruit Class D Amp 
  7. 3in 8 Ohm speaker (I took mine from a clock radio)
  8. SPST toggle switch
  9. Sparkfun FTDI Basic Breakpout (for serial debugging)
  10. 9V Battery  (or any power supply > 5V)
  11. snap-on battery cap with leads (for 9V--other options for other power--e.g., a 4XAA enclosure)
  12. female-female jumpers
  13. JST connectors
  14. RCA phono plug and jack
  15. long header pins 

Construction:

  1. Upload the code to the Trinket.  I really didn't have to do this first, but since is was written for the UNO on an earlier version of the IDE, I wanted to make sure.  All good on IDE version 1.6.5...and I had to do it again once I realized that I needed to re-assign the Echo Pin
  2. I used long header pins (long on both sides) in the breadboard, and used JST female ends to connect to them, and soldered the JSTs to the leads to battery/switch, sensor,  and amp. I used female-female jumpers to connect to the SD breakout (also Speaker Pin to the amp). The amp itself is plugged into the breadboard via its header pins
  3. Drill holes in the enclosure (1/8" for the wires to the JST's, 3/8" for the RCA plug--yes I put the plug on the leads to the amp and the jack on the leads to the speaker)
  4. Solder header pins on the Trinket
  5. Solder leads to the RCA jack and plug (only need one of each since there's just one speaker), and the JST connectors
  6. Connect, test, and go

Code

/*2014-10-05
Halloween Candy Dish: Play random sound when kid reaches into bowl
*/
/*2014-10-05 HC_SR04 Distance sensor code added
 Need to modify pins for Halloween (13&12 used by SPI)
 2014-04-26 Downloaded from Instructables
 HC-SR04 Ping distance sensor]
 VCC to arduino 5v GND to arduino GND
 Echo to Arduino pin 13 Trig to Arduino pin 12 (used 8&7 instead)
*/
/* 2015-10-14
 Change to Pro Trinket from Uno to put the circuit in an enclosure
 Echo to 6 (Pro Trinket does not have pin 7)
 see virgilmachine.blogspot.com
*/

/*includes*/
#include    //SPI library
#include     //SD card library
#include //library for playing sound

/*constants*/
#define SD_ChipSelectPin 10
#define trigPin 8
#define echoPin 6 //used to be 7 on Uno--Pro Trinket does not have a pin 7
/*variables*/
int song = 0;   // song number for random function
/*objects*/
TMRpcm speaker;   // create an object for use in this sketch

void setup(){
  randomSeed(analogRead(0));  //initialize random (A0 unconected)
  pinMode(trigPin, OUTPUT);   //pins for distance sensor
  pinMode(echoPin, INPUT);
  speaker.speakerPin = 9; //output to amp
  speaker.loop(0); //2014-10-05 do not play repeatedly
  Serial.begin(9600);
  if (!SD.begin(SD_ChipSelectPin))
     {  // see if the card is present and can be initialized:
     Serial.println("SD not initialized");
      return;   // don't do anything more if not
      }
   else
      {
       Serial.println("SD initialized");
     }  
  speaker.volume(1);
//  speaker.setVolume(7);   //attempt to increase volume
}

void loop() {
  long duration, distance;
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
//trigPin must me high for 10 microsecs to do ranging
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
//duration is the time between pings of the sensor  in microseconds as returned on echoPin
  duration = pulseIn(echoPin, HIGH);
//duration is a round-trip, so divide by 2; speed of sound is 29.1 cm/microsec, so distance is in cm
  distance = (duration/2) / 29.1;
    Serial.print(distance);  //debug
    Serial.println(" cm");  //debug
//2014-10-05 If distance is <~5in someone has reached in 12/2.54cm=just under 5in
if (distance < 12)
    {
      song = random(1,10); //get random number from 1 to 9   sounds on SD card are 1.wav, etc.
      Serial.print("song: "); //for debugging
      Serial.println(song); //for debugging
      switch (song) {
        case 1:
          speaker.play("1.wav");
          break;
        case 2:
          speaker.play("2.wav");
          break;
        case 3:
          speaker.play("3.wav");
          break;
        case 4:
          speaker.play("4.wav");
          break;
        case 5:
          speaker.play("5.wav");
          break;
        case 6:
          speaker.play("6.wav");
          break;
        case 7:
          speaker.play("7.wav");
          break;
        case 8:
          speaker.play("8.wav");
          break;
        case 9:
          speaker.play("9.wav");
          break;
      }
        delay(5000);
  }
delay(50);
}