mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-09-19 16:46:11 -04:00
0.1.0 MCP23008
This commit is contained in:
parent
d13d98052a
commit
bb3cba8cd7
11
libraries/MCP23008/.arduino-ci.yml
Normal file
11
libraries/MCP23008/.arduino-ci.yml
Normal file
@ -0,0 +1,11 @@
|
||||
compile:
|
||||
# Choosing to run compilation tests on 2 different Arduino platforms
|
||||
platforms:
|
||||
- uno
|
||||
# - due
|
||||
# - zero
|
||||
# - leonardo
|
||||
- m4
|
||||
- esp32
|
||||
# - esp8266
|
||||
# - mega2560
|
13
libraries/MCP23008/.github/workflows/arduino-lint.yml
vendored
Normal file
13
libraries/MCP23008/.github/workflows/arduino-lint.yml
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
|
||||
name: Arduino-lint
|
||||
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: arduino/arduino-lint-action@v1
|
||||
with:
|
||||
library-manager: update
|
||||
compliance: strict
|
17
libraries/MCP23008/.github/workflows/arduino_test_runner.yml
vendored
Normal file
17
libraries/MCP23008/.github/workflows/arduino_test_runner.yml
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
name: Arduino CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
runTest:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: 2.6
|
||||
- run: |
|
||||
gem install arduino_ci
|
||||
arduino_ci.rb
|
18
libraries/MCP23008/.github/workflows/jsoncheck.yml
vendored
Normal file
18
libraries/MCP23008/.github/workflows/jsoncheck.yml
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
name: JSON check
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '**.json'
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: json-syntax-check
|
||||
uses: limitusus/json-syntax-check@v1
|
||||
with:
|
||||
pattern: "\\.json$"
|
||||
|
21
libraries/MCP23008/LICENSE
Normal file
21
libraries/MCP23008/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022-2022 Rob Tillaart
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
405
libraries/MCP23008/MCP23008.cpp
Normal file
405
libraries/MCP23008/MCP23008.cpp
Normal file
@ -0,0 +1,405 @@
|
||||
//
|
||||
// FILE: MCP23008.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.0
|
||||
// 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
|
||||
|
||||
|
||||
|
||||
#include "MCP23008.h"
|
||||
|
||||
|
||||
// Registers // description datasheet
|
||||
#define MCP23008_DDR_A 0x00 // Data Direction Register A P
|
||||
#define MCP23008_POL_A 0x01 // Input Polarity A P
|
||||
#define MCP23008_GPINTEN_A 0x02 // NOT USED interrupt enable P
|
||||
#define MCP23008_DEFVAL_A 0x03 // NOT USED interrupt def P
|
||||
#define MCP23008_INTCON_A 0x04 // NOT USED interrupt control P
|
||||
#define MCP23008_IOCR 0x05 // IO control register P
|
||||
#define MCP23008_PUR_A 0x06 // Pull Up Resistors A P
|
||||
#define MCP23008_INTF_A 0x07 // NOT USED interrupt flag P
|
||||
#define MCP23008_INTCAP_A 0x08 // NOT USED interrupt capture P
|
||||
#define MCP23008_GPIO_A 0x09 // General Purpose IO A P
|
||||
#define MCP23008_OLAT_A 0x0A // NOT USED output latch P
|
||||
|
||||
|
||||
MCP23008::MCP23008(uint8_t address, TwoWire *wire)
|
||||
{
|
||||
_address = address;
|
||||
_wire = wire;
|
||||
_error = MCP23008_OK;
|
||||
}
|
||||
|
||||
|
||||
#if defined(ESP8266) || defined(ESP32)
|
||||
bool MCP23008::begin(const uint8_t dataPin, const uint8_t clockPin)
|
||||
{
|
||||
_wire = &Wire;
|
||||
_wire->begin(dataPin, clockPin);
|
||||
// check connected
|
||||
if (! isConnected()) return false;
|
||||
// disable address increment (datasheet)
|
||||
if (! writeReg(MCP23008_IOCR, 0b00100000)) return false;
|
||||
// Force INPUT_PULLUP
|
||||
if (! writeReg(MCP23008_PUR_A, 0xFF)) return false;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool MCP23008::begin()
|
||||
{
|
||||
_wire->begin();
|
||||
// check connected
|
||||
if (! isConnected()) return false;
|
||||
// disable address increment (datasheet)
|
||||
if (! writeReg(MCP23008_IOCR, 0b00100000)) return false;
|
||||
// Force INPUT_PULLUP
|
||||
if (! writeReg(MCP23008_PUR_A, 0xFF)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool MCP23008::isConnected()
|
||||
{
|
||||
_wire->beginTransmission(_address);
|
||||
if (_wire->endTransmission() != 0)
|
||||
{
|
||||
_error = MCP23008_I2C_ERROR;
|
||||
return false;
|
||||
}
|
||||
_error = MCP23008_OK;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// 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)
|
||||
{
|
||||
_error = MCP23008_PIN_ERROR;
|
||||
return false;
|
||||
}
|
||||
if ((mode != INPUT) && (mode != INPUT_PULLUP) && (mode != OUTPUT))
|
||||
{
|
||||
_error = MCP23008_VALUE_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t dataDirectionRegister = MCP23008_DDR_A;
|
||||
uint8_t val = readReg(dataDirectionRegister);
|
||||
if (_error != MCP23008_OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
uint8_t mask = 1 << pin;
|
||||
// only work with valid
|
||||
if ((mode == INPUT) || (mode == INPUT_PULLUP))
|
||||
{
|
||||
val |= mask;
|
||||
}
|
||||
else if (mode == OUTPUT)
|
||||
{
|
||||
val &= ~mask;
|
||||
}
|
||||
// other values won't change val ....
|
||||
writeReg(dataDirectionRegister, val);
|
||||
if (_error != MCP23008_OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// pin = 0..7
|
||||
// value = LOW, HIGH
|
||||
bool MCP23008::digitalWrite(uint8_t pin, uint8_t value)
|
||||
{
|
||||
if (pin > 7)
|
||||
{
|
||||
_error = MCP23008_PIN_ERROR;
|
||||
return false;
|
||||
}
|
||||
uint8_t IOR = MCP23008_GPIO_A;
|
||||
uint8_t val = readReg(IOR);
|
||||
if (_error != MCP23008_OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t mask = 1 << pin;
|
||||
if (value)
|
||||
{
|
||||
val |= mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
val &= ~mask;
|
||||
}
|
||||
writeReg(IOR, val);
|
||||
if (_error != MCP23008_OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
uint8_t MCP23008::digitalRead(uint8_t pin)
|
||||
{
|
||||
if (pin > 7)
|
||||
{
|
||||
_error = MCP23008_PIN_ERROR;
|
||||
return MCP23008_INVALID_READ;
|
||||
}
|
||||
uint8_t IOR = MCP23008_GPIO_A;
|
||||
uint8_t val = readReg(IOR);
|
||||
if (_error != MCP23008_OK)
|
||||
{
|
||||
return MCP23008_INVALID_READ;
|
||||
}
|
||||
uint8_t mask = 1 << pin;
|
||||
if (val & mask) return HIGH;
|
||||
return LOW;
|
||||
}
|
||||
|
||||
|
||||
// pin = 0..7
|
||||
// reverse = true or false
|
||||
bool MCP23008::setPolarity(uint8_t pin, bool reversed)
|
||||
{
|
||||
if (pin > 7)
|
||||
{
|
||||
_error = MCP23008_PIN_ERROR;
|
||||
return false;
|
||||
}
|
||||
uint8_t inputPolarityRegister = MCP23008_POL_A;
|
||||
uint8_t val = readReg(inputPolarityRegister);
|
||||
if (_error != MCP23008_OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
uint8_t mask = 1 << pin;
|
||||
if (reversed)
|
||||
{
|
||||
val |= mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
val &= ~mask;
|
||||
}
|
||||
writeReg(inputPolarityRegister, val);
|
||||
if (_error != MCP23008_OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool MCP23008::getPolarity(uint8_t pin, bool &reversed)
|
||||
{
|
||||
if (pin > 7)
|
||||
{
|
||||
_error = MCP23008_PIN_ERROR;
|
||||
return false;
|
||||
}
|
||||
uint8_t inputPolarityRegister = MCP23008_POL_A;
|
||||
uint8_t val = readReg(inputPolarityRegister);
|
||||
if (_error != MCP23008_OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
uint8_t mask = 1 << pin;
|
||||
reversed = (val & mask) > 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// pin = 0..7
|
||||
// reverse = true or false
|
||||
bool MCP23008::setPullup(uint8_t pin, bool pullup)
|
||||
{
|
||||
if (pin > 7)
|
||||
{
|
||||
_error = MCP23008_PIN_ERROR;
|
||||
return false;
|
||||
}
|
||||
uint8_t inputPullupRegister = MCP23008_PUR_A;
|
||||
uint8_t val = readReg(inputPullupRegister);
|
||||
if (_error != MCP23008_OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
uint8_t mask = 1 << pin;
|
||||
if (pullup)
|
||||
{
|
||||
val |= mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
val &= ~mask;
|
||||
}
|
||||
writeReg(inputPullupRegister, val);
|
||||
if (_error != MCP23008_OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool MCP23008::getPullup(uint8_t pin, bool &pullup)
|
||||
{
|
||||
if (pin > 7)
|
||||
{
|
||||
_error = MCP23008_PIN_ERROR;
|
||||
return false;
|
||||
}
|
||||
uint8_t inputPullupRegister = MCP23008_PUR_A;
|
||||
uint8_t val = readReg(inputPullupRegister);
|
||||
if (_error != MCP23008_OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
uint8_t mask = 1 << pin;
|
||||
pullup = (val & mask) > 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// 8 pins interface
|
||||
// whole register at once
|
||||
// value = 0..0xFF bit pattern
|
||||
bool MCP23008::pinMode8(uint8_t value)
|
||||
{
|
||||
writeReg(MCP23008_DDR_A, value);
|
||||
_error = MCP23008_OK;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool MCP23008::write8(uint8_t value)
|
||||
{
|
||||
writeReg(MCP23008_GPIO_A, value);
|
||||
_error = MCP23008_OK;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int MCP23008::read8()
|
||||
{
|
||||
_error = MCP23008_OK;
|
||||
return readReg(MCP23008_GPIO_A);
|
||||
}
|
||||
|
||||
|
||||
// mask = 0..0xFF bit pattern
|
||||
bool MCP23008::setPolarity8(uint8_t mask)
|
||||
{
|
||||
writeReg(MCP23008_POL_A, mask);
|
||||
if (_error != MCP23008_OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool MCP23008::getPolarity8(uint8_t &mask)
|
||||
{
|
||||
mask = readReg(MCP23008_POL_A);
|
||||
if (_error != MCP23008_OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// mask = 0..0xFF bit pattern
|
||||
bool MCP23008::setPullup8(uint8_t mask)
|
||||
{
|
||||
writeReg(MCP23008_PUR_A, mask);
|
||||
if (_error != MCP23008_OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool MCP23008::getPullup8(uint8_t &mask)
|
||||
{
|
||||
mask = readReg(MCP23008_PUR_A);
|
||||
if (_error != MCP23008_OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int MCP23008::lastError()
|
||||
{
|
||||
int e = _error;
|
||||
_error = MCP23008_OK; // reset error after read.
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//
|
||||
// PRIVATE
|
||||
//
|
||||
|
||||
bool MCP23008::writeReg(uint8_t reg, uint8_t value)
|
||||
{
|
||||
_wire->beginTransmission(_address);
|
||||
_wire->write(reg);
|
||||
_wire->write(value);
|
||||
if (_wire->endTransmission() != 0)
|
||||
{
|
||||
_error = MCP23008_I2C_ERROR;
|
||||
return false;
|
||||
}
|
||||
_error = MCP23008_OK;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
uint8_t MCP23008::readReg(uint8_t reg)
|
||||
{
|
||||
_wire->beginTransmission(_address);
|
||||
_wire->write(reg);
|
||||
if (_wire->endTransmission() != 0)
|
||||
{
|
||||
_error = MCP23008_I2C_ERROR;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_error = MCP23008_OK;
|
||||
}
|
||||
uint8_t n = _wire->requestFrom(_address, (uint8_t)1);
|
||||
if (n != 1)
|
||||
{
|
||||
_error = MCP23008_I2C_ERROR;
|
||||
return 0;
|
||||
}
|
||||
return _wire->read();
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
76
libraries/MCP23008/MCP23008.h
Normal file
76
libraries/MCP23008/MCP23008.h
Normal file
@ -0,0 +1,76 @@
|
||||
#pragma once
|
||||
//
|
||||
// FILE: MCP23008.h
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.0
|
||||
// PURPOSE: Arduino library for I2C MCP23008 16 channel port expander
|
||||
// DATE: 2022-01-10
|
||||
// URL: https://github.com/RobTillaart/MCP23008
|
||||
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Wire.h"
|
||||
|
||||
|
||||
#define MCP23008_LIB_VERSION (F("0.1.0"))
|
||||
|
||||
#define MCP23008_OK 0x00
|
||||
#define MCP23008_PIN_ERROR 0x81
|
||||
#define MCP23008_I2C_ERROR 0x82
|
||||
#define MCP23008_VALUE_ERROR 0x83
|
||||
#define MCP23008_PORT_ERROR 0x84
|
||||
|
||||
|
||||
#define MCP23008_INVALID_READ -100
|
||||
|
||||
|
||||
class MCP23008
|
||||
{
|
||||
public:
|
||||
MCP23008(uint8_t address, TwoWire *wire = &Wire);
|
||||
|
||||
#if defined(ESP8266) || defined(ESP32)
|
||||
bool begin(const uint8_t dataPin, const uint8_t clockPin);
|
||||
#endif
|
||||
bool begin();
|
||||
bool isConnected();
|
||||
|
||||
|
||||
// single pin interface
|
||||
// mode = INPUT, OUTPUT or INPUT_PULLUP (==INPUT)
|
||||
bool pinMode(uint8_t pin, uint8_t mode);
|
||||
bool digitalWrite(uint8_t pin, uint8_t value);
|
||||
uint8_t digitalRead(uint8_t pin);
|
||||
|
||||
bool setPolarity(uint8_t pin, bool reversed);
|
||||
bool getPolarity(uint8_t pin, bool &reversed);
|
||||
bool setPullup(uint8_t pin, bool pullup);
|
||||
bool getPullup(uint8_t pin, bool &pullup);
|
||||
|
||||
|
||||
// 8 pins interface
|
||||
// value = bit pattern
|
||||
bool pinMode8(uint8_t value);
|
||||
bool write8(uint8_t value);
|
||||
int read8();
|
||||
|
||||
bool setPolarity8(uint8_t mask);
|
||||
bool getPolarity8(uint8_t &mask);
|
||||
bool setPullup8(uint8_t mask);
|
||||
bool getPullup8(uint8_t &mask);
|
||||
|
||||
|
||||
int lastError();
|
||||
|
||||
private:
|
||||
bool writeReg(uint8_t reg, uint8_t value);
|
||||
uint8_t readReg(uint8_t reg);
|
||||
|
||||
uint8_t _address;
|
||||
TwoWire* _wire;
|
||||
uint8_t _error;
|
||||
};
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
77
libraries/MCP23008/README.md
Normal file
77
libraries/MCP23008/README.md
Normal file
@ -0,0 +1,77 @@
|
||||
|
||||
[![Arduino CI](https://github.com/RobTillaart/MCP23008/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
|
||||
[![Arduino-lint](https://github.com/RobTillaart/MCP23008/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/MCP23008/actions/workflows/arduino-lint.yml)
|
||||
[![JSON check](https://github.com/RobTillaart/MCP23008/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/MCP23008/actions/workflows/jsoncheck.yml)
|
||||
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/MCP23008/blob/master/LICENSE)
|
||||
[![GitHub release](https://img.shields.io/github/release/RobTillaart/MCP23008.svg?maxAge=3600)](https://github.com/RobTillaart/MCP23008/releases)
|
||||
|
||||
|
||||
# MCP23008
|
||||
|
||||
Arduino library for MCP23008 8 channel I2C port expander.
|
||||
|
||||
|
||||
## Description
|
||||
|
||||
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.
|
||||
|
||||
|
||||
## Interface
|
||||
|
||||
### Constructor
|
||||
|
||||
- **MCP23008(uint8_t address, TwoWire \*wire = &Wire)** constructor, with default Wire interface.
|
||||
Can be overruled with Wire0..WireN.
|
||||
- **bool begin()** for UNO, returns true if successful.
|
||||
- **bool begin(uint8_t sda, uint8_t scl)** for ESP32, returns true if successful.
|
||||
- **bool isConnected()** returns true if connected, false otherwise.
|
||||
|
||||
|
||||
### 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.
|
||||
- **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.
|
||||
|
||||
|
||||
### 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.
|
||||
- **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.
|
||||
|
||||
|
||||
### Error codes
|
||||
|
||||
- **int lastError()** Above functions set an error flag that can be read with this function.
|
||||
Reading it will reset the flag to **MCP23008_OK**.
|
||||
|
||||
| DESCRIPTION | VALUE |
|
||||
|:----------------------|:-----:|
|
||||
| MCP23008_OK | 0x00 |
|
||||
| MCP23008_PIN_ERROR | 0x81 |
|
||||
| MCP23008_I2C_ERROR | 0x82 |
|
||||
| MCP23008_VALUE_ERROR | 0x83 |
|
||||
| MCP23008_PORT_ERROR | 0x84 |
|
||||
|
||||
|
||||
## Operation
|
||||
|
||||
See examples.
|
||||
|
||||
|
||||
## Future
|
||||
|
||||
- keep in sync with MCP23017
|
||||
|
Binary file not shown.
@ -0,0 +1,40 @@
|
||||
//
|
||||
// FILE: MCP23008_digitalRead.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// DATE: 2019-10-14
|
||||
// PUPROSE: test MCP23008 library
|
||||
|
||||
|
||||
#include "MCP23008.h"
|
||||
#include "Wire.h"
|
||||
|
||||
|
||||
MCP23008 MCP(0x27);
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(230400);
|
||||
Serial.print("MCP23008_test version: ");
|
||||
Serial.println(MCP23008_LIB_VERSION);
|
||||
|
||||
Wire.begin();
|
||||
MCP.begin();
|
||||
|
||||
MCP.pinMode8(0x00);
|
||||
|
||||
Serial.println("TEST digitalRead(pin)");
|
||||
for (int pin = 0; pin < 8; pin++)
|
||||
{
|
||||
int val = MCP.digitalRead(pin);
|
||||
Serial.print(val);
|
||||
Serial.print('\t');
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
@ -0,0 +1,68 @@
|
||||
//
|
||||
// FILE: MCP23008_digitalWrite.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// DATE: 2019-10-14
|
||||
// PUPROSE: test MCP23008 library
|
||||
|
||||
|
||||
#include "MCP23008.h"
|
||||
#include "Wire.h"
|
||||
|
||||
|
||||
MCP23008 MCP(0x27);
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(230400);
|
||||
Serial.print("MCP23008_test version: ");
|
||||
Serial.println(MCP23008_LIB_VERSION);
|
||||
|
||||
Wire.begin();
|
||||
|
||||
MCP.begin();
|
||||
|
||||
MCP.pinMode8(0x00); // 0 = output , 1 = input
|
||||
Wire.setClock(100000);
|
||||
|
||||
Serial.println("TEST digitalWrite(0)");
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
MCP.digitalWrite(0, i % 2); // alternating HIGH/LOW
|
||||
Serial.print(i % 2);
|
||||
Serial.print('\t');
|
||||
delay(250);
|
||||
}
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
Serial.println("TEST digitalWrite(pin)");
|
||||
for (int pin = 0; pin < 8; pin++)
|
||||
{
|
||||
MCP.digitalWrite(pin, 1 - pin % 2); // alternating HIGH/LOW
|
||||
Serial.print(1 - pin % 2);
|
||||
Serial.print('\t');
|
||||
}
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
Serial.println("TEST read back");
|
||||
|
||||
for (int pin = 0; pin < 8; pin++)
|
||||
{
|
||||
int val = MCP.digitalRead(pin);
|
||||
Serial.print(val);
|
||||
Serial.print('\t');
|
||||
}
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
@ -0,0 +1,97 @@
|
||||
//
|
||||
// FILE: MCP23008_performance.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// DATE: 2022-01-09
|
||||
// PUPROSE: test MCP23008 library
|
||||
|
||||
|
||||
#include "MCP23008.h"
|
||||
#include "Wire.h"
|
||||
|
||||
MCP23008 MCP(0x27);
|
||||
|
||||
uint32_t start, stop;
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println();
|
||||
Serial.print("MCP23008_LIB_VERSION: ");
|
||||
Serial.println(MCP23008_LIB_VERSION);
|
||||
Serial.println();
|
||||
delay(100);
|
||||
|
||||
Wire.begin();
|
||||
bool b = MCP.begin();
|
||||
|
||||
MCP.pinMode8(0x00); // 0 = output , 1 = input
|
||||
|
||||
Serial.println("\ntime in microseconds\n");
|
||||
delay(100);
|
||||
|
||||
|
||||
Serial.print("TEST digitalWrite(0, value):\t");
|
||||
delay(100);
|
||||
start = micros();
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
MCP.digitalWrite(i, i & 0x01); // alternating HIGH/LOW
|
||||
}
|
||||
stop = micros();
|
||||
Serial.println((stop - start) / 8.0);
|
||||
|
||||
|
||||
Serial.print("TEST digitalWrite(pin, value):\t");
|
||||
delay(100);
|
||||
start = micros();
|
||||
for (int pin = 0; pin < 8; pin++)
|
||||
{
|
||||
MCP.digitalWrite(pin, 1 - pin % 2); // alternating HIGH/LOW
|
||||
}
|
||||
stop = micros();
|
||||
Serial.println((stop - start) / 8.0);
|
||||
|
||||
|
||||
Serial.print("TEST digitalRead(pin):\t");
|
||||
delay(100);
|
||||
start = micros();
|
||||
for (int pin = 0; pin < 8; pin++)
|
||||
{
|
||||
volatile int val = MCP.digitalRead(pin);
|
||||
}
|
||||
stop = micros();
|
||||
Serial.println((stop - start) / 8.0);
|
||||
Serial.println();
|
||||
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
//
|
||||
// write8 read8 interface
|
||||
//
|
||||
Serial.print("TEST write8(mask):\t");
|
||||
delay(100);
|
||||
start = micros();
|
||||
MCP.write8(0xAA); // alternating HIGH/LOW
|
||||
stop = micros();
|
||||
Serial.println(stop - start);
|
||||
|
||||
|
||||
Serial.print("TEST read8():\t");
|
||||
delay(100);
|
||||
start = micros();
|
||||
volatile int val8 = MCP.read8();
|
||||
stop = micros();
|
||||
Serial.println(stop - start);
|
||||
Serial.println();
|
||||
|
||||
Serial.println("\ndone...");
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
23
libraries/MCP23008/library.json
Normal file
23
libraries/MCP23008/library.json
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "MCP23008",
|
||||
"keywords": "MCP23008,I2C, 8 IO, polarity, pullup",
|
||||
"description": "Arduino library for I2C MCP23008 8 channel port expander",
|
||||
"authors":
|
||||
[
|
||||
{
|
||||
"name": "Rob Tillaart",
|
||||
"email": "Rob.Tillaart@gmail.com",
|
||||
"maintainer": true
|
||||
}
|
||||
],
|
||||
"repository":
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/MCP23008.git"
|
||||
},
|
||||
"version": "0.1.0",
|
||||
"license": "MIT",
|
||||
"frameworks": "arduino",
|
||||
"platforms": "*",
|
||||
"headers": "MCP23008.h"
|
||||
}
|
11
libraries/MCP23008/library.properties
Normal file
11
libraries/MCP23008/library.properties
Normal file
@ -0,0 +1,11 @@
|
||||
name=MCP23008
|
||||
version=0.1.0
|
||||
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
|
||||
paragraph= setPolarity, setPullup
|
||||
category=Signal Input/Output
|
||||
url=https://github.com/RobTillaart/MCP23008
|
||||
architectures=*
|
||||
includes=MCP23008.h
|
||||
depends=
|
107
libraries/MCP23008/test/unit_test_001.cpp
Normal file
107
libraries/MCP23008/test/unit_test_001.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
//
|
||||
// FILE: unit_test_001.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// DATE: 2022-01-10
|
||||
// PURPOSE: unit tests for the MCP23008
|
||||
// https://github.com/RobTillaart/MCP23008
|
||||
// https://github.com/Arduino-CI/arduino_ci/blob/master/REFERENCE.md
|
||||
//
|
||||
|
||||
// supported assertions
|
||||
// ----------------------------
|
||||
// assertEqual(expected, actual); // a == b
|
||||
// assertNotEqual(unwanted, actual); // a != b
|
||||
// assertComparativeEquivalent(expected, actual); // abs(a - b) == 0 or (!(a > b) && !(a < b))
|
||||
// assertComparativeNotEquivalent(unwanted, actual); // abs(a - b) > 0 or ((a > b) || (a < b))
|
||||
// assertLess(upperBound, actual); // a < b
|
||||
// assertMore(lowerBound, actual); // a > b
|
||||
// assertLessOrEqual(upperBound, actual); // a <= b
|
||||
// assertMoreOrEqual(lowerBound, actual); // a >= b
|
||||
// assertTrue(actual);
|
||||
// assertFalse(actual);
|
||||
// assertNull(actual);
|
||||
|
||||
// // special cases for floats
|
||||
// assertEqualFloat(expected, actual, epsilon); // fabs(a - b) <= epsilon
|
||||
// assertNotEqualFloat(unwanted, actual, epsilon); // fabs(a - b) >= epsilon
|
||||
// assertInfinity(actual); // isinf(a)
|
||||
// assertNotInfinity(actual); // !isinf(a)
|
||||
// assertNAN(arg); // isnan(a)
|
||||
// assertNotNAN(arg); // !isnan(a)
|
||||
|
||||
#include <ArduinoUnitTests.h>
|
||||
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "MCP23008.h"
|
||||
|
||||
|
||||
unittest_setup()
|
||||
{
|
||||
fprintf(stderr, "MCP23008_LIB_VERSION: %s\n", (char *) MCP23008_LIB_VERSION);
|
||||
}
|
||||
|
||||
|
||||
unittest_teardown()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
unittest(test_constants)
|
||||
{
|
||||
assertEqual(MCP23008_OK , 0x00);
|
||||
assertEqual(MCP23008_PIN_ERROR , 0x81);
|
||||
assertEqual(MCP23008_I2C_ERROR , 0x82);
|
||||
assertEqual(MCP23008_VALUE_ERROR , 0x83);
|
||||
assertEqual(MCP23008_PORT_ERROR , 0x84);
|
||||
assertEqual(MCP23008_INVALID_READ, -100);
|
||||
}
|
||||
|
||||
|
||||
// TODO more tests if godmode->wire works
|
||||
unittest(test_constructor)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
|
||||
MCP23008 MCP(0x27);
|
||||
|
||||
assertFalse(Wire.didBegin());
|
||||
MCP.begin();
|
||||
// in fact invalid ...
|
||||
assertTrue(Wire.didBegin());
|
||||
assertTrue(MCP.isConnected());
|
||||
}
|
||||
|
||||
|
||||
unittest(test_lastError)
|
||||
{
|
||||
Wire.resetMocks();
|
||||
|
||||
MCP23008 MCP(0x27);
|
||||
MCP.begin();
|
||||
assertEqual(MCP23008_OK, MCP.lastError());
|
||||
|
||||
// MCP23008_PIN_ERROR
|
||||
MCP.pinMode(8, INPUT);
|
||||
assertEqual(MCP23008_PIN_ERROR, MCP.lastError());
|
||||
assertEqual(MCP23008_OK, MCP.lastError());
|
||||
|
||||
MCP.digitalWrite(8, 1);
|
||||
assertEqual(MCP23008_PIN_ERROR, MCP.lastError());
|
||||
assertEqual(MCP23008_OK, MCP.lastError());
|
||||
|
||||
uint8_t y = MCP.digitalRead(8);
|
||||
assertEqual(MCP23008_PIN_ERROR, MCP.lastError());
|
||||
assertEqual(MCP23008_OK, MCP.lastError());
|
||||
|
||||
|
||||
// MCP23008_VALUE_ERROR - 3 is not INPUT, INPUT_PULLUP, OUTPUT)
|
||||
MCP.pinMode(0, 3);
|
||||
assertEqual(MCP23008_VALUE_ERROR, MCP.lastError());
|
||||
assertEqual(MCP23008_OK, MCP.lastError());
|
||||
}
|
||||
|
||||
|
||||
unittest_main()
|
||||
|
||||
// --------
|
Loading…
Reference in New Issue
Block a user