Arduino Fart-o-matic Toilet Humor Prank
by blackfire4116 in Living > Pranks, Tricks, & Humor
9020 Views, 111 Favorites, 0 Comments
Arduino Fart-o-matic Toilet Humor Prank
http://youtu.be/16c64j-qkog This is a fun and relatively simple prank that is ideal to use in a busy restroom. It is fairly simple to create with minimal Arduino skills. I didn't include a step by step because of the simplicity and that every situation can require a different design. Most of my design consists of items I had on hand. The restroom I installed this in is VERY BUSY, so speed and ease of setup was important to my design.
Parts
This list is the exact list of pieces that I used in my design but is easily alter-able for use in your own situation.
Parts:
Parts:
- Arduino - this one is an Uno
- Adafruit's Wave shield and SD card
- Parallax PIR sensor
- 3 pin lead - female to male
- a power source (more on that later)
- goose neck laptop light
- a container (this is from a Johnson & Johnson brand mini first aid kit)
- a strong magnet or other mounting device
- a small speaker
- a compartment to help amplify the speaker (I used a lid to a spray paint can)
- cable mounts
- a pin from a breakaway pin header
- heat shrink tubing
- various screws & nuts
Preparing the Arduino and Wave Shield and Putting Things Together
Assemble the wave shield as directed in the manufacturers tutorial and run some of the sample sketches to confirm that everything is working properly, also test the PIR sensor using some of the example sketches available (there are many here on Instructables). Solder the wires for the speaker to the provided spots in the circuit board of the wave shield.
Once you've made sure all the pieces work find some audio files that are appropriate for your prank and convert them to the necessary format for the Wave shield (there are instructions on how to do this at the Adafruit website).
I originally chose to power my project with a 9 volt battery because of it's compactness but this isn't a very good option to power an Arduino, I found out that I'd get optimum battery life using 4 AA batteries instead.
I put all my parts into a Johnson & Johnson Brand mini first aid kit box and cut out the spots for the pins, speaker wires, and battery wires. I drilled a hole and mounted the magnet to the back. The stalls in the intended restroom are metal so a magnet is ideal, this might require a change in design to fit your situation (although, I don't recommend using suction cups since it's a restroom and people tend to lick suction cups, yuck!).
I used the goose neck laptop light just for the goose neck portion because I wanted something that would be quickly adjustable. I mounted the PIR sensor to the "light" end of this and mounted the other end to my box using cable mounts. The 3 pin female to male lead is plugged into the sensor and on the male end of the lead I left the pins for ground and power intact and clipped the wire for the signal pin from the plug. I soldered a breakaway pin to the end of the signal wire and covered the connection with heat shrink. It would be a good idea to leave two or more pins attached so that it would make a more stable "plug" when attached to the wave shield but I only did one pin. The speaker is hot glued to the spray paint cap and the cap is then hot glued to the box.
When connecting you sensor to the wave shield you can use any pin you want provided it isn't one of the pins needed for the wave shield, pins 2 3 4 and 5 and 10 11 12 13 are all needed for either the wave shield or the SD card, leaving pins 6 through 9 and all the analog pins available. I chose pin seven, but you can use any of the available ones just remember to alter the sketch to that pin.
Once you've made sure all the pieces work find some audio files that are appropriate for your prank and convert them to the necessary format for the Wave shield (there are instructions on how to do this at the Adafruit website).
I originally chose to power my project with a 9 volt battery because of it's compactness but this isn't a very good option to power an Arduino, I found out that I'd get optimum battery life using 4 AA batteries instead.
I put all my parts into a Johnson & Johnson Brand mini first aid kit box and cut out the spots for the pins, speaker wires, and battery wires. I drilled a hole and mounted the magnet to the back. The stalls in the intended restroom are metal so a magnet is ideal, this might require a change in design to fit your situation (although, I don't recommend using suction cups since it's a restroom and people tend to lick suction cups, yuck!).
I used the goose neck laptop light just for the goose neck portion because I wanted something that would be quickly adjustable. I mounted the PIR sensor to the "light" end of this and mounted the other end to my box using cable mounts. The 3 pin female to male lead is plugged into the sensor and on the male end of the lead I left the pins for ground and power intact and clipped the wire for the signal pin from the plug. I soldered a breakaway pin to the end of the signal wire and covered the connection with heat shrink. It would be a good idea to leave two or more pins attached so that it would make a more stable "plug" when attached to the wave shield but I only did one pin. The speaker is hot glued to the spray paint cap and the cap is then hot glued to the box.
When connecting you sensor to the wave shield you can use any pin you want provided it isn't one of the pins needed for the wave shield, pins 2 3 4 and 5 and 10 11 12 13 are all needed for either the wave shield or the SD card, leaving pins 6 through 9 and all the analog pins available. I chose pin seven, but you can use any of the available ones just remember to alter the sketch to that pin.
The Sketch
I'd love to claim to have written the sketch from scratch but I found one already written that I could alter to serve my purposes. I've included the altered sketch but the original sketch is from the Instructable "How to have a talking dog" by Schmidtn, and is worth checking out in it's unaltered form, and anyway, who doesn't want a talking dog?
The sketch can be changed so that more audio clips can be added, just continue with the same pattern -case: 35 playcomplete (filename) break. You will also need to change the number of files listed in the randNum line, here it says random(1, 22); , so for example if you had 35 files it should say random(1,35);. The audio files on the SD card can be named anything you want, I just numbered them, just be sure to replace the numbered file names with your own file names, an example of this is in this sketch it says - playcomplete ("49.WAV") and say your file is named "bob", you'd need to change the 49.WAV in the sketch to say ("bob.WAV").
The finished prank is programmed so that any time there is motion sensed, it plays a random audio file (mine were all gross sounds, it is a restroom after all). As you can see in the photo the device is positioned so that it can't be seen but the motion detector can sense motion anytime someone approaches the urinal. I placed some boots with a pair of pants over them to make the stall look occupied. The restroom I used it in has a pretty steady flow of people, using the magnet mount and goose neck it was possible to put this in place in a matter of seconds. It wasn't until mid-afternoon that my co-workers finally got suspicious and investigated, they loved it so much that they didn't reveal the prank and enjoyed their newly found secret for the rest of the day.
#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 TRIGGER 7
#define LED 13
int val = 0;
int potvalue = 0;
long randNum;
// this handy function will return the number of bytes currently free in RAM, great for debugging!
int freeRam(void)
{
extern int __bss_end;
extern int *__brkval;
int free_memory;
if((int)__brkval == 0) {
free_memory = ((int)&free_memory) - ((int)&__bss_end);
}
else {
free_memory = ((int)&free_memory) - ((int)__brkval);
}
return free_memory;
}
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() {
// set up serial port
Serial.begin(9600);
pinMode(TRIGGER, INPUT);
pinMode(LED, OUTPUT);
randomSeed(analogRead(0));
putstring("Free RAM: "); // This can help with debugging, running out of RAM is bad
Serial.println(freeRam()); // if this is under 150 bytes it may spell trouble!
// 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);
// if (!card.init(true)) { //play with 4 MHz spi if 8MHz isn't working for you
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?
// 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!
}
// Whew! We got past the tough parts.
putstring_nl("Ready!");
/* TCCR2A = 0;
TCCR2B = 1<<CS22 | 1<<CS21 | 1<<CS20;
//Timer2 Overflow Interrupt Enable
TIMSK2 |= 1<<TOIE2;
*/
}
void loop()
{
val = digitalRead(TRIGGER);
potvalue = analogRead(1);
Serial.println(potvalue, DEC);
if (val == HIGH && potvalue >= 0 && potvalue <= 1023)
{
randNum = random(1, 22);
delay(1000);
switch (randNum)
{
case 1:
Serial.println(1);
playcomplete("49.WAV");
break;
case 2:
Serial.println(2);
playcomplete("50.WAV");
break;
case 3:
Serial.println(3);
playcomplete("51.WAV");
break;
case 4:
Serial.println(4);
playcomplete("52.WAV");
break;
case 5:
Serial.println(5);
playcomplete("53.WAV");
break;
case 6:
Serial.println(6);
playcomplete("54.WAV");
break;
case 7:
Serial.println(7);
playcomplete("55.WAV");
break;
case 8:
Serial.println(8);
playcomplete("56.WAV");
break;
case 9:
Serial.println(9);
playcomplete("57.WAV");
break;
case 10:
Serial.println(10);
playcomplete("58.WAV");
break;
case 11:
Serial.println(11);
playcomplete("59.WAV");
break;
case 12:
Serial.println(12);
playcomplete("60.WAV");
break;
case 13:
Serial.println(13);
playcomplete("61.WAV");
break;
case 14:
Serial.println(14);
playcomplete("62.WAV");
break;
case 15:
Serial.println(15);
playcomplete("63.WAV");
break;
case 16:
Serial.println(16);
playcomplete("64.WAV");
break;
case 17:
Serial.println(17);
playcomplete("65.WAV");
break;
case 18:
Serial.println(18);
playcomplete("66.WAV");
break;
case 19:
Serial.println(19);
playcomplete("67.WAV");
break;
case 20:
Serial.println(20);
playcomplete("68.WAV");
break;
case 21:
Serial.println(21);
playcomplete("69.WAV");
break;
case 22:
Serial.println(22);
playcomplete("70.WAV");
break;
default:
break;
}
}
}
// 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();
}
The sketch can be changed so that more audio clips can be added, just continue with the same pattern -case: 35 playcomplete (filename) break. You will also need to change the number of files listed in the randNum line, here it says random(1, 22); , so for example if you had 35 files it should say random(1,35);. The audio files on the SD card can be named anything you want, I just numbered them, just be sure to replace the numbered file names with your own file names, an example of this is in this sketch it says - playcomplete ("49.WAV") and say your file is named "bob", you'd need to change the 49.WAV in the sketch to say ("bob.WAV").
The finished prank is programmed so that any time there is motion sensed, it plays a random audio file (mine were all gross sounds, it is a restroom after all). As you can see in the photo the device is positioned so that it can't be seen but the motion detector can sense motion anytime someone approaches the urinal. I placed some boots with a pair of pants over them to make the stall look occupied. The restroom I used it in has a pretty steady flow of people, using the magnet mount and goose neck it was possible to put this in place in a matter of seconds. It wasn't until mid-afternoon that my co-workers finally got suspicious and investigated, they loved it so much that they didn't reveal the prank and enjoyed their newly found secret for the rest of the day.
#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 TRIGGER 7
#define LED 13
int val = 0;
int potvalue = 0;
long randNum;
// this handy function will return the number of bytes currently free in RAM, great for debugging!
int freeRam(void)
{
extern int __bss_end;
extern int *__brkval;
int free_memory;
if((int)__brkval == 0) {
free_memory = ((int)&free_memory) - ((int)&__bss_end);
}
else {
free_memory = ((int)&free_memory) - ((int)__brkval);
}
return free_memory;
}
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() {
// set up serial port
Serial.begin(9600);
pinMode(TRIGGER, INPUT);
pinMode(LED, OUTPUT);
randomSeed(analogRead(0));
putstring("Free RAM: "); // This can help with debugging, running out of RAM is bad
Serial.println(freeRam()); // if this is under 150 bytes it may spell trouble!
// 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);
// if (!card.init(true)) { //play with 4 MHz spi if 8MHz isn't working for you
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?
// 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!
}
// Whew! We got past the tough parts.
putstring_nl("Ready!");
/* TCCR2A = 0;
TCCR2B = 1<<CS22 | 1<<CS21 | 1<<CS20;
//Timer2 Overflow Interrupt Enable
TIMSK2 |= 1<<TOIE2;
*/
}
void loop()
{
val = digitalRead(TRIGGER);
potvalue = analogRead(1);
Serial.println(potvalue, DEC);
if (val == HIGH && potvalue >= 0 && potvalue <= 1023)
{
randNum = random(1, 22);
delay(1000);
switch (randNum)
{
case 1:
Serial.println(1);
playcomplete("49.WAV");
break;
case 2:
Serial.println(2);
playcomplete("50.WAV");
break;
case 3:
Serial.println(3);
playcomplete("51.WAV");
break;
case 4:
Serial.println(4);
playcomplete("52.WAV");
break;
case 5:
Serial.println(5);
playcomplete("53.WAV");
break;
case 6:
Serial.println(6);
playcomplete("54.WAV");
break;
case 7:
Serial.println(7);
playcomplete("55.WAV");
break;
case 8:
Serial.println(8);
playcomplete("56.WAV");
break;
case 9:
Serial.println(9);
playcomplete("57.WAV");
break;
case 10:
Serial.println(10);
playcomplete("58.WAV");
break;
case 11:
Serial.println(11);
playcomplete("59.WAV");
break;
case 12:
Serial.println(12);
playcomplete("60.WAV");
break;
case 13:
Serial.println(13);
playcomplete("61.WAV");
break;
case 14:
Serial.println(14);
playcomplete("62.WAV");
break;
case 15:
Serial.println(15);
playcomplete("63.WAV");
break;
case 16:
Serial.println(16);
playcomplete("64.WAV");
break;
case 17:
Serial.println(17);
playcomplete("65.WAV");
break;
case 18:
Serial.println(18);
playcomplete("66.WAV");
break;
case 19:
Serial.println(19);
playcomplete("67.WAV");
break;
case 20:
Serial.println(20);
playcomplete("68.WAV");
break;
case 21:
Serial.println(21);
playcomplete("69.WAV");
break;
case 22:
Serial.println(22);
playcomplete("70.WAV");
break;
default:
break;
}
}
}
// 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();
}