Matrix keypad component : interrupt and last row / last column key missing problem

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
PeSe_1509996
Level 3
Level 3
25 replies posted 10 sign-ins 5 questions asked

Dear Bob,

First of all thanks your Matrix keypad component.

To cut the story short:

it's works as expected but I've two annoying problems :

 

1.) only works by polling, e.g.: from main loop, like:

if (MyKeyPad_CharReady() != 0) // Check the buffer for a key already entered. Returns != 0 if character available
{
ButtonPressed = MyKeyPad_GetChar();
SW_Tx_UART_1_PutString("Main Loop a button READED: ");
SW_Tx_UART_1_PutChar(ButtonPressed);
SW_Tx_UART_1_PutCRLF();
}

 

but not works from attached interrupt (InterruptType: rising edge setted): the interrupt never fire 😞

 

like:

CY_ISR(isr_KeyPressed_Handler)
{

...

}

 

int main(void)
{

CyGlobalIntEnable;

...

isr_KeyPressed_StartEx(isr_KeyPressed_Handler);

MyKeyPad_Start(Translation_Table);

}

 

2.) I use with 4x4 Matrix keypad, like:

https://www.hestore.hu/prod_10041773.html#

The problem: all keys works, except the last row, last column key ('D'): this does nothing.

(P1[0] and P1[4] intersection)

(I use Cykit 059, Columns P1[3:0], Rows P1[7:4])

 

Would you be so kind to help me to figure out what should be the problem ?

 

Thanks in advance,

Have a nice day,

Peter

 

 

 

 

 

 

 

0 Likes
1 Solution
ncbs
Moderator
Moderator
Moderator
500 replies posted 50 likes received 250 sign-ins

Hi community,

@PeSe_1509996 has shared interrupt based Martix 4x4 keypad sample code here: https://community.infineon.com/t5/PSoC-Creator-Designer/Mixed-Hardware-and-CPU-interrupt-based-Marti...

Thanks to all the users for taking part in an active discussion here. 

"Alone we can do so little; together we can do so much." – Helen Keller

 

Regards,
Nikhil

View solution in original post

0 Likes
12 Replies
PandaS
Moderator
Moderator
Moderator
250 replies posted 100 solutions authored 5 likes given

Hi @PeSe_1509996 ,

To read the button press in a 4x4 keypad, you generally bring each row of the keypad low in a sequential manner. All 4 rows in this case would normally be pulled to a high state. You then read the state of all 4 Columns and see if any of them are low, that is a button press.
 
In this arrangement Interrupts is probably not the best choice because and you still need to have an indefinite loop controlling those sequential changes.
 
Depending on the requirements of the project you can also do the key scan procedure as part of the main code loop, or have the scan done in an interrupt driven by a timer. Please do let me know your implementation.

 

Coming to the questions:

1) Its probably due to the Interrupt trigger being set to Rising Edge. As explained above, the button press is detected when it is pulled to low so configure the interrupt to trigger in falling edge.

2) Are the pins free to use ?, I checked that P1_0 is reserved for SWD. Try to use some other pins.

 

Thanks and Regards

Sobhit

0 Likes

Dear Sobhit,

First of all thanks for your reply.

The theory of reading such a matrix key pads well known -I know as well, see:
https://www.infineon.com/dgdl/Infineon-AN2034_PSoC_1_Reading_Matrix_and_Common_Bus_Keypads-Applicati...

As you can see there are different 'quality levels' of implementation:

-most basic: polling (scanning rows and columns) periodically (e.g. by SysTick or hardware timer).
In this case: You put all row and column pins resistive pull-down mode (to avoid floating) INITIALLY and for NON-SCANNIG (resting time) periode
and during the SCANING:
drive each row to HIGH (sequentially, one after another, only one row HIGH at a time) and sample (read) column lines.
(the problem with this approach: you waste your valuable CPU time !!: in production code we have a lot of other stuff to do with analogue sensors or time critical tasks as in my case).


-interrupt driven: the trick is in this case: you put row pins in resistive pull-down mode and columns pins in HIGH mode INITIALLY and for NON-SCANNIG time and attach a common interrupt for row pins.
Normally, if no key pressed: row pins remains low => no interrupt event occurs.
If any key pressed => rising edge signal produced => interrupt happen (this is the value of interrupt based approach: no polling needed !):
you can read the values : which key pressed. But really: this is not so easy !: not simply read a pressed key ..
Better if we put it that way: interrupt event is a command to start to analize the process (see debouncing methode later)

Note: you can do in an opposite way to achive the same result -as Bob done: "row-pins are defined as resistive pulled up while to the columnlines
is written a "0". "

