Friday, November 28, 2014

The Head Move Donkey

In 1978, I bought a wind-up donkey for my daughter, then an infant. The donkey moved its head while playing “Donkey Serenade.”  I figured that I could replicate that with an Arduino, a motor, sound on an SD card, and a speaker.  It took me 10 weeks, but I did it. Here’s the story.

I got sidetracked for a while doing my Halloween Candy Cauldron, which came out of this one. While I was working on the donkey, learning about playing sound with an Arduino, I began seeing lots of Halloween projects on Adafruit shows, so I decided to try my hand on Halloween sounds.

This was an incredibly rewarding project that was challenging, fun, interesting, and educational—all the reasons I wanted to start with Arduino in the first place!

Here’s a video, and another pre-completion, and there are links to two appearances on Adafruit’s Show-And-Tell under “Resources” below.

Parts List (about $80 in parts done this way, assuming you have all the tools and supplies)

2.1mm power plug and jack (doesn’t matter what you get as long as they match)
Micro SD Card
Speaker (I used a 2” 8ohm speaker from an MFC printer I took apart)
Sound editing software, like Audacity
Hook-up wire (I used 22 gauge solid wire to connect the speaker, and to run from the terminal block on the PWM board to the power connector because that was easier
Adafruit silicone-coated stranded wire in various colors (very flexible--helpful for connections inside the enclosure)
Header pins (male, female, and right-angle)
Soldering iron and accessories
Heat Shrink tubing
Dremel or similar tool for cutting out the stand-offs on the enclosure
Drill and bits for making holes in the enclosure (1 for the power jack and 1 for the wires to the speaker and servo)
Electrician’s tape to keep stuffing out of the wire hole
Sewable Velcro strips for closing up the donkey
Needle and thread

Step 1:  play music
First, I located and downloaded the song from .
Using a Seeed Studio SD shield, the TMRpcm library and this tutorial ( I was able to play the song. Note the need for specific sound file format, that’s where Audacity came in. I also shortened the song to delete a couple of the more jazzy parts.  Nothing against the music, but this is a child’s toy. The sound needed amplification so I tried the diy amp from   but did not get much improvement (NPN and PMP transistors, etc.).

Step 2:  operate servo
I had a micro servo and an example from Jeremy Blum’s tutorial ( and got that to work fine.

Step 3: put it together
I could get the servo to move or the music to play, but not both. With help from Adafruit support (, buying a PWM breakout board (, and some soldering, I got it to work. The problem was a timer conflict.

Step 4: getting small
I asked Becky Stern, Director of Wearable Technology at Adafruit, for some advice on getting all this in a donkey. She answered my question on Wearable Wednesday (~21:30)!  I also needed to change some components. First I swapped out the Arduino Uno for a Pro Mini 5V (I thought).  Next I bought a microSD breakout to replace the shield. The Micro SD runs on 3.3V, so I thought I needed a voltage regulator and maybe something else ( ).  In the process I found out that the 5V pro mini was really a 3.3V, and figured out that that was really what I wanted (power the Pro Mini, the amplifier, the PWM board, and the servo from the battery, and power the SD from the Mini).

Step 5: refine
I figured out how to play the song in a loop without resetting the Arduino (TMRpcm.loop(1)). In the process of doing all this I cooked my Mini—it won’t put out 3.3V anymore (more like .9V) so I’m back on the Uno until my 3V Pro Trinket comes next week.  I also decided to go with a 6V coin cell holder with switch ( ) for power.  I gave up on the amplifier and put in an LM386 circuit.  It works OK, but I also ordered an amplifier breakout ( just in case I can’t get the sound I want out of a smaller speaker.

Step 6: construction
Donkey arrived 10/4/2014.  It will accommodate a small project box, servo, speaker, and battery holder. Now I need to be sure I can get the whole circuit on a board small enough to fit into the enclosure. The Altoids tin will fit in the donkey, but I also have a project box if I can’t get the circuit in the Altoids tin.
Programming the Pro Trinket was somewhat flaky at first. I needed to install the hardware updates for the Arduino IDE so it would recognize the board. Also, had to set the programmer to USBTinyUSB. When that didn’t work (“can’t find USBTiny”) I discovered I needed the Windows drivers.  After I got that all done I was able to upload the example blink program, so I’m in business, I think. Now I need to solder the headers so I can test the circuit. I have another Pro Trinket coming tomorrow, so I will use that for the real thing, soldering directly, but I’ll need this one with the headers anyway. UPDATE:  there may be an issue with the ProTrinket and device recognition on Windows (or at least my Windows systems).  I got it to work with Ubuntu, and in the process discovered that the upload took longer than the bootloader was active, so I have to wait to press the reset button to activate the bootloader, but leave enough time in the compile process for it to initialize.  Kind of a pain, but it’s working. I never did get it working on Windows 7 (that may be my fault), but it’s working OK on Windows 8 and Ubuntu.

Step 7: more construction
I tested the 6V coin cell battery, and the power lights on the boards come on but no music and no motion.  I need find another power source. I’m considering a 9V with a voltage regulator to bring it to 5V. A 4bXAA works (6V) but it’s big. Also I got the Adafruit mono amp, and it puts out more volume than the LM386. I also takes up a lot less space. Next, I got some SMT breakout boards ( so I’ll see if I can solder the TSSOP-28 PCA9685 to it and save more space. That didn’t work—not skilled enough. I will try to make a DIY breakout. I shorted something and cooked my amp, just got new amps today and will try again. The servo moves but no music…hopefully the new amp will get me back where I was. The new amp fixed the problem. I decided to stick with the Adafruit PCA9685 PWM board because my surface mount skills are not there yet.

Step 9: The enclosure
I got a 4x2x1 enclosure from Radio Shack.  I fixed an Adafruit 1/8 size Perma-Proto Board to the enclosure with a screw, and drilled a ½” hole for a power receptacle and a 3/8” hole for the servo and speaker wires. In another 3V Pro Trinket, I soldered female headers to A4&A5 and Adafruit silicone coated flexible wires to the pins I need for the circuit. I put right angle headers on the I2C pins of the PWM board, so I can slide those into the female headers and have the bigger board flat with the Trinket on its side perpendicular to the PWM board. All the power and ground connections will go to the Perma-Proto Board + and - rails, with the power connector supplying those rails.  The power supply will be an Adafruit 4xAA battery pack with switch so there is an external switch  access to batteries for changing without opening the donkey, and less space to take up inside.

Step 10: new Trinket
I tried wiring up the circuit with the new, newly soldered Trinket. It powers up, and puts out 3.3V on that
Rail, but it does not play sound or move the motor. Either I did not wire it correctly or there is something wrong with my soldering.  More testing tomorrow.
The next week:  I wired it up again.  After some fussing with connections I got the whole thing to work. I spent some design time on the enclosure, so on to soldering/enclosing.

Step 11: The enclosure, part 2
Day 1:  I discovered that I could not fit the Perma-Proto board and the other components in the enclosure.  The next size larger is too big for the donkey.  Also, the internal stand-offs in the enclosure were in the way, so it was redesign time.  I moved the power connector/receptacle from the end to the side to give more room. I used my Dremel knock-off tool to cut out the internal standoffs. Now everything fits.  Without the Perma-Proto Board, I will need to connect the wires for power and ground directly to the connector. Next I got to soldering:
1.       I connected a 2.1mm jack (to plug into the power receptacle) to the battery pack and covered the splices with heat shrink tubing.
2.       I soldered new, solid core wire leads to the speaker.  Solid core works better in the terminal blocks.
3.       I connected solid core wire to the external power terminal block on the PWM board, and ran them under the board to the power connections.
4.       I removed the jumper wires from the amplifier, and soldered wires directly to the header pins.  The A- and GND wires to go to GND, the Vin to go to power, and the A+ pin is soldered to the wire going to digital pin 9 on the Trinket (SpeakerPin).
So far, so good. Tomorrow I’ll replace the six jumper wires on the SD card with direct soldered connections, and test the audio. Assuming that works, I’ll do the 4 remaining wires on the PWM board.

Step 11: The enclosure, part 3
It works!  Without the circuit board there was a lot of soldering. I soldered all the power leads together, two at a time, adding the next one in turn until I had one lead to connect to the power connector + lead, then did the same with the grounds, to the – lead.  I left the jumper wires on the SD board because they’re pretty secure and didn’t want to risk cross-connections due to sloppy soldering.  I did solder leads to the headers for Vcc and GND on the PWM board.  For the SD board, I cut and stripped the jumpers and connected them to the correct leads:
·         GND to the GND complex
·         3.3V to the 3.3V pin on the Trinket
·         SPI pins to the leads I already had soldered to Trinket pins 10-13
I used heat shrink tubing on the splices to protect the connections from touching.
Everything fits—I can close up the enclosure and secure it with screws. The music plays and the servo moves.
Tomorrow: open up the donkey.

Step 12: the donkey 1
I used an x-acto knife to cut the donkey’s belly along a seam, and took out some stuffing.  I got the servo in the neck, and it will turn the head, but I need to fix it to something solid so the horn of the servo turns the donkey instead of the donkey holding the horn while the servo turns. Meanwhile, I stripped the plastic gears on the servo.  This is the second servo I’ve ruined.  So, I ordered two new servos, one micro and one standard, both with metal gears from Adafruit. Hopefully one of them will do the trick.

Step 13: the donkey 2
I used the standard servo. It’s substantial, and it does the trick. I was able to close up the enclosure and screw on the cover with only one mishap: the ground lead on to the power connector broke and I had to de-solder/re-solder it.  I pulled more stuffing out of the head to get the servo in closer. It moves a little, but with more stuffing, it should be even better than it is now.  There’s a little interference from the servo (actually I think it’s from the PWM board) but it’s OK.
Next: sew on the Velcro and re-stuff.

Step 14: the donkey 3
First, I sewed on strips of Velcro that I had cut to the length of the slit in the donkey’s belly.  I’m not great at sewing, so it was a little frustrating, but I got through it.  Next, I tried different positions for the servo to get it to move the head. I re-stuffed the neck to try to keep the servo in position, placed the speaker, re-stuffed the rest of the donkey put the enclosure in and closed the Velcro.  After one more iteration to get the servo better positioned, it’s done.  I’d like more range of motion on the head, but it does move.

Step 15: futures
1.       I’d like to get more movement from the Servo. I have to experiment with different horns, different positions, and different programming.  I was time-limited on this one—I needed to have it ready for Thanksgiving Dinner, so I haven’t been able to pursue more options yet.
2.       I would shorten the wires inside the enclosure, and probably move the power connector to the end of the box (rather than coming up from the bottom). 
3.       I’d also like to find a box that fits the components a little better, and to fasten the boards to the enclosure (right now, they’re loose, and any jostling by grandchildren may disconnect something). I think I could put standoffs on the end of the enclosure for the Trinket and the bottom for the PWM Board.
4.       Rather than connect the Pro Trinket to the PWM board via right-angle headers, I might want to solder wires directly from the holes on the Trinket to the holes on the PWM board.
5.       To accomplish #3 and other improvements, I would need to hold off on soldering header pins to any components until I know how I really want to wire up and solder the whole project. I soldered the headers first thinking generically, then when I got inside I found that some of the pins were in the way.
6.       I’d like to see if I can make a PCA9685 breakout on my own to save space. New Year’s Resloution #1:  get some SMT soldering skills.
7.       Investigate 60MHz vs 50MHz on the Servo (see comment in sketch)

Circuit as laid out on a breadboard


Presentation on Adafruit Show-and-Tell
In-Process about minute 13 to 16:30
Finished about 4:50 to 6:45
Discussion on Wearable Wednesday




Sound from SD:

Micro SD:

TMRpcm library

Power servo

PWM/Servo Breakout


Increase volume (LM386)

Amplifier I used

Servo I finally used

Arduino Sketch

/*September-November 2014
Uses TMRpcm library to play music from and SD card, and Adafruit_PWMServoDriver library to drive the servo.
Some comments are from example code that came with those libraries
Objective is to move the donkey's head with the servo while playing "Donkey Serenade.
When I was on the Uno and had the serial monitor, I used an led to prove that I was moving through the loop. That is now commented.
Circuit uses the Adafruit Class D mono amp, Adafruit PWM servo board driving a micro servo, a micro SD card board, an 8 ohm speaker, and a 4xAA batter holder
It now runs on an Adafruit 3V Pro Trinket, feeding 3V to the SD card and using battery power for the Trinket, Servo, PWM board, and amp
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

// called this way, it uses the default address 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// you can also call it with a different address you want
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);

#include <SD.h> // need to include the SD library
#include <TMRpcm.h>           //  also need to include this library...


// Depending on your servo make, the pulse width min and max may vary, you
// want these to be as small/large as possible without hitting the hard stop
// for max range. You'll have to tweak them as necessary to match the servos you
// have!
#define SERVOMIN  200 // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX  350 // this is the 'maximum' pulse length count (out of 4096)
/*SERVOMAX reduced from 600 in example to 500 to save the servo (I stripped the gears on one already).  That gave me ~160 degrees. 
I reduced it again to 350, so it goes ~90 degrees: 45 to left and 45 to right if I have the motor and horn positioned properly. That's what I want

// our servo # counter

#define SD_ChipSelectPin 10  //using digital pin 4 on arduino nano 328 2014-09-03 changed to 10 to match datalogger
//#define ledPin 5   //pin to control led   2014-10-25 testing
int angle = 0;   // servo position in degrees
uint8_t servonum = 0;
TMRpcm speaker;   // create an object for use in this sketch

void setup(){

  speaker.speakerPin = 9; //11 on Mega, 9 on Uno, Nano, etc
  speaker.loop(1); //2014-10-03 play repeatedly
  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
       Serial.println("SD initialized");
  speaker.volume(1);"hmd.wav"); //play Donkey Serenade each time the arduino powers up, or is reset (as of 2014-10-03, plays repeatedly)
  pwm.setPWMFreq(50);  // Analog servos run at ~60 Hz updates (says Adafruit--I found that 50 worked better with my servo from Radio Shack—never set it back for the Adafruit servo)

void loop()

//blink led to show arduino is looping through this whether servo moves or not
//  digitalWrite(ledPin, LOW); // 2014-10-25 testing only
//  digitalWrite(ledPin, HIGH); //testing
    for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
    pwm.setPWM(servonum, 0, pulselen);
    delay (100); //was 50, doubling the delay to move the head more slowly
  delay(1000); //pause when limit is reached
  for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
    pwm.setPWM(servonum, 0, pulselen);
    delay (100);
  delay(1000); //pause when limit is reached


Saturday, November 1, 2014

Halloween Candy Cauldron

Here I am demonstrating this project on the Adafruit Show and Tell--my video feed wasn't working too well that night, but I got a Sticker!

While I was working on an Arduino project that involved sound, all the Adafruit shows I watch were talking about Halloween.  So, I decided to do a Halloween project. Here's a short video demonstration

It will be more elegant next year (see "Future" below), but here's how it went.


The video really says it all. When someone reaches in the cauldron for candy, the cauldron shrieks/laughs/says boo/howls/etc, A distance sensor detects the hand, and code on the Arduino then plays one of 9 sounds stored on an SD card at random, through an amp to a speaker. That's it.


The only real issue I had was with the sound files.  It took me a while to diagnose because I had some other dumb things going on at the sane time, but the key is that the TMRpcm library I used is fussy about file formats. See the "Software" section below--basically, I had to download a free sound editing program and convert the files to a format that worked.  

Also, I cooked an amp (not sure how, but there was smoke).  When I installed the replacement it didn't work, Then I noticed a blob of solder where it shouldn't be (probably my fault--left from when I soldered the headers and terminal block).  I got out my soldering iron and solder sucker, removed the blob, and it worked fine. 

I don't know if my problem with the PIR sensor was me or the sensor.  I have a replacement that I will try when I have time--for next year, anyway--but the ultrasonic distance sensor worked fine, so that't what I used.

I did have to work on the code to find the right value to test for from the sensor, but that is to be expected (see "Software" below).

I used the Adafruit Class D Mono amp because my DIY amps were not loud enough.  It's very inexpensive, reduces complexity, and takes less space (but does require a little soldering).


Cost depends on what you have on hand.  Assuming that you have an Arduino, a usable speaker, and the support stuff like wire, batteries, breadboard, SD cards, etc., the rest of what you need should cost under $15.You may have some of the other components, and that would bring the cost down.  If you don't have an Arduno, you can buy an UNO for ~$18.  Smaller boards are less expensive (as low as $5), but you may need to do some soldering and you may miss some features (and necessities like cables to connect to the IDE on your computer).

This project does not require a lot beyond a basic understanding of how an Arduino works. It's probably possible to buy all the components and get this to work. However, if you don't know what the Arduino IDE is, for example, you might want to read up a little. I recommend that anyone who is new to Arduino and/or microcontrollers get a starter kit like this or this or this, and find some tutorials like Jeremy Blum's or the Adafruit Learning System. I got mine for Christmas last year and I'm having a ball!

What you'll need
  1. Cauldron: (I got mine from CVS for $1.99)
  2. Arduino Uno: (I'll use a smaller board next year, like an Adafruit Pro Trinket)
  3. Arduino IDE
  4. Seeed Studio SD shield: (worked fine, but I'll use a breakout next year to conserve space--like this one)
  5. Adafruit Class D Mono Amp: (I tried two DIY amps--one with complementary NPN/PNP transistors and one with an LM386 IC, but neither was loud enough. The Adafruit amp for $3.95 is plenty loud, takes up much less space, and has many fewer connections).
  6. HC-SR04 distance sensor: (I could have used a PIR motion sensor, but I think the one I had wasn't working, and the distance sensor worked so I stuck with it)
  7. Speaker: I  harvested a 4" 8Ohm speaker from a clock radio that had an issue with a power surge; any speaker that works with your amp will do (4-8Ohms for the Adafuit)
  8. Audacity (or similar) for editing sound files (see "Software" below)
  9. Half-size Breadboard
  10. Hook-up wire
  11. SD Card that fits (I used an 16G standard size for this shield)
  12. 9V Battery
  13. Snap connector with 2.1mm jack: I bought a jack at Radio Shack and soldered it to a snap connector that I had
  14. Utility knife for cutting the cauldron
  15. Maybe a soldering iron and basic soldering skills, but this can be done without any soldering.
  16. Small project enclosure (if you decide to go the whole way; in that case you'll also need a drill to make holes in the enclosure to connect to power, the sensor, and the speaker)


HC-SR04 at top, speaker on right, amp on breadboard, sd shield stacked on Arduino Uno

Speaker:  the leads go to the corresponding connections on the amp. I soldered the terminal block to the amp, so my speaker connects there.

4 pins: 5V and GND to 5V and GND
Echo and Trigger Pins to digital pins as defined in sketch (I used D7 and D8, respectively).

speaker as above
A+ pin goes to the speaker pin (Digital 9 in my sketch)
A- to GND
Vin to 5V rail

The shield just stacks on the UNO's headers.
For a separate breakout there are 6 connections: the 4 SPI connections (CS to CS as defined in the sketch--mine is Digital 10, MOSI to D11, MISO to D12, CLK to D13), 3.3V rail, and GND.
Note that some smaller boards only operate at 5V or 3V logic. In another application, I used a 3V Pro Trinket, powered the SD from 3.3V on the Trinket and powered the Trinket and all other components off the battery.
If you have a 5V board, you may need a voltage regulator and a logic level shifting board to get the SD card to work (a solution to that is the Adafruit board that can handle 5V--more expensive, but less work).

9V to barrel  jack
5V to breadboard + rail
GND to breadboard - rail
Other pins are  connected as described for individual components:
D9 to amp A+
D7 & D8 to HC-SR04 Echo and Trigger
For the SD Shield, all Arduino pins for SD are handled by stacking the shield, but (only) if you're using an SD breakout board:
D10 to CS, D11 to MOSI, D12 to MISO, D13 to CLK, 3V to power in
Close-up (a little fuzzy) view of amp and Arduino


I used the Arduino TMRpcm library to play the sound. First, I needed sounds, so I went to and downloaded some sounds (I selected 9).  I discovered that TMRpcm wants specific formats and sampling rates (check the wiki).  I had do download Audacity and use it to convert to 16Khz sampling rate and 8-bit PCM wave format. Once I did all that, I copied the files to the SD card.

The Arduino code checks the distance sensor, which returns time for a roundtrip of the sound in milliseconds.  Since sound travels 29.1 cm/ms dividing by 29.1 yields cm per round trip. Since we only care about the one-way distance, we divide that by two.  In my case, the cauldron is about 15cm wide, so I checked for <12cm (meaning that if it finds something closer than that, it's probably someone reaching in for candy.

The Serial stuff allows me to use the serial monitor for debugging.  I first had the distance sensor set at 16cm and that caused it to always see the other side. Using the serial monitor showed me what was going on--it was returning 15cm every time, always <16, so it always played a sound.

The random function returns a number from 1 to 9, and the sketch requests one of the 9 sounds accordingly. I have a long if/elseif construct to do this.I wanted to put the filenames in an array and just reference the one I want using the random number as an index, but the IDE did not like that. I also tried a switch/case construct that did not work. I'm sure I did something dumb in one or both of those cases. This code works, but I have more stuff to investigate.

/*******************Arduino Sketch*******************/

Halloween Candy Cauldron: Play random sound when someone reaches in for candy
/*2014-10-05 HC_SR04 Distance sensor code added
Needed 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)

#include <Wire.h>   //SPI
#include <SD.h>     //need to include the SD library
#include <TMRpcm.h> //library for playing sound

#define SD_ChipSelectPin 10  
#define trigPin 8
#define echoPin 7

int song = 0;   // song number for random function

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
  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
       Serial.println("SD initialized");
  speaker.volume(1); //may  make it louder
void loop() {
  long duration, distance;
  digitalWrite(trigPin, LOW);  
  digitalWrite(trigPin, HIGH);
//trigPin must me high for 10 microsecs to do ranging
  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;
//2014-10-05 If distance is <6in (~16cm) someone put his hand in
//2014-10-20 12cm works better in the cauldron I bought
  if (distance < 12)  
      song = random(1,10); //get random number from 1 to 9
      Serial.print("song: "); //for debugging
      Serial.println(song); //for debugging
    if (song == 1)          {"1.wav");
     } else if (song == 2 ) {"2.wav");
     } else if (song == 3 ) {"3.wav");
     } else if (song == 4 ) {"4.wav");
     } else if (song == 5 ) {     "5.wav");
     } else if (song == 6 ) {"6.wav");
     } else if (song == 7 ) {"7.wav");
     } else if (song == 8 ) {"8.wav");  
     } else  {"9.wav");
  //      case 1:
//        sound = songs[song];
//          Serial.println(sound);

    Serial.print(distance); //for debugging
    Serial.println(" cm"); //for debugging
/*************************end sketch**********************/


Since I didn't have the circuit enclosed, I put the Uno with the SD shield stacked on it, and the breadboard with the Amp plugged into it, at the bottom of the cauldron. I fixed the HC-SR04 under the lip of the cauldron top using hookup wire. The cauldron was black and has circles for faux handles on the sides, so I cut one of those out and fixed the speaker facing out with hookup wire.  After making the connections as described above, I cut out a circle of cardboard for the candy to rest on while protecting the speaker.  Aggressive hands had a tendency to pull the wires and disconnect them (hence the enclosure for next year).

I found that I needed the battery outside of the cauldron so I could detach it easily and also could swap out batteries as they drained. When the battery gets under 8V the circuit becomes erratic.That takes a few hours, depending on the battery quality.

One note: if the candy is piled too high, the sensor detects it and always returns a value less than 12cm, so the sounds play repeatedly, not just when someone reaches in.
Cauldron with cardboard insert--note battery on left


Next year, I'll use a larger container. I will also use a project enclosure to protect the boards and wires. I'll use a Pro Trinket or the like with an SD breakout board. I may also try replacing the ultrasonic distance sensor with a PIR motion sensor. The sensor and the speaker will be external to the enclosure.  
I'll also work on the power.  I need access to the battery for changing, so it will probably stay outside. A switch would be nice, so I don't have to disconnect the battery to conserve power while the cauldron is idle.

Happy Halloween! 

This was fun!