Hello. I'm an Arduino beginner and I need to do a school project involving an arduino, a keypad and an LCD screen. Overall, I want to create a sort of "switch" key on my 4x4 keypad. I need like 7 or 8 extra characters. I investigated and found out it's called a "macro". I'm not too familiarized with macros in basically anything so I'd like to ask for examples in code on how to do this.
In a broader sense what I want is to press a Key and, while I press this key, press another and have a different character show up as a result. How can I achieve this?
Thanks in advance.
If you talk about this keypad, then look at its few features listed below:
1. There are 16 different keys. You can put any labels on them whatever you like overriding the indicated labels.
2. If you operate this Keypad using Keypad.h Library, then the Keypad works in 2-key lockout system. In 2-key lockout system, you must release the present 'pressed down key' to get the action of the next pressed down key.
GolamMostafa:
If you talk about this keypad, then look at its few features listed below:
1. There are 16 different keys. You can put any labels on them whatever you like overriding the indicated labels.
2. If you operate this Keypad using Keypad.h Library, then the Keypad works in 2-key lockout system. In 2-key lockout system, you must release the present 'pressed down key' to get the action of the next pressed down key.
And how do I program that 2-key lockout system? This is how I programmed my keypad without the "shift" function
If a ‘function’ key is pressed you can set a variable to a defined value, let’s say it is 13.
The next key press is the decoded, based on what function key was previously pressed ‘13’ you do a certain action.
larryd:
If a ‘function’ key is pressed you can set a variable to a defined value, let’s say it is 13.
The next key press is the decoded, based on what function key was previously pressed ‘13’ you do a certain action.
And how I can do that in code using the keypad library?
Thanks for the help.
As you can see, is a calculator. But I also need to be able to get the n-root of a number and the n-power of a number, and it also needs to make operations with hexadecimal and base 20 numbers, so I need to be able to input the letters A through J.
I don't have my circuit schematic in a graphic form but the keypad is conected through pins 0 to 7 (the digital ones) I also connected an LCD screen through pins 8 to 13. Everything works flawlessly so far, but I need to implement all that stuff I talked about.
Pins 0 and 1 are used for serial communications, not a good idea to use these for other things.
What Arduino are you using?
Always show us the complete sketch.
Edit
num1 = num1 + key;
Did you mean:
num1 = (num1 * 10) + (key - ‘0’);
For “n-root”
Maybe pressing / twice in a row could be defined as take the ‘n-root‘.
For “n-power”
Maybe pressing * twice in a row could be defined as take the ‘n-power‘.
For A-J things get messy, time to get a larger matrix keypad.
Pins 0 and 1 are used for serial communications, not a good idea to use these for other things.
What Arduino are you using?
Always show us the complete sketch.
Edit
num1 = num1 + key;
Did you mean:
num1 = (num1 * 10) + (key - ‘0’);
For “n-root”
Maybe pressing / twice in a row could be defined as take the ‘n-root‘.
For “n-power”
Maybe pressing * twice in a row could be defined as take the ‘n-power‘.
For A-J things get messy, time to get a larger matrix keypad.
Well, the sketch as it is woks great. This is the sketch in its entirety:
#include <Keypad.h>
#include <LiquidCrystal.h> // Librería para el control del LCD
LiquidCrystal lcd(8, 9, 10, 11, 12, 13); // varible LCD y pines
const byte filas = 4; // número de filas '4'
const byte columnas = 4; // número de columnas '4'
char teclado [filas][columnas]={
{'1','2','3','+'},
{'4','5','6','-'},
{'7','8','9','x'},
{'*','0','=','/'}
}; //variable teclado
byte filaPines[filas]={7,6,5,4}; //configuración de filas
byte columnaPines[columnas]={3,2,1,0}; // configuración de columnas
Keypad calcu = Keypad (makeKeymap(teclado),filaPines, columnaPines, filas, columnas);
boolean inicio = false;
boolean final = false; // variables de control
String num1, num2;
int ans;
char op;
void setup()
{
lcd.begin(16,2);
lcd.setCursor(0,0);
lcd.print("Hola Mundo"); //Prendido de pantalla
delay (2500);
lcd.clear();
}
void loop(){
char key = calcu.getKey();
if (key != NO_KEY && (key=='1' || key=='2' || key=='3' || key=='4' || key=='5' || key=='6' || key=='7' || key=='8' || key=='9' || key=='0')){
if(inicio == false)
{num1 = num1 + key;
int numLength = num1.length();
lcd.setCursor(15-numLength,0);
lcd.print(num1);
}
else {
num2 = num2 + key;
int numLength = num2.length();
lcd.setCursor(15-numLength,1);
lcd.print(num2);
final = true;
}
}
if (inicio == false && key != NO_KEY && (key == '+' || key == '-' || key == 'x' || key == '/'))
{inicio = true;
op = key;
lcd.setCursor(15,0);
lcd.print (op);
}
if (final == true && key !=NO_KEY && key == '=')
{
if (op == '+')
{ans= num1.toInt() + num2.toInt();}
if (op == '-')
{ans= num1.toInt() - num2.toInt();}
if (op == 'x')
{ans= num1.toInt() * num2.toInt();}
if (op == '/')
{ans= num1.toInt() / num2.toInt();}
lcd.clear();
lcd.setCursor(15,0);
lcd.autoscroll();
lcd.print(ans);
lcd.noAutoscroll();
}
if(key !=NO_KEY && key == '*')
{
lcd.clear();
inicio = false;
final = false;
num1 = "";
num2 = "";
ans = 0;
op = ' ';
}
}
Mmm, buying the IR remote you recommended is probably out of the question. I haven't seen them for sale here, and i'm currently residing in mexico, and this project is due in two weeks.
My professor told us that it was possible to make this shift key stuff i'm talking about, and the things you said about multi-key presses seemed like what i'm looking for. Isn't really a way to program a 4x4 keypad to hold more characters using this multi-key pressing functions?
Make your keys have multiple functions by setting a variable OR adding a switch to your circuit.
example:
0 thru 9 normally give you 0 - 9
Then pressing your separate switch (call it SHIFT) 0 thru 9 now give you A - J
Use an array, offset into the array by the amount represent by the matrix switch.
0 gives array index 0,0 = 0
1 gives array index 0,1 = 1
When your SHIFT switch is pressed, you use a different index.
0 gives array index 1,0 = 10 ten
1 gives array index 1,1 = 11 eleven
int myKeys[2][10] =
{
{ 0,1,2,3,4,5,6,7,8,9}, // new switch not pressed
{ 10,11,12,13,14,15,16,17,18,19 } //new switch pressed as needed A,B,C,D . . . J Base 20
};
OR
Maybe just add a constant to the key pressed ex. 10
larryd:
Make your keys have multiple functions by setting a variable OR adding a switch to your circuit.
example:
0 thru 9 normally give you 0 - 9
Then pressing your separate switch (call it SHIFT) 0 thru 9 now give you A - J
Use an array, offset into the array by the amount represent by the matrix switch.
0 gives array index 0,0 = 0
1 gives array index 0,1 = 1
When your SHIFT switch is pressed, you use a different index.
0 gives array index 1,0 = 10 ten
1 gives array index 1,1 = 11 eleven
int myKeys[2][10] =
{
{ 0,1,2,3,4,5,6,7,8,9}, // new switch not pressed
{ 10,11,12,13,14,15,16,17,18,19 } //new switch pressed as needed A,B,C,D . . . J Base 20
};
OR
Maybe just add a constant to the key pressed ex. 10
Hi, thanks for answering.
That seems like a solution, but i'm not really sure where the output of the OR gate should go.
This is more or less the circuit I made:
I should add, just like you said, a switch and an or gate, the first input of the OR gate should be my switch and the second one should be GND no? So if I don't turn my switch on the OR gate shall always be 0.
Gotcha. I will try it out.
So once I read my A0, how can I proceed to switch my keypad to another one in code? I'm imagining something like this:
if(myShiftSwitchState){
//Initialization of my second keypad, with the extra characters
}else{
//Initialization of my first keypad, with the normal characters
}
An important thing to consider:
1-. If the user turns the switch off, then the keypad must return to its original state, so, I guess I have to introduce everything in a loop? How can I do that?
Another way of doing it is, well, reading your first post where you recommended me the use of an OR gate, how can I apply the use of a different index to switch my keypads?
The Shift function can be handled in one of two ways.
You can write the sketch so the keypad is decoded as A-J as long as the Shift button is pressed.
When the switch is released, the keypad is decoded as 0-9.
You can write the sketch so your Shift switch toggles a variable to true/false.
Pressing the switch the first time the variable is set true, pressing the switch the second time you reset the variable to false.
When true, the keypad is decoded one way, when false it is decoded another way.
Since you have some extra pins, why not add a LED to turn on when you are in Shift mode.
Hi, I tried using an OR gate and a switch to define my shift state, but now the arduino doesn't even turn on. The only way of making it turn on is to disconnect my gate, switch and LED or to upload the program while everything is connected and now the LCD prints odd random characters after my "Hello World" (the message it prints when it turns on).
I read my pin A0 (in analog in) as digitalRead(14) like you told me. My conditional sentence is written as it follows:
if(shiftSwitch = HIGH){
//Etc.
}
This what I do inside my if conditional:
if (key != NO_KEY && (key=='1' || key=='2' || key=='3' || key=='4' || key=='5' || key=='6' || key=='7' || key=='8' || key=='9' || key=='0'))
{ if(shiftSwitch = HIGH){
if(inicio == false)
{switch(key){
/*Cambia el valor introducido de key por su
equivalente en el modo shift*/
case '1':
key = 'A';
break;
case '2':
key = 'B';
break;
case '3':
key = 'C';
break;
case '4':
key = 'D';
break;
case '5':
key = 'E';
break;
case '6':
key = 'F';
break;
case '7':
key = 'G';
break;
case '8':
key = 'H';
break;
case '9':
key = 'I';
break;
case '0':
key = 'J';
break;
}
}
num1 = num1 + key;
int numLength = num1.length();
lcd.setCursor(15-numLength,0);
lcd.print(num1);
}
else
{switch(key){
/*Cambia el valor introducido de key por su
equivalente en el modo shift*/
case '1':
key = 'A';
break;
case '2':
key = 'B';
break;
case '3':
key = 'C';
break;
case '4':
key = 'D';
break;
case '5':
key = 'E';
break;
case '6':
key = 'F';
break;
case '7':
key = 'G';
break;
case '8':
key = 'H';
break;
case '9':
key = 'I';
break;
case '0':
key = 'J';
break;
}
num2 = num2 + key;
int numLength = num2.length();
lcd.setCursor(15-numLength,1);
lcd.print(num2);
final = true;
}
Yeah, this code can be improved but I only wanted to see if it could work.
What did go wrong and what can I try to make it work?
Use CTRL T to format your code.
Attach your ‘complete’ sketch between code tags, use the </> icon in the posting menu. [code]Paste your sketch here[/code]
Thanks for your help Larry, I finally managed to get my shift key running as I intended. I'll post the solution here so anyone wanting to use a shift key in a project using keypad can use this method:
My project circuitry is arranged as the following schematic:
Just add a Switch, and an OR gate to yours as you normally would. One of the inputs of the OR gate must be the switch output and the other must be wired to GND. The output of the OR gate must be wired to any unused port in the arduino. In this case I used A0 just like Larry recommended me.
Having all the hardware out of the way, in the code we'll do the following:
Declare two keypads, one being the keypad in shift mode and the other the regular keypad:
Having done that, in our loop function we'll insert an if statement that'll check if our switch is on or off, and, according to that, will use the corresponding keypad: