Skip to content
Joe Young edited this page Aug 31, 2020 · 4 revisions

Welcome to the arduino_keypads wiki!

The arduino_keypads libraries add I2C I/O to the Keypad library by using parallel port expander ICs. Different ICs require subtly different versions of the I2C access functions to remain compatible with the Keypad base library. Consequently, several versions of the library have been implemented. The user should just select the one library that supports the IC that is included in the system being developed.

Different devices have more or less elaborate I2C access functions, and thus require different numbers of bytes of code space..as the following table indicates.

Memory use comparisons for Keypad libraries with I2C I/O

May 29, 2014 - G. D. (Joe) Young [email protected]

Using the HelloKeypad example sketches as being essentially empty of useful code except for bringing in the Keypad libraries, the following code sizes are reported by the arduino 1.05 compilation:


|              | HelloKeypad     |                       |
|  library     |     size        | I2C devices supported |
|  :------:    | :-----------:   | :-------------------  |
|Keypad alone  |  4046 bytes     |  none                 |
|Keypad_I2C    |  6530           |PCF8754, PCF8575, PCF8575C(needs pullups)
|Keypad_I2Ca   |  6842           |PCA9554, PCA9555, PCA9534, PCA9539, TCA6408,
|              |                 |TCA6416, others in family (may need pullups)
|Keypad_MCP    |  6626           |MCP23008 (pullups needed)
|Keypad_MC16   |  6774           |MCP23016 (pullups needed)
|Keypad_MC17   |  6858           |MCP23017

Adding the I2C I/O adds approx. 2500..2800 bytes to the code space in addition to that already needed for the keypad support.

HelloKeypad, simple example using PCF8574A I2C port expander

	#include <Keypad_I2C.h>
	#include <Keypad.h>
	#include <Wire.h>
	#define I2CADDR 0x38
	
	const byte ROWS = 4; //four rows
	const byte COLS = 3; //three columns
	char keys[ROWS][COLS] = {
	  {'1','2','3'},
	  {'4','5','6'},
	  {'7','8','9'},
	  {'*','0','#'}
	};
	
	// Digitran keypad, bit numbers of PCF8574 i/o port
	byte rowPins[ROWS] = {0, 1, 2, 3}; //connect to the row pinouts of the keypad
	byte colPins[COLS] = {4, 5, 6}; //connect to the column pinouts of the keypad

	Keypad_I2C kpd( makeKeymap(keys), rowPins, colPins, ROWS, COLS, I2CADDR, PCF8574 );

	void setup(){
	  Serial.begin(9600);
	  while( !Serial ){ /*wait*/ }
	  Wire.begin( );
	  kpd.begin( );
	  Serial.print( "start with pinState = " );
	  Serial.println( kpd.pinState_set( ), HEX );
	}
	void loop(){
	
	  char key = kpd.getKey();
	  
	  if (key){
	  Serial.println(key);
	  }
	}

Notes to HelloKeypad_I2C example:

  • need to include the Keypad_I2C.h and Wire.h with Keypad.h
  • The constructor is the same as for Keypad, but has two extra arguments, the I2C address, and the device type
  • in setup Wire.begin( ) is added
  • an example of added I2C port access functions is shown in last line of setup( ) kpd.pinState_set( ) returns the state of the whole port (and sets the value in private variable to keep track of pin changes).

Constructor arguments

The Keypad_xxx constructors are one of:

	Keypad_I2C kpd( makeKeymap(keys),rowPins,colPins,ROWS,COLS,I2CADDR,device,awiref );
	Keypad_I2Ca kpd( makeKeymap(keys),rowPins,colPins,ROWS,COLS,I2CADDR,device,awiref );
	Keypad_MCP kpd( makeKeymap(keys),rowPins,colPins,ROWS,COLS,I2CADDR,device,awiref );
	Keypad_MC16 kpd( makeKeymap(keys),rowPins,colPins,ROWS,COLS,I2CADDR,device,awiref );
	Keypad_MC17 kpd( makeKeymap(keys),rowPins,colPins,ROWS,COLS,I2CADDR,device,awiref );

The first 5 arguments are just those used to initialize the Keypad library. They setup the library with the keymap definition and assign the row and column pin definitions to physical pins. The 3 new arguments:

I2CADDR -- specifies the device 7-bit address on the I2C bus

device -- a literal naming the type of I2C port expander IC. Each library has definitions for the type(s) of IC the library supports.

The value of the literal is either 1 or 2 and actually determines if the port is one 8-bit byte wide or two bytes wide when the devices in a family are register-compatible so that the different width can be handled by reading/writing one or two bytes on the bus.

awiref -- a TwoWire reference pointer to an alternate I2C interface bus for using the libraries on an arduino with a processor which can have an alternate bus. The parameter may be omitted, in which case the object created defaults to using Wire.

See the example Hello_I2Cboth for how to create an instance of the alternate I2C bus on the MKR ZERO or other SAMD processors. See also the tutorial Adding more Serial Interfaces to SAMD microcontrollers (SERCOM)

Function reference

The Keypad_xxx libraries each provide the following functions which are meant to operate similarly to the basic arduino digital pin functions--digitalRead, digitalWrite, and pinMode. These emulation functions are:

int pin_read( byte pin )

void pin_write( byte pin, byte value )

void pin_mode( byte pin, MODE )

where arguments: pin is the i/o expander port pin number with values 0..7 for 8-bit ports, 0..15 for 16-bit ports; value is (or resolves to) 0 or 1; and MODE is a literal--one of INPUT, INPUT_PULLUP, or OUTPUT.

This trio of functions accessing the I2C port expander will replace the same-named trio of virtual functions in the Keypad library so that when Keypad invokes them, this library instead carries out the operation on the expander port IC.

In addition to those Keypad supports, whole-port read and write functions are provided:

word pinState_set( ) - returns the current state of all the port pins, sets internal state.

void port_write( word i2cportval ) - sets all the port bits to those in i2cportval

word iodir_read( ) - returns the pattern of bits in the direction register.

void iodir_write( word dirval ) - sets the pattern of bit direction to dirval bits

These last two functions are not available in Keypad_I2C since the PCF8574/5 do not have direction registers. Each bit in the direction register sets the direction of the corresponding pin with 0 output, 1 input. Expander ports typically power on with all bits as inputs.