brutal_magnet:
Hi! I have a problem compiling your code error says "multi_tap_threshold was not declared in this code". What should be the value of multi_tap_threshold and where should I declare it?
here's my code and I'm not sure if this is correct. I'm not good in programming though.
Just do #define multi_tap_threshold 1000
This is the time the function waits until a letter is confirmed. Say you press "2" three times, and wait for 1000 ms then the letter C becomes the output. If you want a longer wait, you can increase the 1000.
Updated code:
I made changes so that you only see the real output, the C, not the temporary such as A then B then C.
The multi-tap only works well on a display, not a serial port, although you can do your preliminary test over a serial port, you can't render a character in place.
#include <Keypad.h>
#define multi_tap_threshold 1000
#define RESET_MTP '~'
const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
int pointer;
char keys[ROWS][COLS] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}
};
byte rowPins[ROWS] = {11,6,7,9}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {10,12,8}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup(){
Serial.begin(9600);
}
void loop()
{
int mtKey=0;
byte key=keypad.getKey(); // Get a key press from the keypad
mtKey=multi_tap(key); // Feed the key press to the multi_tap function.
if(!(mtKey&10000000B)) Serial.print(mtKey);
}
int multi_tap(byte key)
{
static boolean upperCase=true;
static byte prevKeyPress=NO_KEY,cyclicPtr=0;
static unsigned long prevKeyMillis=0;
static const char multi_tap_mapping[10][5]={{'0','#','
,'.','?'},{'1','+','-','','/'},{'A','B','C','2','!'},{'D','E','F','3','%'},{'G','H','I','4','('},{'J','K','L','5',')'},{'M','N','O','6','@'},{'P','Q','R','S','7'},{'T','U','V','8',','},{'W','X','Y','Z','9'}};
if (key==RESET_MTP) // Received reset command. Flush everything and get ready for restart.
{
upperCase=true;
prevKeyPress=NO_KEY;
cyclicPtr=0;
return 0;
}
if (key!=NO_KEY) // A key is pressed at this iteration.
{
if ((key>'9')||(key<'0')) // Function keys
{
if ((key==1)||(key=='#')) // Up for case change
{
upperCase=!upperCase;
return 0;
}
else // Other function keys. These keys produce characters so they need to terminate the last keypress.
{
if (prevKeyPress!=NO_KEY)
{
char temp1=multi_tap_mapping[prevKeyPress-'0'][cyclicPtr];
if ((!upperCase)&&(temp1>='A')&&(temp1<='Z')) temp1+='a'-'A';
cyclicPtr=0;
prevKeyMillis=0;
switch (key)
{
case 2:
// Call symbol list
return 0; // Clear the buffer.
break;
case 3:
prevKeyPress='\b';
break;
case 4:
case '':
prevKeyPress=' ';
break;
case 5:
prevKeyPress='\n';
break;
case 6:
prevKeyPress=NO_KEY; // Clear the buffer.
break;
}
return(256+(unsigned int)(temp1));
}
else
{
prevKeyPress=NO_KEY;
cyclicPtr=0;
prevKeyMillis=0;
switch (key)
{
case 2:
// Call symbol list
return 0; // Clear the buffer.
break;
case 3:
return (256+(unsigned int)('\b'));
break;
case 4:
return (256+(unsigned int)(' '));
break;
case 5:
return (256+(unsigned int)('\n'));
break;
case 6:
return 0; // Clear the buffer.
break;
}
}
}
}
if (prevKeyPress!=NO_KEY)
{
if (prevKeyPress==key)
{
char temp1;
cyclicPtr++;
if ((multi_tap_mapping[key-'0'][cyclicPtr]==0)||(cyclicPtr==5)) cyclicPtr=0; //Cycle key
prevKeyMillis=millis();
temp1=multi_tap_mapping[key-'0'][cyclicPtr];
if ((!upperCase)&&(temp1>='A')&&(temp1<='Z')) temp1+='a'-'A';
return ((unsigned int)(temp1));
}
else
{
char temp1=multi_tap_mapping[prevKeyPress-'0'][cyclicPtr];
if ((!upperCase)&&(temp1>='A')&&(temp1<='Z')) temp1+='a'-'A';
prevKeyPress=key;
cyclicPtr=0;
prevKeyMillis=millis();
//Print key on cursor+1
return(256+(unsigned int)(temp1));
}
}
else
{
char temp1=multi_tap_mapping[key-'0'][cyclicPtr];
if ((!upperCase)&&(temp1>='A')&&(temp1<='Z')) temp1+='a'-'A';
prevKeyPress=key;
prevKeyMillis=millis();
cyclicPtr=0;
return ((unsigned int)(temp1));
}
}
else // No key is pressed at this iteration.
{
if (prevKeyPress==NO_KEY) return 0; // No key was previously pressed.
else if (millis()-prevKeyMillis<multi_tap_threshold) // Key was pressed previously but within threshold
{
char temp1=multi_tap_mapping[prevKeyPress-'0'][cyclicPtr];
if ((!upperCase)&&(temp1>='A')&&(temp1<='Z')) temp1+='a'-'A';
return((unsigned int)(temp1));
}
else // Key was pressed previously and threshold has passed
{
char temp1=multi_tap_mapping[prevKeyPress-'0'][cyclicPtr];
if ((!upperCase)&&(temp1>='A')&&(temp1<='Z')) temp1+='a'-'A';
prevKeyPress=NO_KEY;
cyclicPtr=0;
return(256+(unsigned int)(temp1));
}
}
return 0;
}