Storing Values of Keys pressed in sequence

Go To Last Post
12 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey Guys

I'm trying to store values of keys presses in a sequence they have been pressed. Each key must only be able to be pressed once until reset has been pressed.

Once all 10 keys has been pressed, a "NEXT" key must be used to display the values on 2 x 7 segment displays in the sequence they were pressed.

Now, my displays are working, I read the keys and display them on the displays. It is just the storing that I am having problems with.

Any ideas on what wil be best and simplest way to store these values?

Here is the code for the reading of the keys and displaying them on the displays as they are pressed.

#include  
#include  
#include  

/******************************************************************************
AVR pins connected to 74HCT164
******************************************************************************/
#define DISP_PORT                PORTB
#define DISP_CLOCK_PIN           1
#define DISP_RSDS_PIN            2
#define DISP_LATCH_ENABLE		 3

/******************************************************************************
Variables
******************************************************************************/
volatile int Key;
volatile int Cntr;

/******************************************************************************
ADC Init
******************************************************************************/
void ADC_Init()
	{
   		ADCSR |= (1<<ADPS1) | (1<<ADPS2); 		// Prescale 64-ADC clock 125kHz 
   												// Leave MUX3-0 ADMUX=0 for ADC0 
   		ADMUX |= ( (1<<REFS0) | (1<<ADLAR) );   // AVCC with external cap
   												// at AREF pin,Left justify    
   		ADCSR |= (1<<ADEN); 					// Enable the ADC 
 	}

/******************************************************************************
Write Shift Register
******************************************************************************/
void 
DISP_load_byte(uint8_t out_byte)
	{
   		DISP_PORT &= ~_BV(DISP_CLOCK_PIN);
    	DISP_PORT &= ~_BV(DISP_LATCH_ENABLE);    
        	int i;
        	for(i=0; i<8; i++)
        		{
                	if (out_byte & 0x80)
                		{
                        	DISP_PORT |=_BV(DISP_RSDS_PIN); 
                		}
                	else
                		{
                            DISP_PORT &= ~_BV(DISP_RSDS_PIN);
                		}
        			out_byte = out_byte << 1;
					DISP_PORT &= ~_BV(DISP_CLOCK_PIN);
					DISP_PORT |= _BV(DISP_CLOCK_PIN);
        		}
		DISP_PORT |= _BV(DISP_LATCH_ENABLE);
	}

/***********************************************************************************
Read Key
***********************************************************************************/
void Read_Key()
 	{
   		ADCSR |= (1<<ADSC); 					// Start conversion 
   		while(! (ADCSR & (1<<ADIF)) ); 			// Wait for ADC conversion complete 
   		ADCSR |= (1 << ADIF);
 	}

/******************************************************************************
Key Detection
******************************************************************************/
void Key_ADC_Val()
	{
		if ((ADCH >= 0x18) && (ADCH <=0x25))
			{
				Key = 0x01;				
			}
		if ((ADCH >= 0x27) && (ADCH <=0x2D))
			{
				Key = 0x02;		
			}
		if ((ADCH >= 0x31) && (ADCH <=0x34))
			{
				Key = 0x03;		
			}
		if ((ADCH >= 0x40) && (ADCH <=0x43))
			{
				Key = 0x04;		
			}
		if ((ADCH >= 0x5A) && (ADCH <=0x5F))
			{
				Key = 0x05;		
			}
		if ((ADCH >= 0x6F) && (ADCH <=0x73))
			{
				Key = 0x06;		
			}
		if ((ADCH >= 0x90) && (ADCH <=0x95))
			{
				Key = 0x07;		
			}
		if ((ADCH >= 0xB0) && (ADCH <=0xBE))
			{
				Key = 0x08;		
			}
		if ((ADCH >= 0xC1) && (ADCH <=0xCE))
			{
				Key = 0x09;		
			}
		if ((ADCH >= 0xDA) && (ADCH <=0xDF))
			{
				Key = 0x10;		
			}
		if ((ADCH >= 0xE9) && (ADCH <=0xEC))
			{
				Key = 0x11;						//Next
			}
		if ((ADCH >= 0xED) && (ADCH <=0xF9))
			{
				Key = 0x12;						//Reset
			}
	}

/******************************************************************************
Main
******************************************************************************/
int main(void)
	{
		ADC_Init();
		DDRC = 0x00;
		DDRB = 0xFF;
		sei();
		DISP_PORT |= _BV(DISP_CLOCK_PIN);

		while (1)
			{
				Read_Key();
				Key_ADC_Val();
				DISP_load_byte(Key);
			}
	}

/******************************************************************************
END*****END*****END*****END*****END*****END*****END*****END*****END*****END****
******************************************************************************/

I am using an Atmega8 running 8MHz internal clock. The Keypad is connected to ADC0 and I'm using PortB, pin 1,2 and 3 for the latch and shift register.

Please help me with any info.

