Skip to content

Commit

Permalink
added Keypad_MC17 library for MCP23017 support
Browse files Browse the repository at this point in the history
  • Loading branch information
joeyoung committed May 19, 2014
1 parent b1c1ec8 commit 8fd8253
Show file tree
Hide file tree
Showing 12 changed files with 798 additions and 2 deletions.
201 changes: 201 additions & 0 deletions Keypad_MC17/Keypad_MC17.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
/*
||
|| @file Keypad_MC17.h
|| @version 1.0
|| @author G. D. (Joe) Young
|| @contact "G. D. (Joe) Young" <[email protected]>
||
|| @description
|| | Keypad_MC17 provides an interface for using matrix keypads that
|| | are attached with Microchip MCP23017 I2C port expanders. It
|| | supports multiple keypads, user selectable pins, and user
|| | defined keymaps.
|| | The MCP23017 is somewhat similar to the MCP23016 which is supported
|| | by the earlier library Keypad_MC16. The difference most useful for
|| | use with Keypad is the provision of internal pullup resistors on the
|| | pins used as inputs, eliminating the need to provide 16 external
|| | resistors. The 23017 also has more comprehensive support for separate
|| | 8-bit ports instead of a single 16-bit port. However, this library
|| | assumes configuration as 16-bit port--IOCON.BANK = 0.
|| #
||
|| @license
|| | This library is free software; you can redistribute it and/or
|| | modify it under the terms of the GNU Lesser General Public
|| | License as published by the Free Software Foundation; version
|| | 2.1 of the License.
|| |
|| | This library is distributed in the hope that it will be useful,
|| | but WITHOUT ANY WARRANTY; without even the implied warranty of
|| | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|| | Lesser General Public License for more details.
|| |
|| | You should have received a copy of the GNU Lesser General Public
|| | License along with this library; if not, write to the Free Software
|| | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|| #
||
*/

#include "Keypad_MC17.h"

#define GPIOA 0x12 //MCP23017 GPIO reg
#define GPIOB 0x13 //MCP23017 GPIO reg
#define IODIRA 0x00 //MCP23017 I/O direction register
#define IODIRB 0x01 //MCP23017 I/O direction register
#define IOCON 0x0a //MCP23017 I/O configuration register
#define GPPUA 0x0c //MCP23017 pullup resistors control

/////// Extended Keypad library functions. ////////////////////////////


// Let the user define a keymap - assume the same row/column count as defined in constructor
void Keypad_MC17::begin(char *userKeymap) {
TwoWire::begin();
Keypad::begin(userKeymap);
_begin( );
pinState = pinState_set( );
}


/////// Extended Keypad_MC17 library functions. ////////////////////////

// Initialize MC17
void Keypad_MC17::begin(void) {
TwoWire::begin();
_begin( );
// pinState = 0xff;
pinState = pinState_set( );
}

// Initialize MC17
void Keypad_MC17::begin(byte address) {
i2caddr = address;
TwoWire::begin(address);
_begin( );
// pinState = 0xff;
pinState = pinState_set( );
}

void Keypad_MC17::begin(int address) {
i2caddr = address;
TwoWire::begin(address);
_begin( );
// pinState = 0xff;
pinState = pinState_set( );
} // begin( int )

word iodirec = 0xffff; //direction of each bit - reset state = all inputs.
byte iocon = 0x10; // reset state for bank, disable slew control

// Initialize MCP23017
// MCP23017 byte registers act in word pairs

void Keypad_MC17::_begin( void ) {
iodir_state = iodirec;
TwoWire::beginTransmission( (int)i2caddr );
TwoWire::write( IOCON ); // same as when reset
TwoWire::write( iocon );
TwoWire::endTransmission( );
TwoWire::beginTransmission( (int)i2caddr );
TwoWire::write( GPPUA ); // enable pullups on all inputs
TwoWire::write( 0xff );
TwoWire::write( 0xff );
TwoWire::endTransmission( );
TwoWire::beginTransmission( (int)i2caddr );
TwoWire::write( IODIRA ); // setup port direction - all inputs to start
TwoWire::write( lowByte( iodirec ) );
TwoWire::write( highByte( iodirec ) );
TwoWire::endTransmission( );
TwoWire::beginTransmission( (int)i2caddr );
TwoWire::write( GPIOA ); //point register pointer to gpio reg
TwoWire::write( lowByte(iodirec) ); // make o/p latch agree with pulled-up pins
TwoWire::write( highByte(iodirec) );
TwoWire::endTransmission( );
} // _begin( )

