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: