From 56b01d1fcded341209b7836058ace8c74b453caf Mon Sep 17 00:00:00 2001 From: rob tillaart Date: Wed, 28 Sep 2022 10:44:58 +0200 Subject: [PATCH] 0.1.1 MCP23008 --- libraries/MCP23008/MCP23008.cpp | 57 ++++++------ libraries/MCP23008/MCP23008.h | 4 +- libraries/MCP23008/README.md | 29 +++--- .../MCP23008_I2C_Keypad_4x4_read.ino | 88 +++++++++++++++++++ .../MCP23008_performance.ino | 7 +- libraries/MCP23008/library.json | 2 +- libraries/MCP23008/library.properties | 2 +- 7 files changed, 147 insertions(+), 42 deletions(-) create mode 100644 libraries/MCP23008/examples/MCP23008_I2C_Keypad_4x4_read/MCP23008_I2C_Keypad_4x4_read.ino diff --git a/libraries/MCP23008/MCP23008.cpp b/libraries/MCP23008/MCP23008.cpp index f2d5edc7..2bee866f 100644 --- a/libraries/MCP23008/MCP23008.cpp +++ b/libraries/MCP23008/MCP23008.cpp @@ -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; } diff --git a/libraries/MCP23008/MCP23008.h b/libraries/MCP23008/MCP23008.h index cd8984f5..8f1c4da2 100644 --- a/libraries/MCP23008/MCP23008.h +++ b/libraries/MCP23008/MCP23008.h @@ -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 diff --git a/libraries/MCP23008/README.md b/libraries/MCP23008/README.md index 9040748d..9680db0b 100644 --- a/libraries/MCP23008/README.md +++ b/libraries/MCP23008/README.md @@ -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**. diff --git a/libraries/MCP23008/examples/MCP23008_I2C_Keypad_4x4_read/MCP23008_I2C_Keypad_4x4_read.ino b/libraries/MCP23008/examples/MCP23008_I2C_Keypad_4x4_read/MCP23008_I2C_Keypad_4x4_read.ino new file mode 100644 index 00000000..2e90b14d --- /dev/null +++ b/libraries/MCP23008/examples/MCP23008_I2C_Keypad_4x4_read/MCP23008_I2C_Keypad_4x4_read.ino @@ -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); +} diff --git a/libraries/MCP23008/examples/MCP23008_performance/MCP23008_performance.ino b/libraries/MCP23008/examples/MCP23008_performance/MCP23008_performance.ino index 5a06c165..ab34b1ff 100644 --- a/libraries/MCP23008/examples/MCP23008_performance/MCP23008_performance.ino +++ b/libraries/MCP23008/examples/MCP23008_performance/MCP23008_performance.ino @@ -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..."); diff --git a/libraries/MCP23008/library.json b/libraries/MCP23008/library.json index 43d2bf36..c885b366 100644 --- a/libraries/MCP23008/library.json +++ b/libraries/MCP23008/library.json @@ -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": "*", diff --git a/libraries/MCP23008/library.properties b/libraries/MCP23008/library.properties index 894ec0a8..3aefd039 100644 --- a/libraries/MCP23008/library.properties +++ b/libraries/MCP23008/library.properties @@ -1,5 +1,5 @@ name=MCP23008 -version=0.1.0 +version=0.1.1 author=Rob Tillaart maintainer=Rob Tillaart sentence=Arduino library for I2C MCP23008 8 channel port expander 8 IO-lines