Using a 4x3 keypad to enter a filename for an SD card

This is a pretty challenging question! I'm trying to get a filename from this keypad:

I want to filename to only contain capital letters or a space. It can only be 8 chars long max for the SD filename to work (according to the SD library) I'm off to a good start with the below code, but I came to a screeching halt when I don't know how to add letters to the filename, or how to tell if the filename is more than 8 chars long.
To understand how to input letters, I'll have this notice printed on the panel next to the keypad:

ADDING PARTS
When entering the part name, use the keypad as arrow keys to select letters. Up/Down scrolls through letters, Left/Right moves to the previous or next letter. Part names can have a maximum of 8 characters.
Press * when finished, or # to cancel.

Here is the code I've got so far. (The disp.lcd.print is basically the same as LCD.print, etc)

void Add_Part() {
  char newName[13]; //holder for new part name
  //ascii characters A-Z are 65 - 90     space is 32
  int currentLetter = 65; //holder for the letter they're working on

  disp.lcd_cls(); //clear display
  disp.lcd_print(F("ENTER NEW PART NAME"));
  disp.lcd_rowcol(1, 3); //row, col
  disp.lcd_print(F("8 LETTERS MAX"));
  disp.lcd_rowcol(3, 0); //row, col
  disp.lcd_print(F("1:OK        2:CANCEL"));
  while (1) { //wait for keypress
    byte k = checkKeyBuffer(); //get a keypress from the user
    if (k == 1) break; //move on
    if (k == 2 || k == keyTimeout) {
      cancelMsg();
      return;
    }
  } //end of waiting for go ahead
  boolean nameComplete = false;
  while (nameComplete) { //loop until the name is complete
    disp.lcd_cls(); //clear display
    disp.lcd_print(F("NEW PART NAME:")); //print what ever part of the name they made so far
    disp.lcd_rowcol(1, 6); //row, col
    disp.lcd_print(newName); //print what ever part of the name they made so far
    disp.lcd_print(char(currentLetter)); //print the current letter, starts at A
    disp.lcd_print(F("DONE-*      CANCEL-#"));
    while (1) { //get letters
      byte k = checkKeyBuffer(); //get a keypress from the user
      if (k == keyPound) {
        cancelMsg();
        return; //user canceled
      }
      else if (k == keyAsterisk) { //user finished
        nameComplete = true;
        break;
      }
      else if (k == 2) { // = up arrow; letter step increase 
        currentLetter += 1;
        if (currentLetter > 90) currentLetter = 90; //Z is the max
        if (currentLetter == 33) currentLetter = 65; //jump from space back up to A
        break; //exit to refresh screen
      }
      else if (k == 8) { // = down arrow; letter step decrease
        currentLetter -= 1;
        if (currentLetter < 65 ) currentLetter = 32; //anything below A will be a space
        break; //exit to refresh screen
      }
      else if (k == 6) { // = right arrow; advance to the next letter
        //HOW DO I GET THE CURRENT NUMBER OF LETTERS IN newName
        //ADD THIS LETTER TO newName
      }
    }

  }

}

Why not get a 4x4 keypad, 16 keys, make things a little simpler
a/b c/d e/f g/h
i/j k/l m/n o/p
q/r s/t u/v w/x
y/z <- * #
one press for first letter, two for second
<- backspace

  • accept

cancel

something like that
Use Keypad.h library to read the key presses, simple timer for one press/two press
Or use of * or # as a Shift key for the 2nd button.
Or 3 letters per key like old flip phones used for texting, shift key for letters, otherwise you get a # 0 to 9.

To understand how to input letters, I'll have this notice printed on the panel next to the keypad:

The keypad doesn't have up and down arrow keys or left and right arrow keys. Your label needs to be a lot better than that.

You can decrement a counter each time the non-existent left arrow key is pressed, but not allow the counter to drop below 0. You can increment the same counter each time the non-existent right arrow key is pressed, but not allow the counter to go above 7. Then, the value in the counter tells you which letter in the name they are working on.

You won't be "adding letters to the name". You will be modifying an initial set of 8 letters, some (possibly all) of which will be NULL.

Thanks. The 4x4 and/or alphanumeric pad isn't an option in my application though a good option.
The notice about arrow Key's actually has a photo of the number keys being replaced with arrows, which it didn't occur to me would not make any sense without the photo!

I think I understand the counter idea. Reset the 8 char to null and start adding...
Thanks again.

Reset the 8 char to null and start adding...

You misspelled overwriting!

oh yes. :slight_smile:

also, I WILL be able to use this keypad, so that'll really simplify it for the user!

also, I WILL be able to use this keypad, so that'll really simplify it for the user!

How? If the file name is to be "TIGER", how does that keypad, with only 10 keys simplify entering "TIGER"?

ok, so as I'm working on each letter. What is the best approach for getting the correct val from a keypress? If they want 'C', they press 1 three times. This sounds complicated. How do they advance to the next letter? As long as the next letter is a different key, that could advance it, but if they need two letters that come from the same key. Hmmm, I don't know.

How? If the file name is to be "TIGER", how does that keypad, with only 10 keys simplify entering "TIGER"?

Just that it has the letters on it, instead of using arrows. But now, (I just posted the problem) I think maybe arrows is indeed the best approach.

How do they advance to the next letter?

The way cell phones handled this was based on the length of time between presses. Press the 3 key twice in a short period of time to change D to E. Press the 3 key twice with a longer pause between the presses, and you get "DD".

Look at the way the flip phones like Motorola Razor worked.
You wanted C, you pressed 1 three times quick - slight pause, start next letter, could be 111 again for another C, could be something else.

Ok, I think I'll try the arrow key approach to start with.