PU2CLR MCP23008 Arduino Library  1.0.7
Arduino Library for MCP23008 Device - By Ricardo Lima Caratti
/Users/rcaratti/Desenvolvimento/eu/Arduino/PU2CLR_MCP23008/pu2clr_mcp23008.h
Go to the documentation of this file.
1 /**
2  * @mainpage MCP23008 Arduino Library implementation
3  * @details This library was built based on the Datasheet "MCP23008 8-Bit I/O Expander with Serial Interface" from Microchip
4  * @details The MCP23008 device provides 8-bit, general purpose, parallel I/O expansion. It can be controlled via I²C bus applications. It is a great and inexpensive device that allow you to add more peripherals to be controlled by your Arduino board via I²C protocol.
5  * @details Some Arduino projects may require more pins than the Arduino actually has. In these cases, you can use up to 8 MCP23008 devices using only the I²C bus (two Arduino pins) and add up to 64 input / output ports to your project.
6  * @details This library can be freely distributed using the MIT Free Software model.
7  * @details This library uses the I²C communication protocol and implements most important functions offered by MCP23008 device from MicroChip. It also has primitive functions that make it easier to implement commands that may not have been implemented yet. The main features implemented can be seen below:
8  * @details 1) GPIO individual control (8 I/O pins)
9  * @details 2) Reading and writing Access to all registers (0x00 ~ 0xA)
10  * @details 3) Internal pull up GPIO resistors control
11  * @details 4) I²C address customization (0x20 ~ 0x27)
12  * @details 5) Internal Interrupt feature setup
13  * @details 6) Reset control
14  * @author Ricardo LIma Caratti (pu2clr@gmail.com)
15  * @brief It is a Library to control the MCP23008 device.
16  * @date 2021-01-06
17  * @copyright Copyright (c) 2021 Ricardo Lima Caratti
18  */
19 
20 #include <Arduino.h>
21 #include <Wire.h>
22 
23 // registers
24 #define REG_IODIR 0x00 //!< Controls the direction of the data I/O. When a bit is set, the corresponding pin becomes an input. When a bit is clear, the corresponding pin becomes an output.
25 #define REG_IPOL 0x01 //!< The IPOL register allows the user to configure the polarity on the corresponding GPIO port bits.
26 #define REG_GPINTEN 0x02 //!< The GPINTEN register controls the interrupt-on-change feature for each pin.
27 #define REG_DEFVAL 0x03 //!< The default comparison value is configured in the DEFVAL register.
28 #define REG_INTCON 0x04 //!< The INTCON register controls how the associated pin value is compared for the interrupt-on-change feature
29 #define REG_IOCON 0x05 //!< The IOCON register contains several bits for configuring the device. See method: setIoCon
30 #define REG_GPPU 0x06 //!< The GPPU register controls the pull-up resistors for the port pins.
31 #define REG_INTF 0x07 //!< The INTF register reflects the interrupt condition on the port pins of any pin that is enabled for interrupts via the GPINTEN register.
32 #define REG_INTCAP 0x08 //!< The INTCAP register captures the GPIO port value at the time the interrupt occurred.
33 #define REG_GPIO 0x09 //!< The GPIO register reflects the value on the port.
34 #define REG_OLAT 0x0A //!< The OLAT register provides access to the output latches.
35 
36 #define GPIO_INPUT 0xFF
37 #define GPIO_OUTPUT 0x00
38 
39 #define INTERRUPT_ODR_OPEN_DRAIN 1 //!< Open-drain output (overrides the INTPOL bit).
40 #define INTERRUPT_ODR_ACTIVE_DRIVE 0 //!< Active driver output (INTPOL bit sets the polarity).
41 #define INTERRUPT_INTPOL_ACTIVE_HIGH 1 //!< Active high - polarity of the INT output pin
42 #define INTERRUPT_INTPOL_ACTIVE_LOW 0 //!< Active low - polarity of the INT output pin
43 
44 #define MCP_GPIO0 0
45 #define MCP_GPIO1 1
46 #define MCP_GPIO2 2
47 #define MCP_GPIO3 3
48 #define MCP_GPIO4 4
49 #define MCP_GPIO5 5
50 #define MCP_GPIO6 6
51 #define MCP_GPIO7 7
52 
53 #define CHECK_BIT_HIGH(x,y) ( x & (1 << y) ) //!< Check if a bit is high. Returns 0 or != 0
54 
55 
56 /**
57  * @brief IOCON register structure - I/O EXPANDER CONFIGURATION REGISTER (ADDR 0x05)
58  * @details The IOCON register contains several bits for configuring the device.
59  */
60 typedef union
61 {
62  struct
63  {
64  uint8_t DUMMY1 : 1; //!< Unimplemented
65  uint8_t INTPOL : 1; //!< This bit sets the polarity of the INT output pin. 1= Active-high. 0 = Active - low.
66  uint8_t ODR : 1; //!< This bit configures the INT pin as an open-drain output. 1 = Open-drain. 0 = Active driver.
67  uint8_t HAEN : 1; //!< Hardware Address Enable bit (MCP23S08 only). 1 = Enables.
68  uint8_t DISSLW : 1; //!< Slew Rate control bit for SDA output. 1= Slewratedisabled. 0= Slewrateenabled.
69  uint8_t SEQOP : 1; //!< Sequential Operation mode bit. 1 = Sequential operation disabled, address pointer does not increment.
70  uint8_t DUMMY2 : 2; //!< Unimplemented
71  } arg;
73 } mcp23008_ioncon;
74 
75 class MCP
76 {
77 
78 protected:
79  uint8_t i2cAddress = 0x20; //!< Default i2c address
80  uint8_t gpios = 0; //!< REG_GPIO shadow register
83  int reset_pin = -1; //!< Digital Arduino pin to control the MCP2300 RESET
84 
85 public:
87  void reset();
88  void setup(uint8_t i2c = 0x20, uint8_t io = GPIO_OUTPUT, int reset_pint = -1, long i2c_freq = 100000);
90  void setRegister(uint8_t reg, uint8_t value);
91  void turnGpioOn(uint8_t gpio);
92  void turnGpioOff(uint8_t gpio);
93  void pullUpGpioOn(uint8_t gpio);
94  void pullUpGpioOff(uint8_t gpio);
95  void setIoCon(uint8_t INTPOL, uint8_t ODR, uint8_t HAEN, uint8_t DISSLW, uint8_t SEQOP);
96  mcp23008_ioncon getIoCon();
97  void invertGpioPolarity();
98  void setInterrupt(uint8_t polatity = 0, uint8_t openDrainOutput = 0);
99  void interruptGpioOn(uint8_t gpio, uint8_t bitCompare = 1);
100  bool gpioRead(uint8_t gpio);
101  void gpioWrite(uint8_t gpio, uint8_t value);
102  bool registerDigitalRead(uint8_t mcp_register, uint8_t bit_position);
103  void registerDigitalWrite(uint8_t mcp_register, uint8_t bit_position, uint8_t value);
104 
105  /**
106  * @ingroup group02
107  * @brief Returns the current MCP GPIO pin levels
108  *
109  * @return uint8_t
110  */
111  inline uint8_t getGPIOS()
112  {
113  this->gpios = getRegister(REG_GPIO);
114  return this->gpios;
115  };
116 
117  /**
118  * @ingroup group02
119  * @brief Sets a value to the GPIO Register
120  * @details A direct way to set a given value to deal with the GPIOs pins.
121  * @param value (8 bits)
122  */
123  inline void setGPIOS(uint8_t value) {
124  this->setRegister(REG_GPIO, value);
125  }
126 
127  /**
128  * @ingroup group02
129  * @brief Returns the last value of INTCAP register (value immediately after the last interrupt event)
130  *
131  * @return uint8_t
132  */
134  {
135  this->intcap = getRegister(REG_INTCAP);
136  return this->intcap;
137  };
138 
139  /**
140  * @ingroup group02
141  * @brief Returns the last value of INTF register
142  * @details The INTF register reflects the interrupt condition on the port pins of any pin that is enabled for interrupts via the GPINTEN register. A ‘set’ bit indicates that the associated pin caused the interrupt.
143  * @return uint8_t
144  */
145  inline uint8_t getINTF()
146  {
147  this->intf = getRegister(REG_INTF);
148  return this->intf;
149  };
150 
151  /**
152  * @ingroup group01
153  * @brief Checks if the Bit Value of a given bit position is high
154  * @details This funcion is useful to extract a bit value (0 or 1) from a given MCP23008 register
155  * @param byteValue byte or register value
156  * @param bitNumber bit offset (number / possition from 0 to 7)
157  * @return true if the bit position is 1 (high)
158  */
159  inline bool isBitValueHigh(uint8_t byteValue, uint8_t bitNumber) {
160  return (byteValue & (1 << bitNumber)) != 0;
161  }
162 
163  /**
164  * @ingroup group01 I2C Frequency
165  * @brief Sets I2C bus to a given frequency
166  * @details 100000 = 100KHz; 400000 = 400KHz etc
167  * @details Plese check the property I2C bus frequency/speed of your board
168  */
169  inline void setClock(long freq)
170  {
171  Wire.setClock(freq);
172  };
173 
174 };
MCP::getINTCAP
uint8_t getINTCAP()
Returns the last value of INTCAP register (value immediately after the last interrupt event)
Definition: pu2clr_mcp23008.h:133
REG_INTCAP
#define REG_INTCAP
The INTCAP register captures the GPIO port value at the time the interrupt occurred.
Definition: pu2clr_mcp23008.h:32
MCP::intcap
uint8_t intcap
Definition: pu2clr_mcp23008.h:81
MCP::getRegister
uint8_t getRegister(uint8_t reg)
Gets the corrent register information.
Definition: pu2clr_mcp23008.cpp:97
REG_DEFVAL
#define REG_DEFVAL
The default comparison value is configured in the DEFVAL register.
Definition: pu2clr_mcp23008.h:27
MCP::turnGpioOn
void turnGpioOn(uint8_t gpio)
Turns a given GPIO port on (high level)
Definition: pu2clr_mcp23008.cpp:128
MCP::getGPIOS
uint8_t getGPIOS()
Returns the current MCP GPIO pin levels.
Definition: pu2clr_mcp23008.h:111
MCP::gpioRead
bool gpioRead(uint8_t gpio)
Reads the status (high or low) of a given GPIO.
Definition: pu2clr_mcp23008.cpp:163
MCP::reset_pin
int reset_pin
Digital Arduino pin to control the MCP2300 RESET.
Definition: pu2clr_mcp23008.h:83
MCP::invertGpioPolarity
void invertGpioPolarity()
Inverts the polarity of the all GPIO port bits.
Definition: pu2clr_mcp23008.cpp:300
MCP
Definition: pu2clr_mcp23008.h:75
MCP::setup
void setup(uint8_t i2c=0x20, uint8_t io=GPIO_OUTPUT, int reset_pint=-1, long i2c_freq=100000)
Starts the MCP23008.
Definition: pu2clr_mcp23008.cpp:76
MCP::setInterrupt
void setInterrupt(uint8_t polatity=0, uint8_t openDrainOutput=0)
Configures the MCP23008 interrupt feature.
Definition: pu2clr_mcp23008.cpp:316
GPIO_OUTPUT
#define GPIO_OUTPUT
Definition: pu2clr_mcp23008.h:37
MCP::intf
uint8_t intf
Definition: pu2clr_mcp23008.h:82
REG_GPIO
#define REG_GPIO
The GPIO register reflects the value on the port.
Definition: pu2clr_mcp23008.h:33
MCP::isBitValueHigh
bool isBitValueHigh(uint8_t byteValue, uint8_t bitNumber)
Checks if the Bit Value of a given bit position is high.
Definition: pu2clr_mcp23008.h:159
REG_IOCON
#define REG_IOCON
The IOCON register contains several bits for configuring the device. See method: setIoCon.
Definition: pu2clr_mcp23008.h:29
MCP::gpioWrite
void gpioWrite(uint8_t gpio, uint8_t value)
Sets a given value (high(1) or low(0) ) to a given gpio pin.
Definition: pu2clr_mcp23008.cpp:175
MCP::pullUpGpioOn
void pullUpGpioOn(uint8_t gpio)
Turns intenal pull up resistor ON to a given GPIO PIN (high level)
Definition: pu2clr_mcp23008.cpp:218
MCP::setRegister
void setRegister(uint8_t reg, uint8_t value)
Sets a value to a given register.
Definition: pu2clr_mcp23008.cpp:113
MCP::reset
void reset()
Resets the MCP23008.
Definition: pu2clr_mcp23008.cpp:54
MCP::registerDigitalWrite
void registerDigitalWrite(uint8_t mcp_register, uint8_t bit_position, uint8_t value)
Sets High or Low to a given position in a given MCP23008 register.
Definition: pu2clr_mcp23008.cpp:204
MCP::gpios
uint8_t gpios
REG_GPIO shadow register.
Definition: pu2clr_mcp23008.h:80
MCP::setIoCon
void setIoCon(uint8_t INTPOL, uint8_t ODR, uint8_t HAEN, uint8_t DISSLW, uint8_t SEQOP)
Sets the IO Configurarion gerister.
Definition: pu2clr_mcp23008.cpp:264
MCP::getIoCon
mcp23008_ioncon getIoCon()
Returns the IOCON content.
Definition: pu2clr_mcp23008.cpp:284
REG_INTF
#define REG_INTF
The INTF register reflects the interrupt condition on the port pins of any pin that is enabled for in...
Definition: pu2clr_mcp23008.h:31
MCP::lookForDevice
uint8_t lookForDevice()
Look for MCP23008 device I2C Address.
Definition: pu2clr_mcp23008.cpp:33
MCP::pullUpGpioOff
void pullUpGpioOff(uint8_t gpio)
Turns intenal pull up resistor OFF to a given GPIO PIN (low level)
Definition: pu2clr_mcp23008.cpp:236
REG_IPOL
#define REG_IPOL
The IPOL register allows the user to configure the polarity on the corresponding GPIO port bits.
Definition: pu2clr_mcp23008.h:25
REG_GPPU
#define REG_GPPU
The GPPU register controls the pull-up resistors for the port pins.
Definition: pu2clr_mcp23008.h:30
MCP::interruptGpioOn
void interruptGpioOn(uint8_t gpio, uint8_t bitCompare=1)
Sets the interrupt-on-change feature to a given GPIO pin.
Definition: pu2clr_mcp23008.cpp:336
mcp23008_ioncon::raw
uint8_t raw
Definition: pu2clr_mcp23008.h:72
MCP::i2cAddress
uint8_t i2cAddress
Default i2c address.
Definition: pu2clr_mcp23008.h:79
MCP::setGPIOS
void setGPIOS(uint8_t value)
Sets a value to the GPIO Register.
Definition: pu2clr_mcp23008.h:123
MCP::registerDigitalRead
bool registerDigitalRead(uint8_t mcp_register, uint8_t bit_position)
Reads the status (high or low) of a given bit (position) of a given MCP23008 register.
Definition: pu2clr_mcp23008.cpp:189
REG_IODIR
#define REG_IODIR
Controls the direction of the data I/O. When a bit is set, the corresponding pin becomes an input....
Definition: pu2clr_mcp23008.h:24
MCP::getINTF
uint8_t getINTF()
Returns the last value of INTF register.
Definition: pu2clr_mcp23008.h:145
REG_GPINTEN
#define REG_GPINTEN
The GPINTEN register controls the interrupt-on-change feature for each pin.
Definition: pu2clr_mcp23008.h:26
MCP::setClock
void setClock(long freq)
Sets I2C bus to a given frequency.
Definition: pu2clr_mcp23008.h:169
MCP::turnGpioOff
void turnGpioOff(uint8_t gpio)
Turns a given GPIO port off (low level)
Definition: pu2clr_mcp23008.cpp:146