Binary-operated Button Matrix Keypad
by bevopsmoment in Circuits > Arduino
53 Views, 0 Favorites, 0 Comments
Binary-operated Button Matrix Keypad
So, I wanted to create a soundboard with an ESP32-C3 supermini chip. For that, obviously, you need some way to send data to the chip, and what better way to do it than a keypad. Essentially, this is a button matrix that you press on to get a number.
How does it work?
Well, the dev board iterates through all the OUTPUT pins associated with the columns of the matrix and sends a digital "ON" signal through each of them in turn. In the meantime, another set of INPUT pins associated with the rows perform digital read. When a row pin detects an "ON" signal, it means a button was pressed.
Based on the row that was read, and the current activated column, you can calculate the correct button pressed.
There are several keypad libraries. The first search I got for "esp32 keypad library" was this website.
It works great, the problem is, they use an entire pin for each row and column of the keypad! It might be fine when you use a regular ESP32, and you have like 30+ available GPIOs to choose from, but if you are working with a tiny ESP32-C3 supermini, that only has 12 pins including strapping pins, you need to think about how to downsize your pin count.
My solution?
Encoding the powered column and the active row with binary numbers!
In my project, I managed to save 3 pins and ended up using only 5, which overall gave me exactly the amount I needed for the soundboard (I had to skip GPIO 2, because it was always on and I could not figure out how to use it).
Supplies
- ESP32-C3 supermini.
- Could work with any reasonable board. I used this one because it's the smallest I could fit for my project.
- 1 Keypad.
- I used a 4x4 keypad. This is a nice size as it offers enough buttons for usage and for demonstrating the mechanism of how this binary encoding works without being too complicated.
- 1 NOT gate (74LS04).
- 1 AND gate (74LS08).
- 1 OR gate (74LS32).
- 4 10K Pull-Down resistors.
- For the OR gate. ROW4 should also have a pull-down resistor, I don't know why as it is not connected to the OR gate, but it didn't work properly without it.
Making Plans
Firstly, how many pins do we ACTUALLY need?
For the columns, you need to power each of them in sequence, so the amount of states is equal to the amount of columns. Therefore, you need to use log_2(COLUMN amount), rounded up.
For the rows, each row represents a state, but unlike the columns, there should be a neutral, UNPRESSED state. Therefore, you need to use log_2(ROW amount + 1), rounded up.
For my example, there are ceil(log_2(4)) = 2 column pins, and ceil(log_2(4+1)) = 3 rows.
Now, how to translate a position from a binary number and vice versa?
COLS (Binary to Position):
The columns are easier, so we'll start with them.
We need to translate a 2-bit number to a 1-in-4 choice, so let's define that
00 activates column 1, 01 activates columns 2, 10 activates column 3, and 11 activates column 4.
Therefore:
- activate column 1 if NOT bit#1 AND NOT bit#2
- activate column 2 if bit#1 AND NOT bit#2
- activate column 3 if NOT bit#1 AND bit#2
- activate column 4 if bit#1 AND bit#2.
ROWS (Position to Binary):
Here, we need to encode 5 states into a 3 bit number. We will just calculate the number in binary and send it to the esp32. The numbers are:
- 0->000
- 1->001
- 2->010
- 3->011
- 4->100.
So, we can see that bit#1 is ON if row#1 OR row#3 are ON, bit#2 is ON if row#2 OR row#3, and bit#3 is just equal to row#4.
Wire Up
Translating the calculations into actual wiring according to the schematic.
Downloads
Code
Let's break the code to three sections.
We'll start with the constants and variables:
There are only two functions, one to power the columns, and another to read the rows:
Finally, the setup and loop functions: