Tuesday, May 8, 2012

Digital Magic 8 Ball

Is this one of the coolest projects I've made on the spur of the moment?
 The magic 8 ball is always correct!

I remember I used to have a magic 8 ball key-chain as a kid. I loved asking it the stupidest questions and seeing it magically divine the answer. Either that or it just repeatedly responded with an anti-climatic ask again later. One day the magic just dried up ... literally, the purple fluid in the cavity evaporated! Randomly remembering this device, I decided on the spur of the moment, after learning how to seed and use the rand() function in the standard c library, to make my very own digital magic 8 ball (which would be impervious to drying up, but still vulnerable to releasing its magic smoke).

I've moved on up from the pic16f84a to the 16f886. I know it is overkill for most of what I use it for, but it is great for prototyping because of the large program memory, abundance of peripherals, and gpio. Plus I love using the internal oscillator for anything that doesn't require an accurate clock.

This is the prototyping breadboard I use for everything with the icsp header in the middle, a built in li-polymer battery on the back and integrated charge controller at the top. Ignore the 8 pin dip rtc above the pic, I might add a clock feature and make my magic 8 ball a watch.

The pic starts counting on start up until the user presses the button. This count value (which in effect is somewhat random) then seeds the pseudo random number generator. The number that it comes up with then determines which of the 20 replies the magic 8 ball will give. When the button is pressed again, the user is returned to the main screen asking for another question.

I ported the code I wrote is assembly for the 16f84a which handles spi serial communication in software (I know I could have done it in hardware, but this way was more fun). Then I needed a function to initialize and clear the ram of the oled display. In addition, I ended up having to write a function which would handle parsing strings and generate the data necessary to write them to the graphical display. I wrote most of this months ago and reused code but for a different application. I haven't really optimized anything but everything works and I am happy with it.

The only way to cheat the system is to hold the button or hit it immediately after the main screen loads, which ensures that the count value would be zero, which when seeded into rand() would produce the same value, which will always give the same reply.

I plan on using smt components, ditching the oled pcb, using a CR2032, and polling another button via interrupt so that I can put the micro to sleep and wake it for software power control. The entire device should be not much larger than the 3cm oled (aka perfect as a key-chain). I might think of using an accelerometer or tilt switch and put the oled in the window of an actual magic 8 ball. It would look really cool glowing eerily from the surrounding dark window, magically predicting the future. Might add a clock and fit the entire device to a watch strap so I can wear it around, tell time, and make life altering decisions with it. Maybe I'll add some simple games. Who knows? Either way it will be a great gift for my sister.

Ok ... there's one more question I need to ask it ... magic 8 ball ... will I ever become a famous electrical or computer engineer?
... fine then if you don't want to answer me, who needs you anyway ...

ps. A friend suggested I also make a miniature 20 questions ... hmmmm interesting ... maybe later ...
pps. Since summer is here expect many more projects :-)
ppps. I might make a digital fortune cookie with hundreds of different fortunes. Not too hard if I reuse most of my current code.

Here are the C and hex files for the project: Magic 8 Ball files.

Update: Added Schematic

If you have any questions feel free to shoot below. Enjoy