Harry Potter Party Sorting Hat Ceremony

For my daughter McKenzie’s 11th birthday, we threw her a Harry Potter Party (Harry Potter was 11 when he first entered Hogwarts), and I wanted the attendees go through a Sorting Hat Ceremony. My idea was to sort the attendees into the four Hogwarts houses and have them participate in “classes” and compete for the House Cup at the famous wizarding school.

I had picked up a animated Sorting Hat from Universal Studios Orlando as prop for the ceremony. It moved and looked as if it were talking and calling out Hogwarts’ houses at the press of a button on the brim of the hat. Ideally, I wanted to hack the animated Sorting Hat with a remote switch, which would allow me to activate the hat and choose the house the attendees would be placed in (in order to keep the houses evenly distributed and circumvent disappointment of being sorted into the “wrong” house). However, I ran out of time to completely achieve this.

I woke up at 6:00 AM on the day of the party and gathered my materials on the kitchen table to get something together:

  • an Arduino
  • the Adafruit Wave Shield
  • Simple RF 315MHz T4 Receiver
  • Keyfob 4-Button Remote
  • Speaker

The Wave Shield uses the following pins on the Arduino:

  • D2
  • D3
  • D4
  • D5
  • D10
  • D11
  • D12
  • D13

Because I was using a Arduino Nano, I had to wired the Arduino to the Wave Shield using jumper cables. If using a Arduino Uno R3, you would just stack the Wave Shield on top of the Uno.

I inserted the Simple RF 315MHz T4 Receiver onto a breadboard and wired the following pins to the Arduino:

  • Simple RF 315MHz T4 Receiver GRD Pin -> Arduino GRD Pin
  • Simple RF 315MHz T4 Receiver +5V Pin -> Arduino 5V Pin
  • Simple RF 315MHz T4 Receiver D0 Pin -> Arduino A0 Pin
  • Simple RF 315MHz T4 Receiver D1 Pin -> Arduino A1 Pin
  • Simple RF 315MHz T4 Receiver D2 Pin -> Arduino A2 Pin
  • Simple RF 315MHz T4 Receiver D3 Pin -> Arduino A3 Pin

After some extensive Googling, I came across Bachmann1234’s Github Project and “borrowed” the Harry Potter and Sorcerer’s Stone movie audio clips. Unfortunately, Ravenclaw House was never announced in the movie, hence why the poor quality of Ravenclaw.

I based my Arduino sketch upon the daphc example in the WaveHC Library, which plays every found .WAV file on the SD card in a loop. However, instead, my sketch would “listen” for a button press from the Keyfob 4-Button Remote, play a randomly selected Sorting Hat introduction saying and then announce the appropriate Hogwarts house according to which button was push.

Here is the code to my sketch:

#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 playing

WaveHC wave; // This is the only wave (audio) object, since we will only play one at a time

/*
* Define macro to put error messages in flash memory
*/
#define error(msg) error_P(PSTR(msg))

long opening;
const byte BUTTON_THRESHOLD = 50;

void setup() {
// put your setup code here, to run once:
Serial.begin(9600); // set up Serial library at 9600 bps for debugging

putstring_nl("\nWave test!"); // say we woke up!

putstring("Free RAM: "); // This can help with debugging, running out of RAM is bad
Serial.println(FreeRam());

// 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!)
error("Card init. failed!"); // Something went wrong, lets print out why
}

// 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 🙁
error("No valid FAT partition!"); // Something went wrong, lets print out why
}

// 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)) {
error("Can't open root dir!"); // Something went wrong,
}

// Whew! We got past the tough parts.
putstring_nl("Files found (* = fragmented):");

// Print out all of the files in all the directories.
root.ls(LS_R | LS_FLAG_FRAGMENTED);

randomSeed(analogRead(4));
}

void loop() {
// put your main code here, to run repeatedly:

byte a = analogRead(3); // Gryffindor
byte b = analogRead(2); // Hufflepuff
byte c = analogRead(1); // Ravenclaw
byte d = analogRead(0); // Slytherin

if ( a > BUTTON_THRESHOLD ) {
// FOB button A is pressed... Gryffindor.
openingLine();
Serial.println("GRYFFINDOR!");
playcomplete("1house.wav");
}
if ( b > BUTTON_THRESHOLD ) {
// FOB button B is pressed... Hufflepuff.
openingLine();
Serial.println("HUFFLEPUFF!");
playcomplete("2house.wav");
}
if ( c > BUTTON_THRESHOLD ) {
// FOB button C is pressed... Ravenclaw.
openingLine();
Serial.println("RAVENCLAW!");
playcomplete("3house.wav");
}
if ( d > BUTTON_THRESHOLD ) {
// FOB button D is pressed... Slytherin.
openingLine();
Serial.println("SLYTHERIN!");
playcomplete("4house.wav");
}
}

