Electrickery – KMD's Blog

Halloween Project – Magic Wand

by on Oct.22, 2011, under Hacks, Projects

IR wandThis is the first of my Halloween projects (cutting it fine, I know), all of which will be appearing in the Disenchanted Forest!
For those who don’t know what the Disenchanted Forest is, click the link and have a browse.

Harry Potter Candle

Harry Potter Magic Wand & Candle

One of my fellow event organisers found these funky toys on the net one day and set one in front of me to the phrase of “make that do something cool for us!”… After a quick inspection I saw that it was a “Harry Potter Magic Candle“.

Basically what they are is an LED candle with IR receiver and a wand with an accelerometer and IR LED. You strike the wand toward the candle to turn it on and wave it from side to side to turn it off, the accelerometer distinguishes between the different gestures and sends the appropriate signal. The candle also has a microphone in it so if you blow into it you can turn it off, quite cool I thought…. Then promptly threw the candle away!

In the forest we have some StickLEDs, an invention of ours which are basically 1watt waterproof LEDs on sticks which we can use to light the trees along a section of path leading the punters to their next destination. The wand, I thought, would be a fantastic way of letting one of the actors lead a group along by lighting the path ahead with a quick flick of the wrist.

RBBB by Adafruit

RBBB from Adafruit

So, I picked up one of my favourite arduino clones and set to work!

Using this IR Library by Ken Shirriff, I set to work decoding the IR signals from the wand. I assumed that they wouldn’t use any standard protocol but as luck would have it the library allows for decoding and recognising RAW codes. After a little playing around I found that the codes were being read as 85 digits. This wasn’t a problem until I wrote the code to switch a relay on/off when a code was received. Because of the length of the code there was a delay of around a second or more between striking the wand and the relay switching. The library allows for about a 20% margin for error but I could still only get a few feet of range out of the wand.

I went back to the code and started again. This time not making any assumptions about the protocol and to my surprise it turns out that the wand uses the NEC protocol!

After reprogramming I found that not only was the delay now reduced to less than a second, the range had increased to that far I couldn’t test it without being that far into the forest that I lost line of sight!!!

Here’s the code used, it’s a direct copy of Ken’s example but it will change as I add more functionality as the wands are capable of sending 2 diferent signals:

* IRremote: IRrecvDemo – demonstrates receiving IR codes with IRrecv
* An IR detector/demodulator must be connected to the input RECV_PIN.
* Version 0.1 July, 2009
* Copyright 2009 Ken Shirriff
* http://arcfn.com


int RECV_PIN = 11;
int RELAY_PIN = 4;

IRrecv irrecv(RECV_PIN);
decode_results results;

// Dumps out the decode_results structure.
// Call this after IRrecv::decode()
// void * to work around compiler issue
//void dump(void *v) {
// decode_results *results = (decode_results *)v
void dump(decode_results *results) {
int count = results->rawlen;
if (results->decode_type == UNKNOWN) {
Serial.println(“Could not decode message”);
else {
if (results->decode_type == NEC) {
Serial.print(“Decoded NEC: “);
else if (results->decode_type == SONY) {
Serial.print(“Decoded SONY: “);
else if (results->decode_type == RC5) {
Serial.print(“Decoded RC5: “);
else if (results->decode_type == RC6) {
Serial.print(“Decoded RC6: “);
Serial.print(results->value, HEX);
Serial.print(” (“);
Serial.print(results->bits, DEC);
Serial.println(” bits)”);
Serial.print(“Raw (“);
Serial.print(count, DEC);
Serial.print(“): “);

for (int i = 0; i < count; i++) {
if ((i % 2) == 1) {
Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
else {
Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
Serial.print(” “);

void setup()
pinMode(13, OUTPUT);
irrecv.enableIRIn(); // Start the receiver

int on = 0;
unsigned long last = millis();

void loop() {
if (irrecv.decode(&results)) {
// If it’s been at least 1/4 second since the last
// IR received, toggle the relay
if (millis() – last > 250) {
on = !on;
digitalWrite(RELAY_PIN, on ? HIGH : LOW);
digitalWrite(13, on ? HIGH : LOW);
last = millis();
irrecv.resume(); // Receive the next value


:, , , ,

5 Trackbacks / Pingbacks for this entry

Leave a Reply

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!


A few highly recommended websites...


All entries, chronologically...