Wednesday, October 6, 2010

Arduino, PIR, and MP3 - oh my!

In this post, I'll try and explain as best I can how to use an Arduino to play a sound file from a hacked MP3 player.  The sound file will be triggered using a passive infrared sensor (PIR sensor) hooked up to the Arduino's output. 

Here are the parts I used:
Let's get started...



Coby MP3 Player
Here is a photo of the Coby MP3 player that I bought.  It was relatively cheap ($14.00) so I bought two.



Time to disassemble it.  Remove the two screws on the back and slide a thin flat blade screwdriver (or knife - be careful!) between the white plastic and black plastic body and pry up.  The two halves should pop apart.
 There are a few more screws to remove on the circuit board and then it should pop out of the case.

The object now is to determine how to simulate pressing one of the buttons.  Using a short wire, I touched the top left (or right) of the button (where it is soldered to the board - it is tiny!) to the bottom right (or left) of the same button.  This is the same as if you were to push the actual button - it completes the circuit.  Obviously, this process will depend on what make/model mp3 player you have, so YMMV.

Now on to the hard part (at least for this mp3 player) - soldering some extension wires that can be then hooked up to the Arduino. 

Since the circuit board is out of the case, the AAA battery won't stay between the two contacts.  I just added extension wires from the + and - contacts on the board and used electrical tape to hold the connection.  If you had a AAA battery case, you could use that.


I make no claims that I am very good at soldering (look at that?!).  As I said, the contact points are TINY and I had a hard time getting a good connection.  However, here's a picture of what you would theoretically want to do.  The button that the wires are soldered to is, of course, the play/pause button.
 You can test by simply touching the two wires together.  The mp3 player should start playing.  Touch them again, and it will pause. 

The Bad...
One thing you might notice is that the mp3 player goes to "sleep" after a few minutes of inactivity.  If you hold the wires together for more than a couple seconds, the LED on the board will blink 3 times and wake up.  Clearly, this isn't ideal for a prop which might be sitting idle waiting for a signal from a PIR sensor.  Also, I noticed that when the sound would play (or pause) it would fade in and out rather than just start (or stop) playing.  Again, not the ideal situation unless you are wanting to gradually scare someone.   Yah, I thought not.

The Good...
This is where I decided I would use the USB2M module instead.  I felt it necessary to keep the above instructions and photos in this blog as other mp3 players might not have this problem. 

USB2M Player
Here is a photo of the USB2M device.  No real need to disassemble anything other than removing it from the paper it comes attached to.


One other thing that I did do was to clip off the leads to the push button and install a 2 pin header so I could easily attach some wires to it.



Continuing on...

Building the circuit

Here is a photo of the completed circuit on the Arduino.  I'll step through where each wire should go.


  1. Connect a wire from one side of the relay coil to 5V on the Arduino (in the picture above, it is the brown wire in the lower right running diagonal).
  2. Insert the diode (cathode (-) towards 5V) from 5V on the Arduino to the other side of the relay coil.
  3. Connect a wire from the relay coil in step 2 to the collector of the transistor (in the picture above, it is the brown wire at the bottom running horizontal)
  4. Connect a wire from the base of the transistor to digital out 2 on the Arduino
  5. Connect a wire from the emitter of the transistor to ground on the Arduino.
  6. Connect a 1K ohm resistor from the base of the transistor to ground on the Arduino
  7. Connect one of the leads from the USB2M to the common pin of the relay (in picture above the common pin of the relay is the lower left corner of the relay and is the blue wire going out of frame in the bottom right).
  8. Connect the other lead from the USB2M to the normally open pin of the relay (in the picture above, it is the blue wire at the top of the relay going straight up out of frame - 4 holes from the right side of the breadboard).  NOTE:  Don't connect this to the normally closed pin (3 holes from the right side of the breadboard) or the USB2M will play the sound file continuously UNTIL the PIR is tripped - exactly opposite of what we want.
  9. On the back of the PIR, there are three pins: positive, negative and out.  Connect positive to 5V on the Arduino.  Connect negative to ground on the Arduino.  Connect out to digital out 3 on the Arduino.
  10. Done!
