0.1.1 TCA9548

This commit is contained in:
rob tillaart 2021-11-19 13:21:54 +01:00
parent 90ae8280cd
commit 6d0b984593
10 changed files with 85 additions and 52 deletions

View File

@ -2,6 +2,10 @@ compile:
# Choosing to run compilation tests on 2 different Arduino platforms
platforms:
- uno
- leonardo
- due
- zero
- leonardo
- m4
- esp32
- esp8266
- mega2560

View File

@ -4,10 +4,14 @@ name: Arduino CI
on: [push, pull_request]
jobs:
arduino_ci:
runTest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: Arduino-CI/action@master
# Arduino-CI/action@v0.1.1
- uses: ruby/setup-ruby@v1
with:
ruby-version: 2.6
- run: |
gem install arduino_ci
arduino_ci.rb

View File

@ -1,17 +1,22 @@
[![Arduino CI](https://github.com/RobTillaart/TCA9548/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
[![Arduino-lint](https://github.com/RobTillaart/TCA9548/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/TCA9548/actions/workflows/arduino-lint.yml)
[![JSON check](https://github.com/RobTillaart/TCA9548/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/TCA9548/actions/workflows/jsoncheck.yml)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/TCA9548/blob/master/LICENSE)
[![GitHub release](https://img.shields.io/github/release/RobTillaart/TCA9548.svg?maxAge=3600)](https://github.com/RobTillaart/TCA9548/releases)
# TCA9548
Arduino Library for TCA9548 I2C multiplexer.
## Description
Library for the TCA9548 and TCA9548a I2C multiplexer.
The library allows you to enable 0 to 7 I2C channels (ports) uniquely or simultaneously.
This is especially handy if you have multiple devices/sensors that have a fixed address.
This is especially useful if you have multiple devices/sensors that have a fixed address,
or you have address conflicts between I2C devices
**Warning**
The library is not tested extensively.
@ -21,19 +26,21 @@ I2C address is 0x70 .. 0x77.
The library caches the channels enabled, and if a channel is enabled,
it will not be enabled again (low level) to optimize performance.
## Interface
### Constructor
- **TCA9548(const uint8_t deviceAddress, TwoWire \*wire = &Wire);)** Constructor, Address = 0x70 .. 0x77, wire = Wire or WireN.
- **bool begin(uint8_t sda, uint8_t scl, uint8_t mask = 0x00);** Set I2C pins for ESP32 alikes, set mask of channels to be enabled.
- **bool begin(uint8_t mask = 0x00);** set mask of channels to be enabled.
- **bool isConnected()** retuns true if address of the multiplexer itself is found on I2C bus.
- **TCA9548(const uint8_t deviceAddress, TwoWire \*wire = &Wire)** Constructor, address = 0x70 .. 0x77, wire = Wire or WireN.
- **bool begin(uint8_t sda, uint8_t scl, uint8_t mask = 0x00)** Set I2C pins for ESP32, set mask of channels to be enabled.
- **bool begin(uint8_t mask = 0x00)** set mask of channels to be enabled.
- **bool isConnected()** returns true if address of the multiplexer is found on I2C bus.
### Find device
- **bool isConnected(uint8_t addr)** retuns true if arbitrary address is found on I2C bus.
- **bool isConnected(uint8_t address)** returns true if arbitrary address is found on I2C bus.
This can be used to verify a certain device is available (or not) on an enabled channel.
@ -41,13 +48,25 @@ This can be used to verify a certain device is available (or not) on an enabled
- **void enableChannel(uint8_t channel)** enables channel 0 .. 7. Multiple channels can be enabled in parallel.
- **void disableChannel(uint8_t channel)** disables channel 0 .. 7. Will not disable other channels.
- **void selectChannel(uint8_t channel)** enables a single channel 0 .. 7 uniquely. All other channels will be disabled, although these can be set again with enableChannel.
- **void selectChannel(uint8_t channel)** enables a single channel 0 .. 7 uniquely.
All other channels will be disabled, although these can be set again with enableChannel.
- **bool isEnabled(uint8_t channel)** returns true is a channel is enabled.
- **void setChannelMask(uint8_t mask)** enables 0 or more channels simultaneously with a bitmask.
- **uint8_t getChannelMask()** reads back the bitmask of the channels enabled.
- **void setChannelMask(uint8_t mask)** enables 0 or more channels simultaneously with a bit mask.
- **uint8_t getChannelMask()** reads back the bit mask of the channels enabled.
- **void setResetPin(uint8_t resetPin)** sets the pin to reset the chip. (Not tested)
- **void reset()** trigger the reset pin.
- **getError()** returns the last I2C error.
- **int getError()** returns the last I2C error.
### Forced IO
When forced IO is set all writes and read - **getChannelMask()** - will go to the device.
If the flag is set to false it will cache the value of the channels enabled.
This will result in more responsive / faster calls.
Note that writes are only optimized if the channels are already set.
- **void setForced(bool forced = false)** set forced write, slower but more robust. Default off.
- **bool getForced()** returns set flag.
## Operation
@ -57,9 +76,12 @@ See example
## Future
- improve error handling + documentation.
- add examples
- check TODO in code
- test test and test
- improve documentation
- write unit test
- forced write to chip ? robustness vs performance
- set an "always enabled" mask (have to investigate the consequences)

View File

@ -1,12 +1,16 @@
//
// FILE: TCA9548.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// VERSION: 0.1.1
// DATE: 2021-03-16
// PURPOSE: Library for TCA9548 I2C multiplexer
//
// HISTORY:
// 0.1.0 2021-03-16 initial version
// 0.1.1 2021-11-19 fix reset code (from datasheet)
// implemented forced IO
// update build-CI, readme.md, badges
//
#include "TCA9548.h"
@ -19,6 +23,7 @@ TCA9548::TCA9548(const uint8_t deviceAddress, TwoWire *wire)
_mask = 0x00;
_resetPin = -1;
_forced = false;
_error = 0;
}
@ -54,9 +59,9 @@ bool TCA9548::isConnected()
}
bool TCA9548::isConnected(uint8_t addr)
bool TCA9548::isConnected(uint8_t address)
{
_wire->beginTransmission(addr);
_wire->beginTransmission(address);
return ( _wire->endTransmission() == 0);
}
@ -101,6 +106,11 @@ void TCA9548::setChannelMask(uint8_t mask)
uint8_t TCA9548::getChannelMask()
{
if (_forced) // read from device.
{
_wire->requestFrom(_address, 1);
_mask = _wire->read();
}
return _mask;
}
@ -109,15 +119,15 @@ void TCA9548::setResetPin(uint8_t resetPin)
{
_resetPin = resetPin;
pinMode(_resetPin, OUTPUT);
digitalWrite(_resetPin, LOW); // CHECK
digitalWrite(_resetPin, HIGH); // page 3 HIGH is normal operation
}
void TCA9548::reset()
{
digitalWrite(_resetPin, HIGH); // CHECK
delay(1);
digitalWrite(_resetPin, LOW);
delayMicroseconds(1); // datasheet page 6 & 7 - 500 ns
digitalWrite(_resetPin, HIGH);
}

View File

@ -2,18 +2,19 @@
//
// FILE: TCA9548.h
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// VERSION: 0.1.1
// DATE: 2021-03-16
// PURPOSE: Library for TCA9548 I2C multiplexer
//
// URL: https://github.com/RobTillaart/TCA9548
//
#include "Arduino.h"
#include "Wire.h"
#define TCA9548_LIB_VERSION (F("0.1.0"))
#define TCA9548_LIB_VERSION (F("0.1.1"))
class TCA9548
@ -27,7 +28,7 @@ public:
#endif
bool begin(uint8_t mask = 0x00); // default no channels enabled
bool isConnected(); // find multiplexer on I2C bus
bool isConnected(uint8_t address); // find any addr on I2C bus
bool isConnected(uint8_t address); // find any address on I2C bus
// channel = 0.. 7
void enableChannel(uint8_t channel);
@ -42,21 +43,21 @@ public:
void setResetPin(uint8_t resetPin);
void reset(); // trigger reset pin
// set forced write
void setForced(bool forced) { _forced = forced; };
bool getForced() { return _forced; };
// set forced IO (default false)
void setForced(bool forced = false) { _forced = forced; };
bool getForced() { return _forced; };
// TODO improve errorhandling ?
int getError();
private:
uint8_t _mask = 0x00; // caching mask
uint8_t _resetPin = -1;
int _error = 0;
uint8_t _mask; // caching mask
uint8_t _resetPin;
int _error;
uint8_t _address;
TwoWire* _wire;
bool _forced;
};
// -- END OF FILE --

View File

@ -11,8 +11,6 @@
TCA9548 MP(0x70);
uint32_t start, stop;
void setup()
{
@ -26,7 +24,6 @@ void setup()
Serial.println("COULD NOT CONNECT");
}
Serial.print("MASK:\t");
Serial.println(MP.getChannelMask(), HEX);
for (int chan = 0; chan < 8; chan++)
@ -69,17 +66,5 @@ void loop()
}
void test()
{
start = millis();
stop = millis();
Serial.println();
Serial.print("TIME:\t");
Serial.print(stop - start);
Serial.println(" ms");
Serial.println();
}
// -- END OF FILE --

View File

@ -1,6 +1,6 @@
# Syntax Coloring Map For TCA9548
# Syntax Colouring Map For TCA9548
# Datatypes (KEYWORD1)
# Data types (KEYWORD1)
TCA9548 KEYWORD1

View File

@ -15,8 +15,9 @@
"type": "git",
"url": "https://github.com/RobTillaart/TCA9548"
},
"version": "0.1.0",
"version": "0.1.1",
"license": "MIT",
"frameworks": "arduino",
"platforms": "*"
"platforms": "*",
"headers": "TCA9548.h"
}

View File

@ -1,5 +1,5 @@
name=TCA9548
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 TCA9548 I2C multiplexer.

View File

@ -38,15 +38,18 @@
It appears that Wire.write does not fail without sensor...
*/
#include <ArduinoUnitTests.h>
#include "Arduino.h"
#include "TCA9548.h"
int expect; // TODO needed as there seems a problem with 8 bit comparisons (char?)
uint32_t start, stop;
unittest_setup()
{
}
@ -55,8 +58,10 @@ unittest_teardown()
{
}
unittest(test_begin)
{
fprintf(stderr, "TCA9548_LIB_VERSION: %s\n", (char *) TCA9548_LIB_VERSION);
TCA9548 tca(0x70);
bool b = tca.begin();
@ -66,6 +71,7 @@ unittest(test_begin)
}
unittest(test_enable)
{
TCA9548 tca(0x70);