Thank you
mtlost

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I was thinking of using an array but then I noticed I know how to create an array and read values from it, but I have absolutly no idea how to create one that you can write values to and read it back on a later stage.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Create a 10 element char sized array and a pointer to the array. Each time a key is pressed, check the array to see if this key has already been depressed. If it has, then ignore the key. If it's a new key, then store the key to the pointer location, increment the pointer, and wait for the next key. When all keys have been depressed (10), wait for "NEXT" key. Don't accept any other entries until "NEXT". Then display your values and wait for "RESET". When reset is depressed, clear the array and start over.

It would be a good idea for you to create a state diagram, and maybe a flowchart to get the sequence clear in your mind. But once again, sequential storage is best handled with an array and a pointer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Recommended reading:

Kernighan, Brian W. ; Ritchie, Dennis M.: The C Programming Language. Second Edition. Prentice Hall, Inc., 1988.

Stealing Proteus doesn't make you an engineer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

gahelton, Any pointers on how to create the array and how to write a value to it? A sample or tutorial? I've searched AVR freaks but no success.

Thank you for your input, it is similar to what I had in mind.

P.S. I don't have that textbook available.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mtlost wrote:
gahelton, Any pointers on how to create the array and how to write a value to it? A sample or tutorial? I've searched AVR freaks but no success.

Thank you for your input, it is similar to what I had in mind.

P.S. I don't have that textbook available.

Some stylistic comments, if I may:

It's not at all clear why you'd want to have your "Key_ADC_Val()" routine stuff its results in a global variable instead of just returning them. Why not:

int getADCKey(void) { /* .. body .. */ }

?

And "int" datatypes are 16 bits long (two bytes). There's no apparent need for more than 18 different encoded "key" values, so why not just use an 8-bit (single byte) datatype, like "uint8_t" or "int8_t"?

Every one of the "if" statements in your "Key_ADC_Val()" routine will execute each time that routine is called. Admittedly, execution speed isn't likely to be a concern here, but once your code identifies the key code it wants to deliver, none of the other "if" statements need to execute. Changing the routine so that it actually returns the decoded value would make this avoidance of unnecessary "if" comparisons very easy; your clauses would look like this:

uint8_t getKeyID(void)
{
    // Maybe include the running of the ADC here too?

    // Let's just read the ADC result once, OK?
    //
    uint8_t analogKey = ADCH;

    if ((analogKey >= 0x18) && (ADCH <= 0x25))
    {
        return 0x01;
    }
    // and so on

Next, why do you want to avoid producing a new "key" result for so many ranges of possible ADC results? If the ADC produces a value less than 0x17, or 0x26, 0x2e, 0x2f, 0x30, 0x35..0x3F, 0x44..0x59, and many others, none of your "if" conditions will be matched.

If this is intentional (one possible reason being that your wierd analog keyboard presents one of these "no key" voltages when none of its keys are being pressed), your original code would simply leave whatever previous result had gone into your "Key" variable unchanged. How were you planning on detecting whether a key had been pressed or not?

But to your question of how you'd create the array, it would look something like this:

uint8_t keysHit[MAX_POSSIBLE_KEYS];

,where MAX_POSSIBLE_KEYS appears to be 0x12. Accessing the array to detect whether a particular keycode has been recorded yet would be pretty straightforward:

    uint8_t keypress = getKeyID();
    if keysHit[keypress]++ {
        // error processing...
        // And we have to reset all the slots
        // of the "keysHit" array:
        //
        for (int8_t i = MAX_POSSIBLE_KEYS; 0 <= --i;) {
            keysHit[i] = 0;
        }
    } else {
    // code to do whatever happens to good,
    // nonrepeated keys goes here
    }
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Search the internet for "C Arrays" and "C Pointers". Here are a few links.

http://www.cplusplus.com/doc/tutorial/arrays.html
http://www.cplusplus.com/doc/tutorial/pointers.html

There a lots of sources of information on the internet, some with better explainations than others. Keep in mind that arrays and pointers are closely related.

Also, as someone else suggested, if you are going to be programming in C, one of these books needs to be on your bookshelf.

http://www.amazon.com/Programming-Language-Prentice-Hall-Software/dp/0131103628/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1215874947&sr=8-1

This is the C programmers reference. There have been additions to the C Standard since this book was written, but you should have this book in addition to any others you might find useful.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mtlost / ArnoldB :-
Please permit me to point :-
GOOGLE : Edited out incorrect.
India_AVR

-----------------------------------------
Wonderful world of "0"s & "1"s
-----------------------------------------

Last Edited: Wed. Jul 16, 2008 - 07:10 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Still working on the arrays.

Still saving up for a copy of my own. I know I need to get that K&R bible as a few persons already told me about it.

Thank you.

Last Edited: Tue. Jul 15, 2008 - 08:30 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

IMO the AVRfreaks site is not a place to encourage theft of copyrighted material. I will now contact one of the moderators and ask him to edit or remove india_avr's post above.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl :-
Sorry for the misunderstanding, thanks.
India_AVR

-----------------------------------------
Wonderful world of "0"s & "1"s
-----------------------------------------

Last Edited: Wed. Jul 16, 2008 - 07:11 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I would have liked to edit if out myself, but now I am unable to.

If you hit this again then it really is as simple as clicking that [Edit] button in the bottom right of the posts you've made above.