Let me emphasize: all the above mentioned is USELESS without correct debouncing methode.
(see. as times goes: key pressed in instable state initial (this is why we need debouncing delay), key in stable state, key relased, + you have to take care of the number of stabile readings (see consecutive equal readings), intentional delay for key repetition.)


So, it's clear that we need interrupt based AND debounced solution.
This is why I'm very happy to see somebody else done this hard job and share as component: Bob_Marlowe Matrix keypad component. Thank for her ! 🙂


To answer your questions:
1.) in pdf KeyPad Component clearly written: "KeyPressed – Output ... The signal goes high for about one clock period of the ScanClock so when connected to an interrupt component its trigger must be set to “rising edge”. "
Anyway -based on my knowledge- for PSoC5LP interrupt component there are : rising edge, level, derived modes and NO falling edge mode selectable.
Would you be so kind to help me how to achive falling edge triggered interrupt ?


2.) P1[0] pins: yes, it is reserved for SWD (as P1[1] and P1[3] as well) for default settings.
But you can use this pins (if you don't want to debugging): Desing Wide Resources / System / Programming\Debugging / Debug Select : from SWD to GPIO.

Anyway, let me emphasize: all keys working, in particular 'A', 'B', 'C' keys in SAME COLUMN except 'D'. How it is possible?
Or also from the other side: all keys working, in particular '*', '0', '#' keys in SAME ROW except 'D'. How it is possible?

I mean if the problem would come from P1[0] pin: all other buttons would not work in that row or column.

So, we need Bob or somebody how is familiar with his Matrix keypad component.

Any help ?

Thanks in advance,
Best Regards,
Péter

0 Likes

Hello.

Regarding "D":  possibly a defective switch contact?

I would disconnect matrix from KIT-059 and using an Ohm meter, measure the resistance of a working switch contact.  You might need a second person to assist (to press the switch while you hold DVM probes on corresponding row/colume wires).  Then, measure the resistance of row/colume for "D".

My guess is, "D" has a very high resistance or the row/colume makes no connection at all.

These small keypads don't usually have diodes to provide key-to-key isolation.  However, if it does have diodes, maybe the diode is missing or installed backwards.

Another possibility, "D" is not connected to the designated row/colume shown in picture.  You can use Ohm meter to check other row/colume combinations.  "D" could be shorted to another key contact.

Good luck with your project.

0 Likes

Dear Bibi,

Thanks for your kind help.

You can imagine that was the first check (yesterday) what I did what you recommended:

I've checked off-line with a multimeter / resistance measurement.

see attached pictures:

non-pressed D key: non pushed:  infinite resistance, as expectednon pushed: infinite resistance, as expected

 

pressed D key:

pushed: apprx. 30 Ohm, as expectedpushed: apprx. 30 Ohm, as expected

Anyway:

1.) all other keys have the same behavior, everything is ok / as expected.

2.) I have another  keypad:  everything is ok / as expected.

 

So, there is no hardware failure of matrix keypad hardware.

For your kind information: if you have a 'hook' type (clamp) ending measurement cable / probe, it is very easy to make such measurement by one person (it's me actually).

 

You are right: this matrix keypad has a very simple structure (no isolation diodes), just two pieces of electrically conductive screen printed layer with some dome keys to make a contact if you push that.

 

For your kind information: the problem is:

-we can read the buttons perfectly by a quick-and-dirty solution (similar what Moto shared), but in this case: it's a polling solution, no interrupt driven and no intelligent debouncing mechanism: so we can not use in a production code.

 

-this is the reason why we want to use Bob Matrix Keypad component (interrupt driven, clever debouncing), but in that case 'D' is not working and the interrupt not working (just a polling).

 

So, if is there anybody, who has a practice with Bob_Marlowe Matrix keypad community component with interrupt (not polling based) sample code: it shoul be a big help to share such a sample project.

(unfortunately Bob Matrix Keypad component sample is polling based, there is an interrupt, but it it not working)

 

Matrix keypad component  ISR.JPG

So, this is where we are now.

 

Have a nice day !

 

Péter

 

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

Although I don't know if this can be any help,

I also posted a sample project.

https://community.infineon.com/t5/Code-Examples/4x4-Matrix-Keypad-Sample/m-p/96977#M370

I used SysTick to handle polling, so any time the key condition of the previous cycle is kept in the array.

moto

0 Likes

Dear Moto,

Thanks for your sample project but this is too basic for our real world application,

I mean interrupt driven and debounced solution needed.

Thanks again,

Best Regards,

Péter

 

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Péter-san,

Thank you for your feedback.

I (think I) implemented debouncing and interrupt in software.

Best Regards,

10-Jun-2022

Motoo Tanaka

0 Likes

Dear Motoo,

thanks for your kind help:

First the good news: I readjusted the pins for my layout (one single row of CyKit-059: from P1[7] to P1[0] , Single Wire Debugging OFF at Desing Wide Resources / System / Programming\Debugging / Debug Select : from SWD to GPIO to free 3 SWD pins):

and the problematic 'D'  keys works as expected.

 

Furthermore, I reviewed your code:

-your quick solution for debouncing (see DEBOUNCE_COUNT parameter) not as complete as Bob_Marlowe Matrix keypad component debouncing approach but acceptable.

 

-your solution regarding interrupt is a kind of 'false interrupt' usage: yes, there are two interrupts, but it is attached to Control_Reg, and not for key pins. It is okay for keypress/realease problem handling, but not okay for interrupt driven matrix key pad watching.

So, the real interrupt driven solution should be :

A) no any polling in main loop (see matrix_key_pushed and matrix_key_released).