// individual pin setup - modify pin bit in IODIR reg.
void Keypad_MC17::pin_mode(byte pinNum, byte mode) {
word mask = 0b0000000000000001 << pinNum;
if( mode == OUTPUT ) {
iodir_state &= ~mask;
} else {
iodir_state |= mask;
} // if mode
TwoWire::beginTransmission((int)i2caddr);
TwoWire::write( IODIRA );
TwoWire::write( lowByte( iodir_state ) );
TwoWire::write( highByte( iodir_state ) );
TwoWire::endTransmission();
} // pin_mode( )

void Keypad_MC17::pin_write(byte pinNum, boolean level) {
word mask = 1<<pinNum;
if( level == HIGH ) {
pinState |= mask;
} else {
pinState &= ~mask;
}
port_write( pinState );
} // MC17xWrite( )


int Keypad_MC17::pin_read(byte pinNum) {
TwoWire::beginTransmission((int)i2caddr);
TwoWire::write( GPIOA );
TwoWire::endTransmission( );
word mask = 0x1<<pinNum;
TwoWire::requestFrom((int)i2caddr, 2);
word pinVal = 0;
pinVal = TwoWire::read( );
pinVal |= ( TwoWire::read( )<<8 );
pinVal &= mask;
if( pinVal == mask ) {
return 1;
} else {
return 0;
}
}

void Keypad_MC17::port_write( word i2cportval ) {
// MCP23017 requires a register address on each write
TwoWire::beginTransmission((int)i2caddr);
TwoWire::write( GPIOA );
TwoWire::write( lowByte( i2cportval ) );
TwoWire::write( highByte( i2cportval ) );
TwoWire::endTransmission();
pinState = i2cportval;
} // port_write( )

word Keypad_MC17::pinState_set( ) {
TwoWire::beginTransmission((int)i2caddr);
TwoWire::write( GPIOA );
TwoWire::endTransmission( );
TwoWire::requestFrom( (int)i2caddr, 2 );
pinState = 0;
pinState = TwoWire::read( );
pinState |= (TwoWire::read( )<<8);
return pinState;
} // set_pinState( )

// access functions for IODIR state copy
word Keypad_MC17::iodir_read( ) {
return iodir_state; // local copy is always same as chip's register
} // iodir_read( )

void Keypad_MC17::iodir_write( word iodir ) {
iodir_state = iodir;
TwoWire::beginTransmission((int)i2caddr); // read current IODIR reg
TwoWire::write( IODIRA );
TwoWire::write( lowByte( iodir_state ) );
TwoWire::write( highByte( iodir_state ) );
TwoWire::endTransmission();
} // iodir_write( )


/*
|| @changelog
|| |
|| | 1.0 2014-05-18 - Joe Young : Derived from Keypad_MC16
|| #
*/
91 changes: 91 additions & 0 deletions Keypad_MC17/Keypad_MC17.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
||
|| @file Keypad_MC17.h
|| @version 1.0
|| @author G. D. (Joe) Young
|| @contact "G. D. (Joe) Young" <[email protected]>
||
|| @description
|| | Keypad_MC17 provides an interface for using matrix keypads that
|| | are attached with Microchip MCP23017 I2C port expanders. It
|| | supports multiple keypads, user selectable pins, and user
|| | defined keymaps.
|| | The MCP23017 is somewhat similar to the MCP23016 which is supported
|| | by the earlier library Keypad_MC16. The difference most useful for
|| | use with Keypad is the provision of internal pullup resistors on the
|| | pins used as inputs, eliminating the need to provide 16 external
|| | resistors. The 23017 also has more comprehensive support for separate
|| | 8-bit ports instead of a single 16-bit port. However, this library
|| | assumes configuration as 16-bit port--IOCON.BANK = 0.|| #
||
|| @license
|| | This library is free software; you can redistribute it and/or
|| | modify it under the terms of the GNU Lesser General Public
|| | License as published by the Free Software Foundation; version
|| | 2.1 of the License.
|| |
|| | This library is distributed in the hope that it will be useful,
|| | but WITHOUT ANY WARRANTY; without even the implied warranty of
|| | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|| | Lesser General Public License for more details.
|| |
|| | You should have received a copy of the GNU Lesser General Public
|| | License along with this library; if not, write to the Free Software
|| | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|| #
||
*/

