Maker.io main logo

Behold the Yack-O-Lantern!

2018-10-30 | By SparkFun Electronics

Audio Voice Recognition Movement Passive Infrared (PIR) Other Optoelectronics

With just a handful of parts and a couple of hours of work, you can easily repulse all of your co-workers at this year's office Halloween party!

Ah, autumn! That wonderful time of year when makers, crafters, hackers and DIY-ers of every stripe get down to the business of creating the masterpiece they’ve been planning since November first of the previous year. Sometimes, however, life gets a bit too busy, and you realize that your perfect Halloween build barely has a chance of being finished by Christmas, nevermind Halloween. These are the times when you need a quick build that still shows that you’re very creative, yet slightly disturbed. That’s where the Yack-O-Lantern comes in! This table display uses an Infrared Proximity Sensor to trigger a horrible vomiting sound (it cycles through nine different sounds!) when anyone reaches for a treat from the tray.

The parts list is fairly simple for this one. I’m using a Sparkfun RedBoard, Sparkfun MP3 Player Shield (along with a set of Stackable Headers ), a Sharp GP2Y0A21YK Infrared Proximity Sensor along with the necessary IR Sensor Jumper, and a Hamburger Mini Speaker. For power I used a 4xAA to Barrel Jack Connector Battery Holder with a latching switch spliced into the line, but you could also use a battery holder with its own built-in switch. To add a little flickering candle effect, I also threw in a couple of Super Bright Yellow LEDs and an orange LED from our LED Rainbow Pack. Oh, and if you don’t have a spare one sitting around, you’ll need a microSD card for your sounds. You can also find the wish list here:

Parts List

Putting it together

There’s not much to the assembly here at all. Like I said, sometimes you just need quick and easy. Simply solder the stackable headers into the MP3 Player Shield, and nest it onto the RedBoard. I soldered the two yellow Super Bright LEDs in series, and while I perhaps should have added a 22 Ohm resistor, I skipped it for expediency’s sake, and because the LEDs won’t be constantly powered. I wired the yellow LEDs to pin 9, the orange LED to pin 10, and the IR sensor to pin A0. Then just add the speaker and the battery pack, and Bob’s your uncle!

Finding the sounds

If you’re really into SFX or foley work, you may want to record your own sound files for this one. However, there are other options available, without having to hang out in the bathroom at a fraternity party with recording equipment. I used royalty-free files from https://www.soundjay.com/, along with another site that no longer exists. But there are sound effects sites out there, it will just take some digging to find the ones you like. Please just remember to respect the licenses of the files you use.

The MP3 Player Shield has firm requirements regarding the naming of the files. I would definitely suggest reading the full hookup guide for the MP3 Player Shield here, but the short of it is that you’ll need to name your files “track001.mp3,” “track002.mp3,” etc.

A bit of code

While there is a fair bit of coding needed for the MP3 Player Shield, the code for the Proximity Sensor is fairly simple. The sensor reads the intensity of the returned light, and the higher the intensity - that is, the closer the object - the higher the value returned. Adjust the variable “val” in the code so that the sensor only triggers when a hand gets to the edge of the serving plate.

Copy Code
/***************************************************************************
Puking Party Pumpkin, AKA The Yack-O-Lantern!

Example sketch for the Sharp Ifrared Proximity Sensor GP2Y0A21YK
  (https://www.sparkfun.com/products/242)
  and Sparkfun's MP3 Player Shield
  (https://www.sparkfun.com/products/12660)

Rob Reynolds @ Sparkfun Electronics
Oct 8, 2018  

Based heavily on the prior work of  
Jim Lindblom @ SparkFun Electronics

The proximity sensor has a three-pin JST connector terminating it. Connect
the wire colors like this:
- Yellow: A0 - signal output (pulled up internally)
- Ground: GND
- Red: 5V

Whenever the proximity sensor detects movement within a certain distance, it'll write the alarm pin LOW.

Development environment specifics:
Arduino 1.8.5

License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license).    

***************************************************************************/

// First, we'll include the needed libraries

#include <SPI.h>           // SPI library
#include <SdFat.h>         // SDFat Library
#include <SdFatUtil.h>     // SDFat Util Library
#include <SFEMP3Shield.h>  // Mp3 Shield Library


SdFat sd; // Create object to handle SD functions
SFEMP3Shield MP3player; // Create Mp3 library object
// These variables are used in the MP3 initialization to set up
// some stereo options:
const uint8_t volume = 0; // MP3 Player volume 0=max, 255=lowest (off)
const uint16_t monoMode = 1;  // Mono setting 0=off, 3=max

const int ledPinY = 9; // Yellow LED pin - active-high
const int ledPinR = 10; // Red LED pin - active-high
int sensorPin = 0; //analog pin 0 to read distance
int ledStateY = LOW;
int ledStateR = HIGH;
unsigned long previousMillis = 0;
unsigned long interval = random(50, 250);
int pukeSound;