Arduino Sketch

The wonderful internet already had a sketch for hooking up a PIR to an Arduino so I used that and just tweaked it a bit to introduce another output pin (the mp3Pin).  The sketch is below (my additions are in red):


/*
 * //////////////////////////////////////////////////
 * //making sense of the Parallax PIR sensor's output
 * //////////////////////////////////////////////////
 *
 * Switches a LED according to the state of the sensors output pin.
 * Determines the beginning and end of continuous motion sequences.
 *
 * @author: Kristian Gohlke / krigoo (_) gmail (_) com / http://krx.at
 * @date:   3. September 2006
 *
 * kr1 (cleft) 2006
 * released under a creative commons "Attribution-NonCommercial-ShareAlike 2.0" license
 * http://creativecommons.org/licenses/by-nc-sa/2.0/de/
 *
 *
 * The Parallax PIR Sensor is an easy to use digital infrared motion sensor module.
 * (http://www.parallax.com/detail.asp?product_id=555-28027)
 *
 * The sensor's output pin goes to HIGH if motion is present.
 * However, even if motion is present it goes to LOW from time to time,
 * which might give the impression no motion is present.
 * This program deals with this issue by ignoring LOW-phases shorter than a given time,
 * assuming continuous motion is present during these phases.
 * 
 */

/////////////////////////////
//VARS
//the time we give the sensor to calibrate (10-60 secs according to the datasheet)
int calibrationTime = 10;       

//the time when the sensor outputs a low impulse
long unsigned int lowIn;        

//the amount of milliseconds the sensor has to be low
//before we assume all motion has stopped
long unsigned int pause = 1000; 

boolean lockLow = true;
boolean takeLowTime; 

int pirPin = 3;    //the digital pin connected to the PIR sensor's output
int ledPin = 13;
int mp3Pin = 2;


