April 10, 2012
by 4bits4e4
|
// 4bits Nerdkit MasterMind on Atmel 168.
// by 4bits4E4
//Development release: 1.1.0.20120404
//
// license agreement: FREE & CLEAR
// Be a member of the Free Software Foundation: http://www.fsf.org/
// Respect the code: http://www.gnu.org/copyleft/gpl.html
//
// What could be more random than human timing? This random number generator
// uses the human machine to yield a real random number between 1 and 9.
// The flow of the program gaurantees the first answer will always be 0.
// Press the menu key at least once to generate a random number.
// A fun brain teaser program demonstating simple random number generation
// Guess my number! You simply answer the query for the value of A.
// The program guides you to the correct answer by letting you know if
// your guess is High or Low and tracks the number of guesses as your score.
// 4bits Nerdkit requires the simple keypad, the LCD, the Piezo sounder.
// Have fun improving the code. Solve the first num always = 0.
//////////// Gobble up memory with lots of libraries //////////////
#define F_CPU 14745600
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <inttypes.h>
#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"
//////////////////Header file stuff /////////////////
//Inputs
#define row0 (1<<PB3)
#define row1 (1<<PB4)
#define row2 (1<<PB5)
//Outputs
#define col0 (1<<PB0)
#define col1 (1<<PB1)
#define col2 (1<<PB2)
#define piezo (1<<PC0)
//Prototype declarations
void keypad(void);
void guess_my_number(void);
int blips();
void whistle(void);
//Globals
uint8_t screen=1; //The screen we are working in.
uint8_t scancode; //keypad return val
uint8_t rand_num; //
uint8_t a; // number to guess
//////////////////// Init routine /////////////////////////////
void init()
{
//Keypad matrix port setup
DDRB = ~(1<<DDB5)|~(1<<DDB4)|~(1<<DDB3); //rows = Inputs 10k ohm pull downs
DDRB = (1<<DDB2)|(1<<DDB1)|(1<<DDB0); // cols = outputs
PORTB = ~(1<<PB3)|~(1<<PB4)|~(1<<PB5); // pullups off
//LCD commands
lcd_init();
lcd_set_type_command();
lcd_write_byte(0x0f); //set cursor on and blinking
//Set up sound port
DDRC |= (1<<PC0);
PORTC |= piezo;
return;
}//end
///////////////bcd////////////////// SCREEN 1 ///////////////////////
////|--------------------|
////| |
////| Guess My Number |
////| CORRECT You Win! |
////| Guess= 8 Score= 2 |
////|--------------------|
//////////////////////////
void guess_my_number()
{
//uint8_t a=0;
uint8_t answer=0;
uint8_t score=0;
screen=1;
loop:
blips(2,40,80);
answer=0;
score=0;
lcd_clear_and_home();
lcd_line_two();
lcd_write_string(PSTR(" Guess My Number"));
lcd_line_three();
lcd_write_string(PSTR(" "));
lcd_line_four();
lcd_write_string(PSTR(" Guess= Score="));
lcd_goto_position(3,7);
a=rand_num;
while(screen==1)
{
////////////////////////////////////////////
keypad(); //getkey
if(scancode) //if key
{
switch(scancode) //find key
{
case 0x0a: answer+=1;break;//"UP"
case 0x22: answer-=1;break;//"DOWN"
case 0x12: if(answer==a) //"SELECT"
{
lcd_line_three();
lcd_write_string(PSTR(" CORRECT You Win! "));
score+=1;
whistle();
}
if(answer<a) //"SELECT"
{
lcd_line_three();
lcd_write_string(PSTR(" Too LOW "));
blips(1,100,255);
score+=1;
}
if(answer>a)
{
lcd_line_three();
lcd_write_string(PSTR(" Too HIGH "));
blips(1,255,100);
score+=1;
}
break;
case 0x0c: goto loop;break; //"NEW GAME"
}//endswitch
//Update screen display after each key press
lcd_goto_position(3,7);
lcd_write_int16(answer);
lcd_goto_position(3,16);
lcd_write_int16(score);
lcd_goto_position(3,7);
scancode=0;
}//endif
}//endwhile
return;
}//end
///////////////// Sounds ///////////////
void click()
{
uint8_t k;
for(k=0;k<10;k++)
{
PINC |= piezo;
delay_us(20);
PINC &= ~piezo;
delay_us(20);
}
return;
}
int blips(num,dur,freq) //Beep num times, duration, frequency
{
uint8_t k;
uint8_t j;
for(j=1;j<=num;j++)
{
for(k=0;k<dur;k++)
{
PINC |= piezo;
delay_us(freq);
PINC &= ~piezo;
delay_us(freq);
}
delay_ms(freq);
}
return(0);
}
void whistle()
{
uint16_t k;
for(k=40;k<1220;k+=5)
{
PINC |= piezo;
delay_us(k);
PINC &= ~piezo;
delay_us(k);
}
for(k=1220;k>40;k-=10)
{
PINC |= piezo;
delay_us(k);
PINC &= ~piezo;
delay_us(k);
}
return;
}
////////////////////Keypad scancode generator///////////////////////////
//PORTB 0 1 2
///// |------------|
///// 3 |09 | 0A | 0C| Use 10k ohm pull-down resistors on inputs.
///// |------------|
///// 4 |11 | 12 | 14|
///// |------------|
///// 5 |21 | 22 | 24|
//// |------------|
void keypad()
{
uint8_t column;
uint8_t row;
uint8_t row_high = (PINB & 0x38);
scancode=0;
if(row_high); //then key pressed
{
delay_ms(50);
for(column=0;column<3;column++)
{
PINB |= (1<<column); //Walking 1, PB0=0 ,1 ,2
for(row=3;row<6;row++)
{
row_high = (PINB & 0x38); //Read port and mask columns
if(row_high) //then key found
{
click();
scancode = PINB; //1 col and 1 row
while(scancode == PINB)
{
rand_num+=1;
if(rand_num>9)
{
rand_num=1;
}
}
}//endif
}//endfor
PINB &= (1<<column); // Turn off walking one
}//endfor
}//endif
return;
}//end
//////////////////////////MAIN ///////////////////////////////
int main()
{
init();
/////////////////////////////////
while(1)
{
guess_my_number();
}
return(0);
}
////////////////////// * NOTES:////////////////////////////////
////////// LCD MAP //////////////////Keypad //////////////////////
///____________________
//|00000000001111111111|
//|0123456789ABCDEF0123|
//|--------------------| _PB0
//|44444444444444445555| | _PB1
//|0123456789ABCDEF0123| | | _PB2
//|--------------------| | | |
//|11111111111122222222| |----|----|----|
//|456789ABCDEF01234567| PB3--|0X09|0X0a|0x0c| NOTE: Use 10k ohm
//|--------------------| |----|----|----| PULL-DOWN resistors
//|55555555555566666666| PB4--|0x11|0x12|0x14| on PB3,4,5
//|456789ABCDEF01234567| |----|----|----|
//|--------------------| PB5--|0x21|0x22|0x24|
// |----|----|----|
//168 Memory Map///////////////////////////////////////////////////
//32 Registers ------------ 0x000-0x01F
//64 I/O Registers -------- 0x020-0x05F
//160 Ext I/O Registers --- 0x060-0x0FF
//SRAM -------------------- 0x100-0x4FF
//EEPROM 512 bytes -------- 0x500-0x6FF
//Flash (w/boot section) -- 0x000-0x1FFF
|
April 25, 2012
by Ralphxyz
|
Now 4bits4e4, once again this should be posted in the Nerdkit Community Library.
I really like your button press routine and the whole thing actually.
Now I know it is here, so if, some time in the future, I want to reference it I can search the forum for "Guess" and probable find it.
But of course I have to remember the key word and that it is here.
Anyone coming after today probable will never see another reference to it so it will not be readily available.
Where as in the Library we have a ready reference to a lot of neat projects and code examples.
Posting to the Library is the same as posting here in the forum, it uses the same stupid Markdown syntax.
Let me know if you want some help offline, rhulslander gmail com.
No I will not do it, well I might but don't know when.
Ralph |
April 25, 2012
by Rick_S
|
Sorry 4bits, I forgot your name... I purchased a 4x4 keypad that has 4 row and 4 column pins. I think that should work for this correct? It looks like you are using either a 3x3 with 3 row/3column pins or a 4x4 and only using 3x3 of it. Your game caught my attention and got me thinking more. Years ago, (probably about 20 years ago) I wrote a program in quickbasic that was a guess the three letter word game. I actually went through Websters dictionary and hand typed a list of every 3 letter word I could find. I was thinking that could be a neat game to port if I can find the old source to get my list
I'm going to see if I can find that old source... It may be long lost though...
If it is though, it could make for an interesting new project.
Rick |