The Matrix
“Unfortunately, no one can be told what The Matrix is. You’ll have to see it for yourself.” ― Morpheus
for this blog we could change it to something more meaningful like below :)
“Unfortunately, no one can be told what The Matrix Keyboard is. You’ll have to Do it for yourself, and learn.”
Sensing Inputs
MCU interacts with real world using sensors and actuators. In this blog, lets consider the sensors. There are different types of sensors that can be sensed by MCU to measure different parameters in real world for control purposes.
The ‘Humble Switch’
One of the simplest input sensors we can read from the MCU is the ‘digital switch’.
Switch Configurations
There are different configurations possible to connect switch to your MCU. Which variant to choose depends on the particular application or use case.
Switch with Pull-Up resistor
Here, a resistor is connected to switch and pulled up to supply. When the switch status is,
- Closed - Output is at Low-State.
- Open - Output is at High-State.
Switch with Pull-Down resistor
In case of switch with pull-down resistor configuration the output level of circuit is inverted as below.
- Closed - Output is at High-State.
- Open - Output is at Low-State.
Matrix Keypad
If the applicaton has few switches, one of the above configurations will suffice. Let’s consider if there are 16 switches needed for an application then, 16 IO pins are needed from MCU! Due to limited number of IO pins available, we may not be allocate 16 IO pins for keyboard.
One way to reduce the IO pin requirements is to arrange the keys in matrix keypad configuration. One such 4x4 configuration is shown above. Here, we use 8 IO pins and detect upto 16 switches. There are different configurations possible like, 3x3, 3x4 or 5x5 etc ….
Pro’s and Con’s of different switch configurations
Ofcourse there are both pro’s and con’s for each method as listed below
- Discrete(pull-up/pull-down) configuration:
- Advantages
- Simple circuit.
- Simple SW.
- Dis-advantages
- More switches need more IO pins.
- Advantages
- Matrix configurations
- Advantages
- Less number of IO pins needed.
- Can be adapted to different configurations as needed.
- Dis-advatages
- Complex circuit for keypad.
- SW complexity is more to decode a switch.
- Advantages
Software
Famous word’s from Linus Torvalds, the father of Linux operating system, comes to my mind.
“Talk is Cheap, Show me the code!” – Linus Torvalds
Let’s evaluate how the code can be constructed to decode the key pressed in matrix configuration. Row’s and column’s of 4x4 matrix keypad is connected to MCU as per below list.
MCU port –> Keypad connections
Keypad | Nano | atmega328p |
---|---|---|
Row_0 | D0 | PD0 |
Row_1 | D1 | PD1 |
Row_2 | D2 | PD2 |
Row_3 | D3 | PD3 |
Col_3 | D4 | PD4 |
Col_2 | D5 | PD5 |
Col_1 | D6 | PD6 |
Col_0 | D7 | PD7 |
We are using port D of atmega328p microcontroller for our interfacing of 4x4 keypad. Lower 4 bits(PD0-PD3) are used for Row connections and Upper 4 bits(PD4-PD7) are used for Column connections of keypad. This particular connection scheme makes the SW design a bit easier :)
Software design
We will be using bitwise operators to scan the keypad and decode the key pressed in keypad.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#define ROW_COUNT (4)
#define COL_COUNT (4)
#define ROW_PORT (PORTD)
#define COL_PORT (PORTD)
#define ROW_MASK (0b00000001)
#define COL_MASK (0b10000000)
#define NO_KEY_PRESSED (255)
uint8 key_scan(void)
{
uint8 col_mask = COL_MASK;
uint8 row_mask;
uint8 key_pressed = 0;
for(row_counter = 0; row_counter < ROW_COUNT; row_counter++)
{
row_mask = ROW_MASK;
for(col_counter = 0; col_counter < COL_COUNT; col_counter++)
{
ROW_PORT = row_mask;
if(COL_PORT & col_mask)
{
return (key_pressed);
}
else
{
key_pressed++;
}
col_mask = col_mask >> 1;
}
row_mask = row_mask << 1;
}
return (NO_KEY_PRESSED);
}
Switch Debouncing
Switch is a mechanical device and when a switch is pressed the switch plate gets closed. The switch closure doesnt produce a step response as we expect in an ideal switch. There are some spikes which are produces whenever a key is pressed or released. These spikes needs to filtered(debounced) to get proper key readings. key_scan() function can be called once in a ms and a debounce of 10 to 20 times counts can be done to rule out errors due to mechanical debounce.
Build images
Closing notes
!!!Happy tinkering!!! :D