void setup() 
{
  Serial.begin(9600); //For testing purposes, to send message to Serial Monitor

  pinMode(ledPinY, OUTPUT);
  pinMode(ledPinR, OUTPUT);

  initSD();  // Initialize the SD card
  initMP3Player(); // Initialize the MP3 Shield
  delay(10000); // allows 10 seconds for initial setup without triggering SFX
}

void loop() 
{
  // This first section is for the flickering candle effect, based on BlinkWithoutDelay
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;
    if (ledStateY == LOW){
      ledStateY = HIGH;
      ledStateR = LOW;
      interval = random(50, 250);}
    else {
      ledStateY = LOW;
      ledStateR = HIGH;
         }
    digitalWrite(ledPinY, ledStateY);
    digitalWrite(ledPinR, ledStateR);
      }


  int val = analogRead(sensorPin);
  Serial.println(val); // Watch the value, and adjust it as needed for proper distance to trigger sfx

  if (val > 250) // This is the number to adjust for distance tuning
  {
      pukeSound = ++pukeSound;
//    Serial.println("Motion detected!");
    uint8_t result = MP3player.playTrack(pukeSound);

    delay(10000); // give it 10 seconds before it will re-trigger
//    digitalWrite(ledPinRED, LOW);

    if (pukeSound == 9){
      pukeSound = 0;
    }
   } 
  }

// initSD() initializes the SD card and checks for an error.
void initSD()
{
  //Initialize the SdCard.
  if(!sd.begin(SD_SEL, SPI_HALF_SPEED)) 
    sd.initErrorHalt();
  if(!sd.chdir("/")) 
    sd.errorHalt("sd.chdir");
}

// initMP3Player() sets up all of the initialization for the
// MP3 Player Shield. It runs the begin() function, checks
// for errors, applies a patch if found, and sets the volume/
// stereo mode.

void initMP3Player()
{
  uint8_t result = MP3player.begin(); // init the mp3 player shield
  if(result != 0) // check result, see readme for error codes.
  {
    // Error checking can go here!
  }
  MP3player.setVolume(volume, volume);
  MP3player.setMonoMode(monoMode);
}    

The first part of the void loop() is for the flickering candle effect, and is a slight variation on the Blink Without Delay sketch. That is definitely a bit of coding with which you should be familiar. You know from your first Arduino sketch that the simplest way to blink an LED is with the delay() command – however, that stops the script from continuing on, so it’s not ideal for most applications. Blink Without Delay works around this, so that you can set the duration of the LED blinks without holding up the rest of your code. For this build, I’ve added a random component to give the blink more of an illusion of a flickering candle.

Behold the Yack-O-Lantern!

Why certainly I want to eat whatever is dribbling out of his mouth!

What is happening

Once you have your Yack-O-Lantern assembled, coded and running, here’s what is actually happening. The infrared sensor is sending out an IR beam. When this beam hits an object - say, a hand reaching for a delicious treat - that beam is reflected back to the IR receiver. However, unlike a LIDAR unit or an ultrasonic sensor, the IR sensor isn’t measuring the time it takes for the beam to return. It’s measuring the intensity of the returned light, so the closer the object, the higher the intensity. If you watch the data being returned in the Arduino serial monitor, you’ll see that the closer an object gets to the sensor, the higher the number the sensor returns.

Behold the Yack-O-Lantern!

Leonardo, is that you?

What’s in your vomit?

Too much? Oh well. So for this demo, I used classic twin snakes gummies, because they were easy for people to grab. I’ve also used guacamole, which looks great coming out of the pumpkin, but requires chips, and is a bit messier. But really, even if you just have little candy bars coming out of the mouth, the effect will still be there. So have fun with carving the face, have fun sourcing the sounds and have a hack-tacular Halloween!

制造商零件编号 DEV-13975
REDBOARD ATMEGA328 EVAL BRD
SparkFun Electronics
¥175.01
Details
制造商零件编号 DEV-12660
SPARKFUN MP3 PLAYER SHIELD
SparkFun Electronics
¥235.66
Details
制造商零件编号 PRT-11417
ARDUINO STACKABLE HEADER KIT - R
SparkFun Electronics
¥14.25
Details
制造商零件编号 SEN-08733
INFRARED SENSOR JUMPER WIRE 3POS
SparkFun Electronics
¥13.48
Details
制造商零件编号 COM-14023
SPEAKER 4OHM 3W TOP PORT
SparkFun Electronics
¥44.77
Details
制造商零件编号 PRT-09835
BATT HLDR AA 4 CELL BARREL PLUG
SparkFun Electronics
¥22.96
Details
制造商零件编号 AP16GMCSH10U1-B
MEMORY CARD MICROSD 16GB UHS
Apacer Memory America
¥211.89
Details
Add all DigiKey Parts to Cart
TechForum

Have questions or comments? Continue the conversation on TechForum, DigiKey's online community and technical resource.

Visit TechForum