Skip to content

renepenner/gpio_expander

 
 

Repository files navigation

gpio_expander library

Universal GPIO library for Arduinos and Teensy 2/3/3.x


An attempt to create an universal library that works with many common GPIO chips and can be used with Arduino's and Teensy's (my preferred choice)
Here's a list of the GPIO's chip managed:

chipcompanypinsprotocolfeaturesstatus
mcp23s17Microchip16SPIHAEN/INTdone
mcp23017Microchip16I2CINTdone
mcp2308Microchip8I2CINTdone
mcp23s08Microchip8SPIHAEN/INTdone
mcp23s18Microchip16SPIHAEN/INTdone
mcp23018Microchip16I2CINTdone
mcp23016Microchip16I2CINTdone
pcf8574NTX8I2CINTdev
pcf8574aNTX8I2CINT/different address rangedev
pcf8575NTX8I2CINTplanned
pca9698NTX40I2CINT/64adrsplanned
pca9555NTX16I2CINT/64adrstesting
tca9555TI16I2CINT/64adrstesting
max6957TI20/28I2CINT/64adrstesting
max7301TI20/28I2CINT/64adrstesting
max7311TI16I2CINT/64adrs/hot insertiontesting
max7318TI16I2CINT/64adrs/hot insertiontesting
rd1073LATTICE16SPIINTplanned
xra1200EXAR8I2CINTplanned
xra1201EXAR16I2CINTplanned
xra1405EXAR16SPIINT/24Mhz SPIdev
fxl6408FAIRCHILD8I2CINTplanned
bu1852guwROHM20I2CINTplanned
cy8C9560CYPRESS60I2CINT/EEPROM/max 100Khz I2Cplanned
sx1505SEMTECH8I2CINT/Indipendent railsdev
sx1506SEMTECH16I2CINT/Indipendent railsdev
sx1509SEMTECH16I2CINT/LED driver/Level Shifterdev

Status Legend:

done:
fully working.
dev:
currently in development.
testing:
currently in testing, may works or partially.
planned:
will be developed soon and added before the release.
planned[R2]:
will not included in the release but planned for version 2.

When working with microcontrollers it's common run quickly out of I/O's, that because these small chips have few pins and some periferal (like LCD) uses many pins. For this reason I use a lot external GPIO's chips.

Microchip series MCP23xxx GPIO expanders are great chips but they can be a nightmare if you want to deal with registers, timings, etc., for these reasons a lot of coders prefere the supereasy to use PCF series from NTX.
I personally prefere the Microchip series because I can choose from I2C and SPI and they have an extra feature called HAEN that allow me to share CS pin between 8 different chips in SPI mode!
This library it's an improvement of my old MCP23xxx library since it's smaller, faster and deal with all MCP23xx series plus PCF series from NTX.
I designed as a small and easy library that can be easily expanded but still have the ability to handle directly the registers for special purposes.
If you need a simple expander, use this library and choose between many GPIO's chip by using really simply commands, but if you need a specialized GPIO you can still use this library and use the direct access to chip registers (see the keypad demo).
The MCP23xxx registers are stored in each chip library extension so you can share demos between different chips (there's some exceptions like the MCP23016 that has limited features and you cannot share some features between NTX and MCP ones since they are internally very different).
Library is modular, every chip it's an extension of the same library so it's easy to expand.
Why create an unified library? It's better create single libraries for chip families? Seems no!
Almost all GPIO chips have really similar programming, only Microchip families has more features and looks more complicated but the access it's almost the same for all so it have sense to build up an unified way to access these chips with common commands so you can easily use the chip you like without have to recode anithing, just be sure you don't need some special features of some particular chip.

How To Use:

Library it's unified so you just need toi include the chip and his protocol, example for mcp23017

 #include <Wire.h>
 #include <mcp23017.h>

then you need an instance:

 mcp23017 gpio(address);//instance
 // NOTE: If you need to include library in other libraries you can use mcp23017 gpio(); (empty address)
 // then call postSetup!!

where the address it's specific to the chip (read chip.h file)

From below the commands are the same for all chip with some exceptions:

  • Some chip it's 8 bit so it doesn't have the writeWord command
  • Some chip has limited features so not all registers are accessible, take a look to the chip.h file)

Commands are:

 gpio.postSetup(depends of chip);//Useful when you want include in other libraries
 gpio.begin();//gpio.begin(1); will not init the protocol (useful when multiple chip are used or you want to manually init it
 
 gpio.gpioPinMode(INPUT or OUTPUT or data);//set all pin accordly
 gpio.gpioPinMode(pin,mode);//set an individual pin as INPUT or OUTPUT
 gpio.port(data or HIGH or LOW);//data=8..xx bits, depends of chip. set all pins at once
 gpio.port(low byte,high byte);//useful for 16 bit GPIOs that have 2 ports of 8 bit
 gpio.readGpioPort();//read the state of all pins, it returns 8...xx bits depending of chip
 gpio.readGpioPortFast();//experimental. Read the state of the library buffer instead of the chip.
 gpio.gpioDigitalWrite(pin,state);//set individual pin HIGH or LOW
 gpio.gpioDigitalRead(pin);//read the state of one pin
 gpio.gpioDigitalReadFast(pin);//experimental. Read the state of a pin from the library buffer
 gpio.gpioRegisterReadByte(register);//not available to all chip, read a byte from the specific register
 gpio.gpioRegisterReadWord(register);//not available to all chip, read a word from the specific register
 gpio.gpioRegisterWriteByte(register,data);//write byte directly in chip register
 gpio.gpioRegisterWriteWord(register,data);//write word directly in chip register(not 8 bit chip)
 gpio.portPullup(HIGH or LOW or data);//Set pullup on input pin (not all chip!)

Another example: How to include in another library?

Here's how to inlude and use this library inside an existing one. In the .h file of your existing library add this lines just after the aruino.h include or library protection declaration:

#ifndef _YOURLIB_H_
#define _YOURLIB_H_

#include <inttypes.h>

#include "yourlib.h"

//here start the include
#include <../SPI/SPI.h>//this chip needs SPI
#include <../gpio_expander/mcp23s17.h>
//here ends

Now you have to provide an instance! Go to the private section of your library .h file and add to existings:

 private:
    bla
    bla
    
    uint8_t 		_cs;//needed for this chip
    uint8_t 		_adrs;//needed for this chip (if you using HAEN)

   mcp23s17		mygpio;//here the instance
 As you noticed I have included also the _cs pin var and _adrs var needed for the chip I choose for demo.
 Now open the .cpp file of your library and add these lines to your initialization function:
	 void myLibrary::begin(bla, bla){
	     bla
	     bla
	     
	      mygpio.postSetup(_cs,_adrs);//you should set these 2 vars before!
	      mygpio.begin();//put true if you want to init SPI (or I2C, depends of chip) manually!
	      mygpio.gpioPinMode(OUTPUT);
	      mygpio.gpioPort(0xFFFF);
	      etc...
	 }

Since the library was already instanced and inited you can use the library function inside your library where you want but not forget to initialize it as I show above!

version 0.6b1 - beta release - only some driver released and partially tested!!!

coded by Max MC Costa for s.u.m.o.t.o.y [sumotoy(at)gmail.com]


About

A library for drive a lot of GPIO chips with Arduino and Teensy

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published