views:

103

answers:

5

I have a device which has got 9 keys just like an ordinary mobile phone. I want to print normal alphabets like ABCD using these 9 keys exactly the way mobile phones let you do it.

This is an embedded system programming project. I am unable to figure out the logic to implement this functionality.

I am detecting keys by polling and not by interrupt.

Can someone help? I will appreciate if you can point out related resources as well.

A: 

I think we cannot much help.

The high level logic is straightforward; a key is pressed, you get the first letter from it; if it is pressed again within a certain time, you move onto the next letter for that key.

This is all well and good but is of almost no use to you; and the rest - the details of what/why/where/when - will depend almost entirely on the platform upon which you are developing; exactly which phone, what services it offers you as a C developer, etc.

Without those details, it is impossible to indicate what should be done.

I'm afraid you may not appreciate the nature, level of difficulty and what is involved in your task, given the fact this question is asked as it is asked.

Also, I should point out, what's being asked here is essentially for others to do the whole of this work, which is not what SO is for. We are not a free contract IT worker service!

Blank Xavier
i havent asked anyone to do the work for me, if someone has worked on similar stuff before he can provide me some obvious resources that i might have overlooked. Just like any other site SO too seems to have many people who offer unsolicited advices.
Down voted for unnecessary rhetoric.
Akshar Prabhu Desai
+6  A: 

Here is a little keyboard decoding demo that should get you well on your way. You'll need to rewrite the key scanning routine for your hardware. In addition, there will be some kind of timeout needed to select the same digit twice in a row. You should also have little trouble figuring out how to add support for capitalization, punctuation, and meta keys...

#include <stdio.h>

#define NUM_KEYS 10
#define NUM_PHASES 6

char KeyMap[NUM_KEYS][NUM_PHASES] =
    {   { '0',   0,   0,   0,   0,   0 },
        { '1',   0,   0,   0,   0,   0 },
        { '2', 'A', 'B', 'C',   0,   0 },
        { '3', 'D', 'E', 'F',   0,   0 },
        { '4', 'G', 'H', 'I',   0,   0 },
        { '5', 'J', 'K', 'L',   0,   0 },
        { '6', 'M', 'N', 'O',   0,   0 },
        { '7', 'P', 'Q', 'R', 'S',   0 },
        { '8', 'T', 'U', 'V',   0,   0 },
        { '9', 'W', 'X', 'Y', 'Z',   0 }    };

char KeyGet()
{
    char key;

    /* do whatever it takes to scan your
       keyboard and return the _numeric_ digit. */

    /* for this test simulate with console input */
    key = getc(stdin);

    if ((key >= '0') && (key <= '9'))
    {
        key -= 0x30;
    }
    else
    {
        key = 0;
    }

    return key;
}

char DecodeKey(char NewKey, char *pOldKey, int *pPhase)
{
    char ch = 0;

    /* Validate Phase */
    if ((*pPhase < 0) || (*pPhase >= NUM_PHASES))
    {
        *pPhase = 0;
    }

    /* see if a different key was pressed than last time */
    /* if it was then restart the phase counter */
    if (NewKey != *pOldKey)
    {
        *pPhase = 0;
        *pOldKey = NewKey;
    }

    /* Validate Key */
    if ((NewKey >= 0) && (NewKey < NUM_KEYS))
    {
        ch = KeyMap[(int)NewKey][*pPhase];

        /* if the phase position is NULL, just get the numeric digit */
        if (ch == 0)
        {
            *pPhase = 0;
            ch = KeyMap[(int)NewKey][*pPhase];
        }

        /* bump the phase */
        ++(*pPhase);

        if (*pPhase >= NUM_PHASES)
        {
            *pPhase = 0;
        }
    }

    return ch;
}

int main()
{
    char nk;        /* new key */
    char ok = 0;    /* old key */
    char c;         /* resulting character */
    int phase = 0;  /* tracks the key presses */

    while (1)
    {
        /* get a key */
        nk = KeyGet();

        /* convert it to a character */
        c = DecodeKey(nk, &ok, &phase);

        if (c != 0)
        {
            printf("%c", c);
        }
    }

    return 0;
}
Amardeep
key = getc(stdin); is a blocking call ?
Akshar Prabhu Desai
@Akshar: Yes, it is a blocking call used for this demo. Standard C does not have a non-blocking console input library routine. The implementer needs to write a custom routine for the actual target.
Amardeep
+1  A: 

