0.1.1 MCP23008

This commit is contained in:
rob tillaart 2022-09-28 10:44:58 +02:00
parent 01f9937d80
commit 56b01d1fcd
7 changed files with 147 additions and 42 deletions

View File

@ -1,13 +1,14 @@
//
// FILE: MCP23008.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// VERSION: 0.1.1
// PURPOSE: Arduino library for I2C MCP23008 8 channel port expander
// DATE: 2019-10-12
// URL: https://github.com/RobTillaart/MCP23008
//
// HISTORY:
// 0.1.0 2022-01-10 initial version
// 0.1.1 2022-09-28 optimize digitalWrite() [as that is the most used one]
@ -41,11 +42,11 @@ bool MCP23008::begin(const uint8_t dataPin, const uint8_t clockPin)
{
_wire = &Wire;
_wire->begin(dataPin, clockPin);
// check connected
// check connected
if (! isConnected()) return false;
// disable address increment (datasheet)
// disable address increment (datasheet)
if (! writeReg(MCP23008_IOCR, 0b00100000)) return false;
// Force INPUT_PULLUP
// Force INPUT_PULLUP
if (! writeReg(MCP23008_PUR_A, 0xFF)) return false;
return true;
}
@ -55,11 +56,11 @@ bool MCP23008::begin(const uint8_t dataPin, const uint8_t clockPin)
bool MCP23008::begin()
{
_wire->begin();
// check connected
// check connected
if (! isConnected()) return false;
// disable address increment (datasheet)
// disable address increment (datasheet)
if (! writeReg(MCP23008_IOCR, 0b00100000)) return false;
// Force INPUT_PULLUP
// Force INPUT_PULLUP
if (! writeReg(MCP23008_PUR_A, 0xFF)) return false;
return true;
}
@ -78,9 +79,9 @@ bool MCP23008::isConnected()
}
// single pin interface
// pin = 0..7
// mode = INPUT, OUTPUT, INPUT_PULLUP (= same as INPUT)
// single pin interface
// pin = 0..7
// mode = INPUT, OUTPUT, INPUT_PULLUP (= same as INPUT)
bool MCP23008::pinMode(uint8_t pin, uint8_t mode)
{
if (pin > 7)
@ -120,8 +121,8 @@ bool MCP23008::pinMode(uint8_t pin, uint8_t mode)
}
// pin = 0..7
// value = LOW, HIGH
// pin = 0..7
// value = LOW, HIGH
bool MCP23008::digitalWrite(uint8_t pin, uint8_t value)
{
if (pin > 7)
@ -131,6 +132,7 @@ bool MCP23008::digitalWrite(uint8_t pin, uint8_t value)
}
uint8_t IOR = MCP23008_GPIO_A;
uint8_t val = readReg(IOR);
uint8_t pre = val;
if (_error != MCP23008_OK)
{
return false;
@ -145,10 +147,14 @@ bool MCP23008::digitalWrite(uint8_t pin, uint8_t value)
{
val &= ~mask;
}
writeReg(IOR, val);
if (_error != MCP23008_OK)
// only write if there is a change
if (val != pre)
{
return false;
writeReg(IOR, val);
if (_error != MCP23008_OK)
{
return false;
}
}
return true;
}
@ -173,8 +179,8 @@ uint8_t MCP23008::digitalRead(uint8_t pin)
}
// pin = 0..7
// reverse = true or false
// pin = 0..7
// reverse = true or false
bool MCP23008::setPolarity(uint8_t pin, bool reversed)
{
if (pin > 7)
@ -225,8 +231,8 @@ bool MCP23008::getPolarity(uint8_t pin, bool &reversed)
}
// pin = 0..7
// reverse = true or false
// pin = 0..7
// reverse = true or false
bool MCP23008::setPullup(uint8_t pin, bool pullup)
{
if (pin > 7)
@ -278,9 +284,10 @@ bool MCP23008::getPullup(uint8_t pin, bool &pullup)
///////////////////////////////////////////////////////////////////////
// 8 pins interface
// whole register at once
// value = 0..0xFF bit pattern
//
// 8 pins interface
// whole register at once
// value = 0..0xFF bit pattern
bool MCP23008::pinMode8(uint8_t value)
{
writeReg(MCP23008_DDR_A, value);
@ -304,7 +311,7 @@ int MCP23008::read8()
}
// mask = 0..0xFF bit pattern
// mask = 0..0xFF bit pattern
bool MCP23008::setPolarity8(uint8_t mask)
{
writeReg(MCP23008_POL_A, mask);
@ -327,7 +334,7 @@ bool MCP23008::getPolarity8(uint8_t &mask)
}
// mask = 0..0xFF bit pattern
// mask = 0..0xFF bit pattern
bool MCP23008::setPullup8(uint8_t mask)
{
writeReg(MCP23008_PUR_A, mask);
@ -353,7 +360,7 @@ bool MCP23008::getPullup8(uint8_t &mask)
int MCP23008::lastError()
{
int e = _error;
_error = MCP23008_OK; // reset error after read.
_error = MCP23008_OK; // reset error after read.
return e;
}

View File

@ -2,7 +2,7 @@
//
// FILE: MCP23008.h
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// VERSION: 0.1.1
// PURPOSE: Arduino library for I2C MCP23008 16 channel port expander
// DATE: 2022-01-10
// URL: https://github.com/RobTillaart/MCP23008
@ -12,7 +12,7 @@
#include "Wire.h"
#define MCP23008_LIB_VERSION (F("0.1.0"))
#define MCP23008_LIB_VERSION (F("0.1.1"))
#define MCP23008_OK 0x00
#define MCP23008_PIN_ERROR 0x81

View File

@ -18,6 +18,9 @@ This library gives easy control over the 8 pins of a (I2C) MCP23008 chip.
This IC is strongly related tot the MCP23017 I2C port expander - https://github.com/RobTillaart/MCP23017_RT
Programming Interface is kept the same as much as possible.
Since 0.1.1 the **digitalWrite(pin, value)** is optimized.
If a pin is not changed it will not be written again to save time.
## Interface
@ -32,28 +35,30 @@ Can be overruled with Wire0..WireN.
### Single pin interface
- **bool pinMode(uint8_t pin, uint8_t mode)** pin = 0..7, mode = INPUT, OUTPUT, returns true if successful.
- **bool digitalWrite(uint8_t pin, uint8_t value)** pin = 0..7, value = LOW(0) HIGH (!0), returns true if successful.
- **bool pinMode(uint8_t pin, uint8_t mode)** pin = 0..7, mode = INPUT, OUTPUT. Returns true if successful.
- **bool digitalWrite(uint8_t pin, uint8_t value)** pin = 0..7, value = LOW(0) HIGH (!0). Returns true if successful.
- **uint8_t digitalRead(uint8_t pin)** pin = 0..7, returns LOW or HIGH, might set the lastError();
- **bool setPolarity(uint8_t pin, bool reversed)** pin = 0..7, set reversed flag, returns true if successful.
- **bool getPolarity(uint8_t pin, bool &reversed)** pin = 0..7, reads reversed flag, returns true if successful.
- **bool setPullup(uint8_t pin, bool pullup)** pin = 0..7, set pull-up flag, returns true if successful.
- **bool getPullup(uint8_t pin, bool &pullup)** pin = 0..7, reads pull-up flag, returns true if successful.
- **bool setPolarity(uint8_t pin, bool reversed)** pin = 0..7, set reversed flag. Returns true if successful.
- **bool getPolarity(uint8_t pin, bool &reversed)** pin = 0..7, reads reversed flag. Returns true if successful.
- **bool setPullup(uint8_t pin, bool pullup)** pin = 0..7, set pull-up flag. Returns true if successful.
- **bool getPullup(uint8_t pin, bool &pullup)** pin = 0..7, reads pull-up flag. Returns true if successful.
### 8 pins interface
- **bool pinMode8(uint8_t value)** value = 0..255, returns true if successful.
- **bool write8(uint8_t value)** value = 0..255, returns true if successful.
- **bool pinMode8(uint8_t value)** value = 0..255. Returns true if successful.
- **bool write8(uint8_t value)** value = 0..255. Returns true if successful.
- **uint8_t read8()** reads 8 pins into one byte.
- **bool setPolarity8(uint8_t mask)** sets polarity for 8 channels at once.
- **bool getPolarity8(uint8_t &mask)** reads polarity of 8 channels at once.
- **bool setPullup8(uint8_t mask)** sets pull-up for 8 channels at once.
- **bool getPullup8(uint8_t &mask)** reads pull-up for 8 channels at once.
- **bool setPolarity8(uint8_t mask)** sets polarity for 8 channels at once. Returns true if successful.
- **bool getPolarity8(uint8_t &mask)** reads polarity of 8 channels at once. Returns true if successful.
- **bool setPullup8(uint8_t mask)** sets pull-up for 8 channels at once. Returns true if successful.
- **bool getPullup8(uint8_t &mask)** reads pull-up for 8 channels at once. Returns true if successful.
### Error codes
If one of the above functions return false, there might be an error.
- **int lastError()** Above functions set an error flag that can be read with this function.
Reading it will reset the flag to **MCP23008_OK**.

View File

@ -0,0 +1,88 @@
//
// FILE: MCP23008_I2C_Keypad_4x4_read.ino
// AUTHOR: François Longchamp
// DATE: 2022-09-27
// PUPROSE: Keypad MCP23008 library
//
// Tested with Seeed Studio XIAO RP2040
// Keypad used https://fr.aliexpress.com/item/1005003176287473.html
#include "MCP23008.h"
#include "Wire.h"
MCP23008 MCP(0x20);
const byte ROWS_OF_KEYPAD = 4; //four rows
const byte COLS_OF_KEYPAD = 4; //four columns
byte keys_of_keypad[ROWS_OF_KEYPAD][COLS_OF_KEYPAD] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10,11,12},
{13,14,15,16}
};
void setup()
{
Serial.begin(115200);
Serial.print("MCP23008 version: ");
Serial.println(MCP23008_LIB_VERSION);
Wire.begin();
MCP.begin();
}
void loop()
{
bool val;
// rows pinMode (0 or false = pressed)
MCP.pinMode8(0x0f);
for (int pin = 0; pin < 4; pin++)
{
val = MCP.digitalRead(pin);
Serial.print(val);
Serial.print(' ');
}
// columns pinMode (0 or false = pressed)
MCP.pinMode8(0xf0);
for (int pin = 4; pin < 8; pin++)
{
val = MCP.digitalRead(pin);
Serial.print(val);
Serial.print(' ');
}
// digital pressed from referer keys_of_keypad
MCP.pinMode8(0x0f);
for (int r = 0; r < ROWS_OF_KEYPAD; r++)
{
if( MCP.digitalRead(r) == false ) // false = pressed
{
MCP.pinMode8(0xf0);
for (int c = ROWS_OF_KEYPAD; c < ROWS_OF_KEYPAD+COLS_OF_KEYPAD; c++)
{
if( MCP.digitalRead(c) == false ) // false = pressed
{
Serial.print(keys_of_keypad[r][c-4]);
}
}
MCP.pinMode8(0x0f);
}
}
Serial.println("");
delay(500);
}

View File

@ -24,6 +24,8 @@ void setup()
Wire.begin();
bool b = MCP.begin();
Serial.print("BEGIN: ");
Serial.println(b);
MCP.pinMode8(0x00); // 0 = output , 1 = input
@ -55,13 +57,15 @@ void setup()
Serial.print("TEST digitalRead(pin):\t");
delay(100);
volatile int val = 0;
start = micros();
for (int pin = 0; pin < 8; pin++)
{
volatile int val = MCP.digitalRead(pin);
val = MCP.digitalRead(pin);
}
stop = micros();
Serial.println((stop - start) / 8.0);
Serial.println(val);
Serial.println();
@ -83,6 +87,7 @@ void setup()
volatile int val8 = MCP.read8();
stop = micros();
Serial.println(stop - start);
Serial.println(val8);
Serial.println();
Serial.println("\ndone...");

View File

@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/MCP23008.git"
},
"version": "0.1.0",
"version": "0.1.1",
"license": "MIT",
"frameworks": "arduino",
"platforms": "*",

View File

@ -1,5 +1,5 @@
name=MCP23008
version=0.1.0
version=0.1.1
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for I2C MCP23008 8 channel port expander 8 IO-lines