/////////////////////////////
//SETUP
void setup(){
  Serial.begin(38400);
  pinMode(pirPin, INPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(mp3Pin, OUTPUT);  //set mp3Pin as an output
  digitalWrite(pirPin, LOW);
  digitalWrite(mp3Pin, LOW); //set mp3Pin to low ("off")

  //give the sensor some time to calibrate
  Serial.print("calibrating sensor ");
    for(int i = 0; i < calibrationTime; i++){
      Serial.print(".");
      delay(1000);
      }
    Serial.println(" done");
    Serial.println("SENSOR ACTIVE");
    delay(50);
  }

////////////////////////////
//LOOP
void loop(){

     if(digitalRead(pirPin) == HIGH){
       digitalWrite(ledPin, HIGH);   //the led visualizes the sensors output pin state
       digitalWrite(mp3Pin, HIGH);  //send a signal on the mp3Pin to have the relay trigger the sound
       delay(5); //wait
       digitalWrite(mp3Pin,LOW);  //bring the mp3Pin back low so the relay closes and doesn't loop the sound
       if(lockLow){ 
         //makes sure we wait for a transition to LOW before any further output is made:
         lockLow = false;           
         Serial.println("---");
         Serial.print("motion detected at ");
         Serial.print(millis()/1000);
         Serial.println(" sec");
         delay(50);
         }        
         takeLowTime = true;
       }

     if(digitalRead(pirPin) == LOW){      
       digitalWrite(ledPin, LOW);  //the led visualizes the sensors output pin state
       digitalWrite(mp3Pin, LOW);
       if(takeLowTime){
        lowIn = millis();          //save the time of the transition from high to LOW
        takeLowTime = false;       //make sure this is only done at the start of a LOW phase
        }
       //if the sensor is low for more than the given pause,
       //we assume that no more motion is going to happen
       if(!lockLow && millis() - lowIn > pause){ 
           //makes sure this block of code is only executed again after
           //a new motion sequence has been detected
           lockLow = true;                       
           Serial.print("motion ended at ");      //output
           Serial.print((millis() - pause)/1000);
           Serial.println(" sec");
           delay(50);
           }
       }
  }



Testing it out

The USB2M has its own utility to load sounds onto the device.  You can download it from the 123Electronics website for free.  Simply insert the device into a USB port and browse for a file and click Record (high quality or low quality).

Fire up the Arduino and load the sketch.  After the calibration period (15 seconds or so) you should be able to wave your hand in front of the PIR and it should trigger the sound to play.  If it doesn't work, check your connections.

You can tweak the sketch as you see fit.  This is really just a basic quick how-to in order to get you started.  One tweak I can see as being useful would be to add a delay after the PIR is triggered.  This would be useful when you'd like the PIR to be tripped but let the victim walk a little further down the path before the sound triggers.

Monday, September 27, 2010

Boarded up windows

I tried this last year and it didn't work out as well as I had hoped.  This year, I built a frame which would friction fit between our brick window-casing on the front of our house. 


Frame:
The frame was made to roughly match the window style (frame with a cross in the middle) made out of 1x4 material.  I bought some industrial velcro and ran a strip vertically down each outer edge of the frame.  I'll take a photo of the frame and put it up here tonight.

Foam Boards:
The wooden boards were made out of rigid insulation sheets that you can get at any home improvement store.  I cut them about a foot longer than the width of the frame to allow overlap and to allow them to be mounted on odd angles.  The steps were pretty easy:  1. cut out a strip of foam to whatever width board you want, 2. use a knife to cut the edges of the board, 3. use a pen or blunt object (or a knife) to trace/cut the grain of the wood into the foam, and 4. paint them up!  On the back of each board, I ran a piece of velcro (opposite side of what went on the frame) horizontally about 4 or 5 inches on each side of the board.  This allows me to position them at various angles between the two vertical strips of velcro on the frame.










For the paint, I painted them with a dark brown base coat and then lightly dry brushed them with a lighter color brown.  I could have spent more time on them, but I needed to move on to other projects.  Busy, busy!



Monday, September 20, 2010

Graveyard Columns HowTo - Part 3

Almost there!  I've painted each column with a latex semi-gloss black for a base coat as seen here:


Then, I took some gray latex paint and brushed over the top of the black.  Make sure not to cover up the black base color entirely.  The black will be visible in the low parts (made by the water and blow torch).



Once this dries, I'm going to add a bit of white to my gray to get a little lighter color and use a sponge to hit it gently to make some highlights.  Of course, you could add as many colors and shades as you like (green for moss/lichens, etc).  If I have time, I may try some of those, but for now, this will be good enough.

Until next time...
Happy Haunting!

Saturday, September 11, 2010

Graveyard Columns HowTo - Part 2

I've been working on finishing the columns this weekend.  I'm pretty far along now.  I cut the rest of the foam board and glued them to the panels, trimmed out the primary (test) column and made a top for it.  I don't have the procedure down just yet for the top.  It works, but I can probably improve on it for the next one I build.  Here are some photos of the first column before painting.  The texture you see on the foam is from spraying the foam with a spray bottle to wet it and then taking a blow torch (outside people - toxic fumes!) and lightly wave it back and forth.  It causes a really cool weathered effect.

Here you can see the top is separate from the base for easy storage


fully assembled - just need paint!
closeup of the top-not crazy about this and will probably change the design for the next column.
Texture using water and blow-torch.
the front (pulled away here) and back have the vertical corner mouldings attached.  The side foam pieces fit behind the other side of the corner moulding.  Each panel has a base plate which is glued and nailed to each panel (about an inch off the ground so the ground doesn't cause the panels to shift if it is uneven - in theory anyway).

Next up - painting!

Tuesday, September 7, 2010

Graveyard Columns HowTo - Part 1

As I mentioned yesterday, I'm trying to make some graveyard columns for my haunt.  I have the basic construction done and thought I'd share some photos with you.  This post will only cover what I've actually done so far.  I'll post another with relevant photos once I'm further along.

Here's what I used (so far anyway):
  • 1x4 lumber to build the face plates for each column
  • plastic milk crates
  • wood screws to assemble the face plates (wood glue helps too)
  • mini bungee cords (found a bundle of them at Home Depot)
  • small eyelet screws (hooks would work as well I guess - something to hook the end of the bungee cords to)



First things first.  Decide how many columns you want and how high you want your columns to be.  Obviously, more columns, more milk crates.  Taller columns, more milk crates.  I settled on using 5 milk crates per column (and keep with my 4 columns for the yard).  So I scavenged the internet trying to find some free or inexpensive plastic milk crates (all the same size).  No real luck second hand (I even called the local grocery stores to see if they would get rid of any - no luck).  I did find that Wally-world (Wal-Mart) had a set of 6 for like $24.00.  At $4.00 each, not terrible I guess.  So I ordered them.





Next, I went to Home Depot and bought some 1x4s to make the face frame.  I experimented with how wide to make the frames.  Unfortunately, the milk crates were not perfectly square - one side was an inch or so longer than the other.  However, I figured it would be nice if I could make all the frames the same size so as not to have to keep track of which ones go on which side (we'll see if that comes back to haunt me).  I'm not going to give specific dimensions now since I'm still not entirely sure this will work.  Once I am done and (hopefully) have succeeded, I'll post a final list of materials and measurements.  Here are a few photos of how the face frames turned out (4 for each column, of course):


You can see one of the eyelet screws in the middle brace of the frame above.  There are similar eyelet screws in the top brace and bottom brace as well. 
I used a pocket hole jig to attach everything together.  It works well since you don't need to clamp everything (I build one using biscuits and soon realized it would take 100 years to finish since I had to clamp and wait for them to dry).

After the frames were assembled and the eyelet screws attached, I found a bag of mini (10") bungee cords at Home Depot.  These work perfectly - and you could shorten them by tying a knot in the end if need be.  The tension seems to be just right though out of the box, er bag.


Next, the assembly.  Starting at the bottom, place a milk crate on the ground and lay the four panels around it.

Place a bungee cord through one side of the milk crate and attach it to the eyelet screw.  Run it to the other side and attach it to the other eyelet screw.  Run another from the other two faces:


Place two more milk crates on top of the first.  Notice the third milk crate has a hole drilled in it to allow access to the middle eyelet screw.

Bring the face plates up and attach with two more bungee cords.

Add two more milk crates and attach as above.

There we have it!  Of course, now the plan is to cut some foam board and glue it to each face frame and paint it.  I'm also planning on using some corner moulding on the corners of the columns.  I think this might help keep things square and hide the edges of the foam.  Here's what that looks like:


Part 2 should be up soon!



Happy Haunting!

Monday, September 6, 2010

Graveyard columns new and improved

For the last two years I've put out a cemetery fence with columns for Halloween. It definitely adds to the feel of a cemetery of course but it also helps keep kids from running through the lawn and potentially tripping over the wires and cables that light up the other decorations.

From Halloween 2009

The columns were made out of 1x2 lumber and then covered with sheets of regular white beaded styrofoam and painted. They worked pretty well but they were heavy and a pain to store in the off season. So, last year I decided I would try and come up with a column that looked just as good but could be easily disassembled for storage. I think I might have figured something out and it centers around milk crates.

My thinking is that I could get some plastic milk crates and stack them up to whatever height and then create four panels (one for each side) that could be attached (and, of course, removed) easily. These panels would then be covered in foam board and decorated like normal. When Halloween is over, I can simply remove the side panels and stack (they should stack and store quite nicely) and then unstack the milk crates and use them for storing other Halloween decorations.

As soon as I start this project, I'll post photos and a more detailed how-to (assuming it works out well that is).