To do a really good design, you'll need a keyboard input routine which can tell when keys have been held for awhile, and when they have been released for awhile. For a short time after a digit is pressed, you should keep the cursor on the newly-typed character; if the same digit is pushed again, you should change the newly-typed character. If another digit is typed, make the selected digit 'permanent' and show the cursor on the character for the new key. If no key is pushed for a second or so, advance the cursor to the next position. If enter is pushed when the cursor is on a newly-typed digit, just advance the cursor. If it's pushed within about 1/4 second of the cursor auto-advancing, do nothing. If it's pushed when the cursor isn't on a character and hasn't just auto-advanced, confirm entry.

supercat
A: 

Take your controller`s 6 pins for keyboard P0->P6.Connect your 3 columns P0->P3and 3 rows to P4->P6.Make all pins high by code. Scan each rows by giving low on each columns. So by getting the particular row and column you will be able to get the entered key.. Hope you look for this..

arun
A: 

Adapting Amardeep's answer:

char KeyMap[NUM_KEYS][NUM_PHASES] =
{   { '0',   0,   0,   0,   0,   0 },
    { '1',   0,   0,   0,   0,   0 },
    { '2', 'A', 'B', 'C',   0,   0 },
    { '3', 'D', 'E', 'F',   0,   0 },
    { '4', 'G', 'H', 'I',   0,   0 },
    { '5', 'J', 'K', 'L',   0,   0 },
    { '6', 'M', 'N', 'O',   0,   0 },
    { '7', 'P', 'Q', 'R', 'S',   0 },
    { '8', 'T', 'U', 'V',   0,   0 },
    { '9', 'W', 'X', 'Y', 'Z',   0 }    };


//Gets the system time, e.g. as number of timer ticks since power up.  You write this.
sometype GetSystemTime();

//Checks if key has been pressed.  Returns 0-9 if a key was pressed or -1 if no key was pressed.  You write this.
int KeyAvailable();

int main()
{ 
 const sometype PHASE_WAIT = somevalue; //The delay before shifting to the next character.
 char keyBuffer[BUFFER_SIZE]; //The input buffer.
 int  keyIndex = 0; //The index into keyBuffer. 
 int keyPress1 = -1, keyPress2; // keyboard inputs.
 sometype lastKeyPressTime; // The time a key was last pressed.
 int numKeyPresses; // The number of times the same key has been pressed this phase.



 /* keyboard processing loop. */
 while ( 1 )
 {
  if ( ( GetSystemTime() - lastKeyPressTime > PHASE_WAIT ) && ( -1 != keyPress1 ) )
  {
   // Phase timed out.  Commit current character.
   keyBuffer[keyIndex++] = KeyMap[keyPress1][numKeyPresses - 1];
   keyPress1 = -1;
  }
  if ( ( keyPress2 = KeyAvailable() ) > -1 )
  {
   // Key pressed. 
   lastKeyPressTime = GetSystemTime();
   if ( ( keyPress2 != keyPress1 ) && ( -1 != keyPress1 ) )
   {
    // Different than last key.  Commit current character and start a new one.
    keyBuffer[keyIndex++] = KeyMap[keypress1][numKeyPresses - 1];
    numKeyPresses = 1; // Yes, I"m using 1-based indexing.  Deal.

   }else if ( keyPress2 == keyPress1 )
   {
    // Pressed same key multiple times in same phase. 
    numKeyPresses = ((numKeyPresses) % KEYMAPROWSIZE) + 1;
    if ( 0 == KeyMap[keypress2][numKeyPresses - 1] )
    {
     //Loop back to first 'valid' character associated with this key.
     numKeyPresses = 1;
    }
   }else // -1 == keyPress1 
   {
    // Pressed new key. Start new phase. 
    numKeyPresses = 1;
   }
   keyPress1 = keyPress2.
  }
 } 

}
sskuce