User input can be obtained via discrete, independant buttons (e.g., toggle the state of a particular function to be either 'on' or 'off') which are determined by reading the state of the button via a I/O port on the microcontroller. However, when 'numeric' and or 'text' user input is required, having discrete buttons for each 'number' or 'letter' quickly outstrips the number of I/O pins available with boards such as the Arduino Nano. Hence, matrix keypads are used instead to decrease the number of required I/O pins. Matrix keypads operate with a process called 'keypad scanning' in conjunction with circuitry attached to the matrix keypad with pullup resistors at either the 'rows' or 'columns'.
Matrix Keypad Diagram
Matrix Keyboard 'scanning'
The microcontroller determines which individual key is pressed using the following steps:
- Step 1: First set all ROWS to OUTPUT and set them at +5V. Next set all COLUMNS as INPUT to sense the HIGH logic. Now consider a button is pressed on keypad. And that key is at 2ND COLUMN and 3rd ROW. With the button being pressed the current flows through the connection between Row 2 to Column 2. With that a voltage of +5V appears at terminal C2. Since the COLUMN pins are set as INPUTS, the controller can sense C2 going high. The controller is coded to remember that C2 going high and the button pressed is in C2 COLUMN.
- Step 2: Next set all COLUMNS to OUTPUT and set them at +5V. Next set all ROWS as INPUT to sense the HIGH logic. Since the key pressed is at 2ND COLUMN and 3rd ROW. The current now flows through the connection between Column 2 to Row 3. With that current flow a positive voltage of +5V appears at Row 3 pin. Since all ROWS are set as INPUTS, the controller can sense +5V at Row 3 pin. The controller is coded to remember the key being pressed at third ROW of KEYPAD MATRIX.
- Step 2: The microcontroller now knows the COLUMN number of key pressed and the ROW number. With that the matched key being pressed can be found. In this way the individual particular key being pressed on the 4X4 KEYPAD MODULE can be determined.
This sounds a little complex, but the Arduino 'Keypad library' (1) provides the necessary 'keypad scanning' code, abstracting the circuit operation to simply calling the appropriate read statement. This enables for example, a 4 x 4 matrix keypad (i.e., sixteen (16) keys) to be read using only eight (8) I/O pins on the Arduino Nano, rather than 16 I/O pins if the keypad was in effect discrete buttons.
While the Arduino Nano is advantageous in terms of small physical size and low cost per GPIO/onboard peripheral available (particularly good for 'small' DIY projects controlling a single sensor and or output for example), the small physical size means limited input/output pins. Therefore, using the Arduino 'Keypad library' with a 4x4 matrix keypad means the Arduino Nano input pins are severly limited for connectivity with other circuit components.
Conveniently, there are I/O port expanders available such as the PCF8574 which can be interfaced using only 2 pins, and provide 8 GPIO's. Further, the PCF8574 can be daisy-chained so that multiple's of additional 8 GPIO's can be achieved. The interface for connecting the PCF8574 to the Arduino Nano is called I2C (I2C is an acronym for “Inter-Integrated Circuit”).
This project will focus on using the PCF8574 with a 4x4 matrix keypad, as minimising the number of I/O ports used on the Arduino Nano to connect a keypad will likely be the general requirement.
In addition to the benefit of gaining additional GPIO's by using PCF8574 port expanders is learning how to use the I2C interface. There are literally thousands of components that use the I2C interface such a real-time clocks, digital potentiometers, temperature sensors, digital compasses, memory chips etc. So once the PCF8574 interface to the Arduino Nano is successfully achieved, the same process can then be used with additional components as required.
First some background about I2C and then some specifics about the PCF8574.
Details on how to setup the Arduino IDE and environment to programme Arduino Nano microcontrollers are given in the Arduino Nano introduction.
I2C “Inter-Integrated Circuit”
I2C orginated from Philips Semiconductor (now NXP) as a way of standardising the data lines that travel between various integrated circuits, which only requires two wires (SDA – data, and SCL – clock). In terms of the hardware and communications protocol, the software library abstracts the majority of the details i.e., you don't really need to know - but if interested, the sparkfun page gives an easy introduction (4). However, some knowledge about the hardware/signal levels is necessary so the importance of having pull-up resistors on the SDA/SCL lines is appreciated.
Each I2C bus consists of two signals: SCL and SDA. SCL is the clock signal, and SDA is the data signal. The clock signal is always generated by the current bus master. The I2C bus drivers are “open drain”, meaning that they can pull the corresponding signal line low, but cannot drive it high. This eliminates possibility of data bus contention where one device is trying to drive the line high while another tries to pull it low. However, this means it is mandatory that each signal line has a pull-up resistor on it, to restore the signal to high when no device is asserting it low.
The usual value for these pull-up resistors is 4K7 (but sometimes if multiple devices on the bus 10K may be appropriate). Also, the I2C bus is meant for short distances (generally on the same PCB). The maximum length of an I2C bus is approximately 1 meter.
Devices with I2C can be connected in any physical order, there are 'address pins' on each device which can be phyiscally set to determine unique addresses.
PCF8574 Port Expander
The datasheet (see Bill of Materials Section) gives all the necessary details. Note there are alternatives to the PCF8574 (I just have a bunch of these available) such as the MCP23008 (which has 25mA sink/source per I/O pin) and 16-bit varieties (e.g. MCP23018 which gives 16 I/O lines on a single chip).
Important to realise is that the PCF8574 is a current sink device rather than current source. This means that external components need to be connected to Vcc via pull-up resistors.
Only Logged-In Members can add comments