I am using a PIC16F877A (http://www.kynix.com/Search/PIC16F877A.html), running at 20 MHz.
I have two paralleled, 3 columns, 4 rows keypad. My setup is as follows:

KR1 to KR4 are rows, KC1 to KC3 are columns, and they all go to the microcontroller.
In the program, rows are set as digital outputs and columns are set as digital inputs. Other peripherals of the pins are disabled. The way I scan the keys is as follows:
I make the first row bit HIGH, then I check column 1, column 2 and column 3. If any of them is HIGH, then I wait a little and check again to de-bounce. If it is still HIGH, the program decides that a key is pressed. This routine follows for the other 3 rows.
I check the keypad about every 100 ms, and for each row, it takes about 2.4uS as I measured with the oscilloscope. That, I guess, means, for a specific digit; set it high then try to measure for about 800nS, if nothing happens, move on.
So the problem was weird. Every digit worked, except from '0'. It worked randomly and that random means rarely at the same time. Also, when I tried to measure its voltage to the ground with a multimeter in DC volts mode, and then pushed the button at the same time, it worked for every press.
Then I added a delay of 5 uS after making the specific row HIGH and then I checked the columns. It worked!
Now, what is the problem here? The keypad wires are about 30 cm (~12 inches) long. Is it some kind of a transmission line problem, like it is adding a delay? Or is the problem is sourced from the microcontroller; the microcontroller is not fast enough?
Here is a portion of the code that is relevant to the issue:
... KEY_R4 = 1; delay_us(5); if (KEY_C1) { scan_keys.waitstate = 10; goto c4r1; } else if (KEY_C2) { scan_keys.waitstate = 11; goto c4r2; } else if (KEY_C3) { scan_keys.waitstate = 12; goto c4r3; } else { KEY_R4 = 0; presstime = 0; } ... c4r2: if (++presstime >= PRESSTIMEVALUE && !KEY_C2) { scan_keys.waitstate = 0; KEY_R4 = 0; return '0'; } return 'n'; ...
I have two paralleled, 3 columns, 4 rows keypad. My setup is as follows:

KR1 to KR4 are rows, KC1 to KC3 are columns, and they all go to the microcontroller.
In the program, rows are set as digital outputs and columns are set as digital inputs. Other peripherals of the pins are disabled. The way I scan the keys is as follows:
I make the first row bit HIGH, then I check column 1, column 2 and column 3. If any of them is HIGH, then I wait a little and check again to de-bounce. If it is still HIGH, the program decides that a key is pressed. This routine follows for the other 3 rows.
I check the keypad about every 100 ms, and for each row, it takes about 2.4uS as I measured with the oscilloscope. That, I guess, means, for a specific digit; set it high then try to measure for about 800nS, if nothing happens, move on.
So the problem was weird. Every digit worked, except from '0'. It worked randomly and that random means rarely at the same time. Also, when I tried to measure its voltage to the ground with a multimeter in DC volts mode, and then pushed the button at the same time, it worked for every press.
Then I added a delay of 5 uS after making the specific row HIGH and then I checked the columns. It worked!
Now, what is the problem here? The keypad wires are about 30 cm (~12 inches) long. Is it some kind of a transmission line problem, like it is adding a delay? Or is the problem is sourced from the microcontroller; the microcontroller is not fast enough?
Here is a portion of the code that is relevant to the issue:
... KEY_R4 = 1; delay_us(5); if (KEY_C1) { scan_keys.waitstate = 10; goto c4r1; } else if (KEY_C2) { scan_keys.waitstate = 11; goto c4r2; } else if (KEY_C3) { scan_keys.waitstate = 12; goto c4r3; } else { KEY_R4 = 0; presstime = 0; } ... c4r2: if (++presstime >= PRESSTIMEVALUE && !KEY_C2) { scan_keys.waitstate = 0; KEY_R4 = 0; return '0'; } return 'n'; ...
Comment