// 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();
}

/////////////////////////////////// HELPERS
/*
* print error message and halt
*/
void error_P(const char *str) {
PgmPrint("Error: ");
SerialPrint_P(str);
sdErrorCheck();
while(1);
}
/*
* print error message and halt if SD I/O error, great for debugging!
*/
void sdErrorCheck(void) {
if (!card.errorCode()) return;
PgmPrint("\r\nSD I/O error: ");
Serial.print(card.errorCode(), HEX);
PgmPrint(", ");
Serial.println(card.errorData(), HEX);
while(1);
}

void openingLine (void) {
opening = random(1,7);
switch (opening) {
case 1:
playcomplete("ahright.wav");
Serial.println("Ah right then!");
delay(700);
break;
case 2:
playcomplete("allhere.wav");
Serial.println("You could be great you know. It's all here in your head.");
delay(700);
break;
case 3:
playcomplete("d-cult.wav");
Serial.println("Hmmm. Difficult. Very difficult.");
delay(700);
break;
case 4:
playcomplete("iknow.wav");
Serial.println("I know!");
delay(700);
break;
case 5:
playcomplete("rightok.wav");
Serial.println("Hmmm. Right. OK!");
delay(700);
break;
case 6:
playcomplete("whattodo.wav");
Serial.println("I know just what to do with you!");
delay(700);
break;
case 7:
playcomplete("where.wav");
Serial.println("Plenty of courage I see. Not a bad mind either. There's talent. Oh, yes, a thrist to prove yourself. But where to put you?");
delay(700);
break;
}
}

I put together a short video outlining the Sorting Hat. Check out the end of the video as I had live-streamed the sorting of the party attendees and show a clip of my nephew being sorted:

January 31, 2016 Shop Log

  • Last night, Jill and I won the fourth grade class auction project, and it is on temporary exhibit at MakerCave.

    On temporary exhibit at MakerCave…

  • I drilled a 2″ hole in the table top of the Electronics Workspace and slipped in the Tankstation into place. Now I can charge my electronic devices to my heart’s content. 
  • I made another electronics tool caddy for my larger tools that wouldn’t fit in the first tool caddy.

    Larger Electronics Tool Caddy

  • I managed some additional improvements on my Printrbot Simple Metal base, like this swing arm for the Raspberry Pi.

    Raspberry Pi Swing Arm in the Closed Position

    Raspberry Pi Swing Arm in the Open Position

  •  I also added a small storage box.

    Small Storage Box on Printrbot Simple Metal Base

  • Too often, when doing an annual event, you often just throw things immedaitely back into storage until the next year and forgot get about any problems or issues. Here is my attempt not to do that. The attachment apparatus for the light string support poles to the hotel tables is not very stable. We have been taping or zip-tying the mounts to the table legs. For next year, I would like to make a clamping mechanism, which would be more stable.

    Redesign Notes for the Mounting of Poles for Light Strings for OLL Auction

January 22, 2016 Shop Log

  • Started to assemble some semblance of an electronics workspace

  • I managed to separate the USB micro connector from the Printrbot electronics board. I used my Sparksfun Rework Station for the first time to reset the connector back onto the board. Now to see if it worked…
  • No, the USB micro connector detached from the board as soon as I plugged in the cable, and now the connector looks suspect. I either have to find another connector or get another Printrbot board.
  • Add a work light to the electronics workspace

  • Better yet…if I could salvage an old micro USB connector from another junk device!

January 17, 2016 Shop Log

  • Added second layer of cherry-colored wood filler

  • Sanded away the wood filler and filled the inage with gray paint

  • Cutting a side wall of the Baefong Radio Charging Bank on the Shapeoko

  • Baefong Radio Charging Bank Holder

    Assembled the Baefong Radio Charging Bank Holder

  • Cleaned up my sloppy paint job by sanding away my mistakes

  • Bolted my platform to the Printrbot Simple Metal for easier transport

  • I broke the 3mm tap in one of the holes I drilled into the base of the Printrbot Simple Metal. I need to remember to utilize the proper drillbit size. I used a #40 size bit and should have used a #39 size bit. Live and learn.