#ifndef KEYPAD_MC17_H
#define KEYPAD_MC17_H

#include "Keypad.h"
//#include "../Wire/Wire.h"
#include "Wire.h"

class Keypad_MC17 : public Keypad, public TwoWire {
public:
Keypad_MC17(char* userKeymap, byte* row, byte* col, byte numRows, byte numCols, byte address) :
Keypad(userKeymap, row, col, numRows, numCols) { i2caddr = address; }

// Keypad function
void begin(char *userKeymap);
// Wire function
void begin(void);
// Wire function
void begin(byte address);
// Wire function
void begin(int address);

void pin_mode(byte pinNum, byte mode);
void pin_write(byte pinNum, boolean level);
int pin_read(byte pinNum);
// read initial value for pinState
word pinState_set( );
// write a whole word to i2c port
void port_write( word i2cportval );
// access functions for IODIR state copy
word iodir_read( );
void iodir_write( word iodir );

private:
// I2C device address
byte i2caddr;
// I2C pin_write state persistant storage
word pinState;
// byte pin_iosetup( );
// MC17 setup
word iodir_state; // copy of IODIR register
void _begin( void );
};


#endif // KEYPAD_MC17_H

/*
|| @changelog
|| |
|| | 1.0 2014-05-18 - Joe Young : Convert from Keypad_MC16
|| #
*/

Binary file added Keypad_MC17/docs/MCP23017.pdf
Binary file not shown.
Binary file added Keypad_MC17/docs/usingKeypad_MC17.pdf
Binary file not shown.
Binary file added Keypad_MC17/docs/usingMCP23017.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
49 changes: 49 additions & 0 deletions Keypad_MC17/examples/CustomKeypad_MC17/CustomKeypad_MC17.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/* file CustomKeypad_MC17 Feb 2/13
||@file CustomKeypad.pde
|| @version 1.0
|| @author Alexander Brevig
|| @contact [email protected]
||
|| @description
|| | Demonstrates changing the keypad size and key values.
|| #
Use with I2C i/o G. D. (Joe) Young Feb 28/12
Use with MCP23008 I2C i/o G. D. (Joe) Young Jul 29/12
Use with MCP23016 I2C i/o G. D. (Joe) Young Feb 2/13
Use with MCP23017 I2C i/o G. D. (Joe) Young May 19/14
*/
#include <Keypad_MC17.h>
#include <Keypad.h> // GDY120705
#include <Wire.h>

#define I2CADDR 0x24

const byte ROWS = 4; //four rows
const byte COLS = 5; //five columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
{'0','1','2','3','W'},
{'4','5','6','7','X'},
{'8','9','A','B','Y'},
{'C','D','E','F','Z'}
};
byte rowPins[ROWS] = {3, 2, 1, 0}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {8, 7, 6, 5, 4}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad_MC17 customKeypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS, I2CADDR);

void setup(){
// Wire.begin( );
customKeypad.begin( ); // GDY120705
Serial.begin(9600);
}

void loop(){
char customKey = customKeypad.getKey();

if (customKey != NO_KEY){
Serial.println(customKey);
}
}
Loading

0 comments on commit 8fd8253

Please sign in to comment.