/* 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. 20.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 #include // defines things like "PORTB" and "TCCR0" etc #include // delay functions //#include "time.h" #include "lcd.h" // LCD Library #include //do I need this?? hmm // Definitions //these are functions you'll call later #define output(directions,pin) (directions |= pin) // set port direction for output #define input(directions,pin) (directions &= (~pin)) // set port direction for input #define set(port,pin) (port |= pin) // set port pin #define clear(port,pin) (port &= (~pin)) // clear port pin #define pin_test(pins,pin) (pins & pin) // test for port pin #define bit_test(byte,bit) (byte & (1 << bit)) // test for bit set #define F_CPU 20000000 //these depend on how you set up the board //inputs = buttons #define button_port PORTD #define button_direction DDRD //do I need this? #define button1 (1 << PD5) #define button2 (1 << PD6) #define button3 (1 << PD7) #define input_pins PIND //All my inputs are in D because I am just such a thoughtful circuit designer // function prototypes void setup(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(); uint8_t rand_num = 0; // random number from prng seeded w/ shake_count //srand(time(NULL)); //sei(); // enable global interrupts lcd_init(LCD_DISP_ON); // initialize display and turn off cursor _delay_ms(6000); //srand(4); //lcd_clrscr(); // clear display and put cursor @ home lcd_puts(" Hi Tom!"); // line 1 //lcd_puts("This part worked"); // line 2 _delay_ms(40000); lcd_clrscr(); //while (is_shakin() == 0); // while nothing is happening // now it detected a shake //_delay_ms(3000); // wait three seconds while(1) { //srand(14); lcd_clrscr(); // clear display and put cursor @ home if (!pin_test(input_pins,button1)){ lcd_clrscr(); rand_num = rand(); // get a pseudo random number from 0 to 255 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(40000); lcd_clrscr(); } else { // do nothing } if (!pin_test(input_pins,button2)){ rand_num = rand(); // get a pseudo random number from 0 to 255 switch (rand_num % 6) // pick an answer { case 0: lcd_puts(" work it!"); break; case 1: lcd_puts("ummmm..........."); _delay_ms(40000); lcd_clrscr(); lcd_puts(".........no"); break; case 2: lcd_puts("ummmm..........."); _delay_ms(40000); lcd_clrscr(); lcd_puts(".........yes!"); break; case 3: //shouldn't ever be here lcd_puts("What would Tim\n"); //line 1 lcd_puts("Gunn say?"); //line 2 break; case 4: lcd_puts(" sun's out\n"); lcd_puts(" guns out"); break; case 5: lcd_puts("dahhling, you\n"); lcd_puts("look fabulous"); break; default: lcd_puts("wear whatever"); } _delay_ms(40000); lcd_clrscr; } else { // do nothing } if (!pin_test(input_pins,button3)){ rand_num = (uint8_t) rand(); switch (rand_num % 7) { case 0: lcd_puts("You are lovable\n"); lcd_puts("and capable"); break; case 1: lcd_puts("Aww, let me call\n"); lcd_puts("the waahmbulance"); break; case 2: lcd_puts("I believe in you!"); break; case 3: lcd_puts("Make it a great\n"); lcd_puts("day... or not..."); _delay_ms(40000); lcd_clrscr(); lcd_puts("...the choice is\n"); lcd_puts("always yours"); break; case 4: lcd_puts("You can do it!"); //lcd_puts(""); break; case 5: lcd_puts("lol you're\n"); lcd_puts("screwed"); break; case 6: lcd_puts("Follow your\n"); lcd_puts("heart!"); break; default: lcd_puts("I love you \n"); lcd_puts("little noodle"); break; } //end of switch _delay_ms(40000); lcd_clrscr; } else { // do nothing } //rand_num = (uint8_t) rand(); // get a pseudo random number from 0 to 255 lcd_clrscr(); // clear display and put cursor @ home } } // functions void setup(void) { // port config DDRC |= ((1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5) | (1<<6)); // set PC0:5 to 1 for LCD OUTPUT //mine are on port c //but I commented out the other stuff, which I think is for the tilt switch he uses? DDRD |= (1<<5); //for that last one, which is on port D // set clock divider to /1 // I don't entirely understand this, I just know it's in all the programs CLKPR = (1 << CLKPCE); CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0); //first initialize the buttons clear(button_port, button1 | button2 | button3); input(button_direction, button1 | button2 | button3); //now you want it listening for these buttons //the buttons are connected to ground on one end, and to the IC on the other end //so, you want the ports to listen for when they become ground, because it means the button is pressed set(button_port, button1 | button2 | button3); //set to higher voltaaage lcd_clrscr(); //srand(3.14159); //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 //I don't think I need interrupts either??? MAYBE?? //EICRA |= ((1<