For about a week now I have been staring at a cellphone charger my friend Caitlin gave me to repair after she had loaned it to some chimpanzees for apparent durability testing. I was debating on whether I had put the repair off long enough, when, with no humans in earshot to ask, I figured I would build a Magic 8 Thing and ask it if I could procrastinate any longer. Was this a lack of motivation to repair a cellphone charger or was it motivation to make a Magic 8 Thing. Irrelevant really as I got both things done in about 10 hours this weekend.
For those who don't know what a Magic 8 Thing is, it is a Magic 8 Ball, made with an ATMega328, an LCD, a surplus mercury tilt switch from a retired thermostat and some code. I call it a "Thing" instead of a "Ball" because my version is both non-spherical and bears no functional resemblance to an actual "Magic 8 Ball". It does, however, have equal effectiveness in helping you make important life decisions.
I wanted to be able to physically shake the thing to illicit a response to my questions. And, since I wanted this project to be done quickly i.e. no ordering parts I was thinking about making a "shake" switch out of a couple of quarters and a pachinko ball. But, instead, while rooting through one of my many "stuff" bins I found an old thermostat with a mercury tilt switch. This has an unanticipated side effect of being able to hear the mercury sloshing around when you shake it. It is cool, it almost sounds like the original Magic 8 Ball that has the answer icosahedron floating in it. If I had my druthers, however, I would have used an accelerometer like a normal human to detect the shakes, but I have none at the moment.
You can see the mercury switch in the picture below. It is hot glued to the lower left of the circuit board. The header at the top connects the LCD which is mounted in the lid of this enclosure. Space and time were limiting factors on this build so, component layout was adjusted accordingly. E.g. jamb the bits in where they fit.
Here is a video of the Magic 8 Thing in action. As you can see, you ask it a question (which I failed to do in the video), shake it and it replies with one of its 20 answers. If you shake it to hard though, it tells you to "Stop It!" then gives you an answer anyway. The sound at the end of the video is my cellphone getting a text message. It has nothing to do with the Magic 8 Thing.
For those who don't know what a Magic 8 Thing is, it is a Magic 8 Ball, made with an ATMega328, an LCD, a surplus mercury tilt switch from a retired thermostat and some code. I call it a "Thing" instead of a "Ball" because my version is both non-spherical and bears no functional resemblance to an actual "Magic 8 Ball". It does, however, have equal effectiveness in helping you make important life decisions.
I wanted to be able to physically shake the thing to illicit a response to my questions. And, since I wanted this project to be done quickly i.e. no ordering parts I was thinking about making a "shake" switch out of a couple of quarters and a pachinko ball. But, instead, while rooting through one of my many "stuff" bins I found an old thermostat with a mercury tilt switch. This has an unanticipated side effect of being able to hear the mercury sloshing around when you shake it. It is cool, it almost sounds like the original Magic 8 Ball that has the answer icosahedron floating in it. If I had my druthers, however, I would have used an accelerometer like a normal human to detect the shakes, but I have none at the moment.
You can see the mercury switch in the picture below. It is hot glued to the lower left of the circuit board. The header at the top connects the LCD which is mounted in the lid of this enclosure. Space and time were limiting factors on this build so, component layout was adjusted accordingly. E.g. jamb the bits in where they fit.
Here is a schematic.
And the code.
/* Program Tile: Magic 8 Thing Filename: ATMega_328_Magic_8_Thing_v1.0_main.c Date: 2011.03.20 Author: Pete Mills http://petemills.blogspot.com/ ATMega328 Ext. Crystal Osc. 8.0- MHz; Start-up time PWRDWN/RESET: 258 CK/14 CK + 4.1 ms */ /* Program description This program uses an ATMega328 to interface an LCD and a Hg "shake" switch. This is actually a mercury tilt switch from a retired thermostat. rand() is called to generate a random value for a switch statement. There are 20 possible answers based on the original "Magic 8 Ball" toy. The responses were found on wikipedia and modified very little. The LCD library is written by Peter Fleury and can be found at http://www.jump.to/fleury You will need to modify lcd.h to fit your port connections. The user is to ask the device a question then shake the unit. The device then responds with one of 20 answers ranging from affirmative to negative and somewhere in between. Don't shake it too hard or it will tell you to "Stop It! before giving you an answer. */ // Includes #include <stdlib.h> #include <avr/io.h> // defines things like "PORTB" and "TCCR0" etc #include <util/delay.h> // delay functions #include "lcd.h" // LCD Library #include <avr/interrupt.h> // Definitions #define LED_PORT PORTD #define LED PD1 // LED pin PORTD Pin 2 // function prototypes void setup(void); int is_shakin(void); // Global volatile uint8_t shake_count = 0; // counts up the mercury switch contacts, overflows for entropy volatile uint16_t seconds = 0; // seconds counter int main(void) { setup(); sei(); // enable global interrupts lcd_init(LCD_DISP_ON); // initialize display and turn off cursor while(1) { uint8_t rand_num = 0; // random number from prng seeded w/ shake_count lcd_clrscr(); // clear display and put cursor @ home lcd_puts("Magic 8 Thing\n"); // line 1 lcd_puts("Ask and Shake"); // line 2 while (is_shakin() == 0); // while nothing is happening // now it detected a shake _delay_ms(500); // wait a second er, half lcd_clrscr(); // clear display and put cursor @ home while (is_shakin() == 1) // wait for the shaking to stop { lcd_puts("Stop It!"); // line 1 _delay_ms(2000); lcd_clrscr(); // clear display and put cursor @ home } srand(shake_count); // seed the prng with shake_count rand_num = (uint8_t) rand(); // get a pseudo random number from 0 to 255 lcd_puts("Magic 8 Thing\n"); // line 1 lcd_puts("Says..."); // line 2 _delay_ms(3000); // the responses... lcd_clrscr(); // clear display and put cursor @ home switch (rand_num % 20) // pick an answer { case 0: lcd_puts("As I see it, yes\n"); // line 1 //lcd_puts("blank"); // line 2 break; case 1: lcd_puts("It is certain!\n"); // line 1 //lcd_puts("blank"); // line 2 break; case 2: lcd_puts("It is decidedly\n"); // line 1 lcd_puts("so."); // line 2 break; case 3: lcd_puts("Most likely.\n"); // line 1 //lcd_puts("blank"); // line 2 break; case 4: lcd_puts("Outlook good!\n"); // line 1 //lcd_puts("blank"); // line 2 break; case 5: lcd_puts("Signs point to\n"); // line 1 lcd_puts("yes!"); // line 2 break; case 6: lcd_puts("Without a doubt!\n"); // line 1 //lcd_puts("blank"); // line 2 break; case 7: lcd_puts("Yes.\n"); // line 1 //lcd_puts("blank"); // line 2 break; case 8: lcd_puts("Yes, definitely\n"); // line 1 //lcd_puts("blank"); // line 2 break; case 9: lcd_puts("You may rely\n"); // line 1 lcd_puts("on it!"); // line 2 break; case 10: lcd_puts("Reply hazy,\n"); // line 1 lcd_puts("try again."); // line 2 break; case 11: lcd_puts("Ask again later.\n"); // line 1 //lcd_puts("blank"); // line 2 break; case 12: lcd_puts("Better not tell\n"); // line 1 lcd_puts("you now!"); // line 2 break; case 13: lcd_puts("Cannot predict\n"); // line 1 lcd_puts("now..."); // line 2 break; case 14: lcd_puts("Concentrate and\n"); // line 1 lcd_puts("ask again."); // line 2 break; case 15: lcd_puts("Don't count on\n"); // line 1 lcd_puts("it!"); // line 2 break; case 16: lcd_puts("My reply is no.\n"); // line 1 //lcd_puts("blank"); // line 2 break; case 17: lcd_puts("My sources say\n"); // line 1 lcd_puts("no!"); // line 2 break; case 18: lcd_puts("Outlook not so\n"); // line 1 lcd_puts("good."); // line 2 break; case 19: lcd_puts("Very doubtful!\n"); // line 1 lcd_puts("LOL"); // line 2 break; default: // you should never be here lcd_puts("IDK\n"); // line 1 } _delay_ms(5000); // display the answer for this long } } // functions void setup(void) { // port config DDRC |= ((1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6)); // set PC0::6 to 1 for LCD OUTPUT DDRD &= ~(1<<2); // set PD0 to "0" for mercury switch input PORTD |= (1<<2); // enable internal pullup DDRD |= ((1<<0) | (1<<1)); // set PD1 to "1" for output - LED PD0 for LCD PORTD &= ~(1<<1); // set the output low // interrupt config // external interrupts EICRA |= ((1<<ISC00) | (1<<ISC01)); // external rising edge interrupt on INT0 EIMSK |= (1<<INT0); // enable external interrupt } ISR(INT0_vect) { shake_count++; } int is_shakin(void) { // this function determines if the unit is being shaken based on the number // of pin state changes in 100mS uint8_t shake_count_first = shake_count; // initial shake count _delay_ms(100); if (shake_count - shake_count_first > 3) // can adjust the shake "sensitivity" here { LED_PORT |= (1<<LED); return 1; } LED_PORT &= ~(1<<LED); return 0; }
Here is a video of the Magic 8 Thing in action. As you can see, you ask it a question (which I failed to do in the video), shake it and it replies with one of its 20 answers. If you shake it to hard though, it tells you to "Stop It!" then gives you an answer anyway. The sound at the end of the video is my cellphone getting a text message. It has nothing to do with the Magic 8 Thing.
So, as I stated in the beginning, this Magic 8 Thing was made to help me decide if I have goofed off enough and should start on the cell phone charger repair. When I posed the the question "Magic 8 thing, have I procrastinated long enough?" it replied with the text in the picture below. Apropos.
Comments
char array[2]={"sd", "fgdgh"]
lcd_put(array[rand_number %2]);
instead of so many repetitive switch case clauses.
If you disagree with me i would like to hear it.
Thank you for the kind words and yes, your suggestion for using a char array (with correct syntax ;)) should work too.
It's great to get different perspectives on how to approach tasks when sharing knowledge like this.
Allison