the sample code main loop must be empty !

B) the interrupt(s) must be attached to key pins directly: this is how the hardware event driven interrupt works: the firmware do not have to poll (ask/read) the key states continuously): if user push any button, this trigger (just start !) the key read process (wait for key contact to stabilize, after that: debouncing -e.g.- watch for N  number of same readings one-after-one, and if it is true: call another interrupt: key pressed.

 

Anyway, thank four  your kind help,

Have a nice day from Hungary !

Péter

 

 

 

 

PeSe_1509996
Level 3
Level 3
25 replies posted 10 sign-ins 5 questions asked

For anybody interested I have found a workaround for missing interrupt problem:

in KeyPad.c file (under components tab) change this:

// Signal Keypress
#ifdef `$INSTANCE_NAME`_KbdControl_Write
`$INSTANCE_NAME`_KbdControl_Write(0x01);
`$INSTANCE_NAME`_KbdControl_Write(0x00);
#endif

 

TO: 

// Signal Keypress:

`$INSTANCE_NAME`_KbdControl_Write(0x01);
`$INSTANCE_NAME`_KbdControl_Write(0x00);

Interrupt driven  Matrix keypad component works as expected.

 

Anyway: the missing 'D' key problem still exists.

 

Best Regards,

Péter

 

 

 

0 Likes
PeSe_1509996
Level 3
Level 3
25 replies posted 10 sign-ins 5 questions asked

Some small progress to fighting regarding only 'D' key  not working:

after resolder and remap pins from Port1 to Port2, a can use debugger.

 

background: my Translation_Table is:

CYCODE char8 Translation_Table[MAXKEYVALUE ] = {
'D', 'C', 'B', 'A',
'#', '9', '6', '3',
'0', '8', '5', '2',
'*', '7', '4', '1'
};

 

Important: the only one problematic 'D' is the first one, with index of 0.

from debug there are only one difference between not working 'D' and all the others  which is working:

in MyKeyPad.c, under the CY_ISR(MyKeyPad_Debounce) routine:

at:

if ((uint8)((~NewKey) & (~Debounced_Keys))== 0xffu) // Nothing has happened
{
Debounced_Keys = NewKey;
return;
}

 

In case of others it is working if push/release a button, but at 'D' key it return : take it as nothing happened.

But evident that  D is pushed, because the breakpoint hitted.

I suspect that since the only button with NewKey and Debounced_Keys value is zero (0) is the 'D' - all the others are non-zero - this could be the problem.

(if NewKey  == 0 & Debounced_Keys == 0, the inverted values will be 1111 1111, and the AND-ed value will be 0xFF.

which is the problem, because this code not possible to hande the first zero key)

 

But in this case, how it should works at the other programmers or even at Bob side ?

Seeems like to be : the first button -in my case key 'D'- is allways neglected (the actual code take it as nothing happend).

 

Is there any trick to do the row/column pin layout ?

 

Any help  appreciated,

Best regards,

Péter

 

 

 

 

 

 

 

 

 

 

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Afaik didn't the original version show that 'D' eror when reading from Debounced_Key where zero means no key pressed. When indexing into the table with a non-zero value subtract 1 from Debounced_Key.

 

Bob

0 Likes
ncbs
Moderator
Moderator
Moderator
500 replies posted 50 likes received 250 sign-ins

Hi community,

@PeSe_1509996 has shared interrupt based Martix 4x4 keypad sample code here: https://community.infineon.com/t5/PSoC-Creator-Designer/Mixed-Hardware-and-CPU-interrupt-based-Marti...

Thanks to all the users for taking part in an active discussion here. 

"Alone we can do so little; together we can do so much." – Helen Keller

 

Regards,
Nikhil

0 Likes