Giter VIP home page Giter VIP logo

adafruit_circuitpython_tca9548a's Introduction

Introduction

Documentation Status

Discord

Build Status

Code Style: Black

CircuitPython driver for the TCA9548A I2C Multiplexer.

Dependencies

This driver depends on:

Please ensure all dependencies are available on the CircuitPython filesystem. This is easily achieved by downloading the Adafruit library and driver bundle.

Installing from PyPI

On supported GNU/Linux systems like the Raspberry Pi, you can install the driver locally from PyPI. To install for current user:

pip3 install adafruit-circuitpython-tca9548a

To install system-wide (this may be required in some cases):

sudo pip3 install adafruit-circuitpython-tca9548a

To install in a virtual environment in your current project:

mkdir project-name && cd project-name
python3 -m venv .venv
source .venv/bin/activate
pip3 install adafruit-circuitpython-tca9548a

Usage Example

Documentation

API documentation for this library can be found on Read the Docs.

For information on building library documentation, please check out this guide.

Contributing

Contributions are welcome! Please read our Code of Conduct before contributing to help this project stay welcoming.

adafruit_circuitpython_tca9548a's People

Contributors

blitzcitydiy avatar caternuson avatar dhalbert avatar evaherrada avatar foamyguy avatar gwndaan avatar jposada202020 avatar kattni avatar sak917 avatar siddacious avatar sommersoft avatar stevenbruinen avatar tannewt avatar tcfranks avatar tekktrik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

adafruit_circuitpython_tca9548a's Issues

No matching distribution found for typing-extensions~=4.0

pi@raspberrypi:~/Adafruit_CircuitPython_TCA9548A $ python3 --version
Python 3.5.3
pi@raspberrypi:~/Adafruit_CircuitPython_TCA9548A $ pip3 --version
pip 9.0.1 from /usr/lib/python3/dist-packages (python 3.5)
pi@raspberrypi:~/Adafruit_CircuitPython_TCA9548A $
pi@raspberrypi:~/Adafruit_CircuitPython_TCA9548A $
pi@raspberrypi:~/Adafruit_CircuitPython_TCA9548A $
pi@raspberrypi:~/Adafruit_CircuitPython_TCA9548A $ pip3 install -r requirements.txt
Collecting Adafruit-Blinka (from -r requirements.txt (line 5))
  Using cached https://www.piwheels.org/simple/adafruit-blinka/Adafruit_Blinka-5.13.1-py3-none-any.whl
Collecting adafruit-circuitpython-busdevice (from -r requirements.txt (line 6))
  Using cached https://www.piwheels.org/simple/adafruit-circuitpython-busdevice/adafruit_circuitpython_busdevice-5.2.4-py3-none-any.whl
Collecting adafruit-circuitpython-typing (from -r requirements.txt (line 7))
  Using cached https://www.piwheels.org/simple/adafruit-circuitpython-typing/adafruit_circuitpython_typing-1.9.2-py3-none-any.whl
Collecting typing-extensions~=4.0 (from -r requirements.txt (line 8))
  Could not find a version that satisfies the requirement typing-extensions~=4.0 (from -r requirements.txt (line 8)) (from versions: 3.6.2, 3.6.2.1, 3.6.5, 3.6.6, 3.7.2, 3.7.4, 3.7.4.1, 3.7.4.2, 3.7.4.3, 3.10.0.0, 3.10.0.1, 3.10.0.2)
No matching distribution found for typing-extensions~=4.0 (from -r requirements.txt (line 8))

python 3.5.3
pip 9.0.1

Support multiple TCAs

There's a simple way to disable the channel output for TCAs not currently in use:
https://learn.adafruit.com/adafruit-tca9548a-1-to-8-i2c-multiplexer-breakout/wiring-and-test#multiple-multplexers-4-13
but not sure how that could get implemented here and still maintain the current ease of use.

tca1 = adafruit_tca9548a.TCA9548A(i2c, address=TCA1_ADDRESS)
tca2 = adafruit_tca9548a.TCA9548A(i2c, address=TCA2_ADDRESS)

sensor1 = SomeSensor(tca1[0])
#
# etc for sensors 2-8
#
sensor9 = SomeSensor(tca2[0])
#
# etc for sensors 10-16
#

Maybe end all transactions with a disable-all-channels?

Not working with MLX90393

Re this thread:
https://forums.adafruit.com/viewtopic.php?f=60&t=165549

Issue recreated.

Adafruit CircuitPython 5.3.0 on 2020-04-29; Adafruit ItsyBitsy M4 Express with samd51g19
>>> import board, busio, adafruit_mlx90393, adafruit_tca9548a
>>> tca = adafruit_tca9548a.TCA9548A(board.I2C())
>>> mlx = adafruit_mlx90393.MLX90393(tca[7])

And work around verified:

Adafruit CircuitPython 5.3.0 on 2020-04-29; Adafruit ItsyBitsy M4 Express with samd51g19
>>> import board, busio, adafruit_mlx90393
>>> i2c = board.I2C()
>>> i2c.try_lock()
True
>>> i2c.writeto(0x70, b'\x80')
>>> i2c.unlock()
>>> mlx = adafruit_mlx90393.MLX90393(i2c)
>>> mlx.magnetic
(-301.8, 38.7, 190.212)
>>> 

setup

Issue with implementation of VL53L0X and TCA9548A multiplexer

kgdthomas commented 1 hour ago
I've been trying to work one vl53l0x with a TCA9548A. My code is as follows:

import time
import board
import busio
import adafruit_vl53l0x
import adafruit_tca9548a

# Create I2C bus as normal
i2c = busio.I2C(board.SCL, board.SDA)

# Create the TCA9548A object and give it the I2C bus
tca = adafruit_tca9548a.TCA9548A(i2c)

# For each sensor, create it using the TCA9548A channel instead of the I2C object
vl53a = adafruit_vl53l0x.VL53L0X(tca[0])
#vl53b = adafruit_vl53l0x.VL53L0X(tca[1])

#tsl2 = adafruit_tsl2591.TSL2591(tca[1])

# print range 1 per second
while True:
    print("Range: {0}mm".format(vl53a.range))
#    print("Range: {0}mm".format(vl53b.range))
    time.sleep(1.0)

# Optionally adjust the measurement timing budget to change speed and accuracy.
# See the example here for more details:
#   https://github.com/pololu/vl53l0x-arduino/blob/master/examples/Single/Single.ino
# For example a higher speed but less accurate timing budget of 20ms:
# Measured in microseconds
# 1 second = 1000 millisecond = 1000000 microsecond
# vl53.measurement_timing_budget = 20000
# Or a slower but more accurate timing budget of 200ms:
# vl53.measurement_timing_budget = 200000
# The default timing budget is 33ms, a good compromise of speed and accuracy.

but every attempt leads to the following error.

%Run test-i2c.py
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/dist-packages/adafruit_bus_device/i2c_device.py", line 154, in __probe_for_device
    self.i2c.writeto(self.device_address, b"")
  File "/home/pi/.local/lib/python3.7/site-packages/adafruit_tca9548a.py", line 67, in writeto
    return self.tca.i2c.writeto(address, buffer, **kwargs)
  File "/home/pi/.local/lib/python3.7/site-packages/busio.py", line 116, in writeto
    return self._i2c.writeto(address, buffer, stop=stop)
  File "/home/pi/.local/lib/python3.7/site-packages/adafruit_blinka/microcontroller/generic_linux/i2c.py", line 49, in writeto
    self._i2c_bus.write_bytes(address, buffer[start:end])
  File "/home/pi/.local/lib/python3.7/site-packages/Adafruit_PureIO/smbus.py", line 308, in write_bytes
    self._device.write(buf)
OSError: [Errno 121] Remote I/O error

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/dist-packages/adafruit_bus_device/i2c_device.py", line 160, in __probe_for_device
    self.i2c.readfrom_into(self.device_address, result)
  File "/home/pi/.local/lib/python3.7/site-packages/adafruit_tca9548a.py", line 61, in readfrom_into
    return self.tca.i2c.readfrom_into(address, buffer, **kwargs)
  File "/home/pi/.local/lib/python3.7/site-packages/busio.py", line 106, in readfrom_into
    return self._i2c.readfrom_into(address, buffer, stop=stop)
  File "/home/pi/.local/lib/python3.7/site-packages/adafruit_blinka/microcontroller/generic_linux/i2c.py", line 56, in readfrom_into
    readin = self._i2c_bus.read_bytes(address, end - start)
  File "/home/pi/.local/lib/python3.7/site-packages/Adafruit_PureIO/smbus.py", line 179, in read_bytes
    return self._device.read(number)
OSError: [Errno 121] Remote I/O error

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/pi/Desktop/test-i2c.py", line 19, in <module>
    vl53l0x = adafruit_vl53l0x.VL53L0X(tca9548a[0])
  File "/usr/local/lib/python3.7/dist-packages/adafruit_vl53l0x.py", line 142, in __init__
    self._device = i2c_device.I2CDevice(i2c, address)
  File "/usr/local/lib/python3.7/dist-packages/adafruit_bus_device/i2c_device.py", line 50, in __init__
    self.__probe_for_device()
  File "/usr/local/lib/python3.7/dist-packages/adafruit_bus_device/i2c_device.py", line 163, in __probe_for_device
    raise ValueError("No I2C device at address: 0x%x" % self.device_address)
ValueError: No I2C device at address: 0x29

Bug : Channel Switch Missing in TCA9548A_Channel.scan

Action: To perform i2c scan on a particular channel in TCA9548A

...
# Initialize I2C bus.
i2c = busio.I2C(I2C1_SCL_PIN,I2C1_SDA_PIN)
# default TCA address=0x70
tca = adafruit_tca9548a.TCA9548A(i2c)

print([hex(i) for i in i2c.scan()])
print([hex(i) for i in tca[0].scan()])
...

Expected result: Perform i2c scan on selected channel

$ python i2c-mux.py 
['0x70']
['0x60', '0x70'] #MCP4725 DAC module is connected to channel 0 of TCA9548A
Press Entre to exit..

Actual Result: It Performs i2c scan on actual i2c bus where TCA9548A is connected

$ python i2c-mux.py 
['0x70']
['0x70']
Press Entre to exit..

Correction : TCA9548A_Channel.scan needs to be modified

def scan(self):
"""Perform an I2C Device Scan"""
return self.tca.i2c.scan()

read addresses of hardware on several multiplexers

Hi. I'm new to this so sorry if I have done it all wrong, and my general ignorance.

I have a pi pico and two tca9548a devices. One on 0x70 and another on 0x72

As I see it this means I have an extra 16 'slots' to attach address-contended (or indeed any) devices.

I have used i2c.scan() and can find the multiplexers, and any other hardware on the main bus.
I have then instantiated the 'found' multiplexers on the i2c bus ( I've assumed they are multiplexers due to their address, but can the library prove/test that they are?), using this:
adafruit_tca9548a.TCA9548A(bus, address=hex(l))

I have connected random hardware to the multiplexers in random places, and I want to 'find' each connected device on its channel by scanning the 8 possible channels for each of the two and see what's there (by getting an address if there is one, like with i2c.scan(), somehow).

I think I can change the channel on a given mux using
TCA9548A_Channel(tca[mux],channel) (tca[mux] = the hex address, channel = 0-7)

I cant see how to do this with the library? is it possible?

code.txt

How to connect 4725 DAC devices through the multiplexer.

Trying to hook up multiple 4725 DAC breakouts using a TCA9548A:

Code follows:
#!/usr/bin/python3
import time
import board
import busio
import adafruit_tca9548a
import adafruit_mcp4725

#links for how to use the multi-plexer and the DAC's:
#https://github.com/adafruit/Adafruit_CircuitPython_TCA9548A
#https://github.com/adafruit/Adafruit_CircuitPython_MCP4725/blob/master/examples/mcp4725_simpletest.py

Create I2C bus as normal

i2c = busio.I2C(board.SCL, board.SDA)

Create the TCA9548A object and give it the I2C bus

tca = adafruit_tca9548a.TCA9548A(i2c)

#for each DAC, creat it using the TCA9548A channel instead of the i2c object
dac2 = adafruit_mcp4725.MCP4725(tca[2])
dac4 = adafruit_mcp4725.MCP4725(tca[4])

dac2.value = 30000
dac4.value = 30000

Which produces the following errors:

Traceback (most recent call last):
File "/home/pi/Documents/python_programs/plexer_new_lib_test1.py", line 20, in
dac2 = adafruit_mcp4725.MCP4725(tca[2])
File "/usr/local/lib/python3.7/dist-packages/adafruit_mcp4725.py", line 75, in init
self._i2c = i2c_device.I2CDevice(i2c, address)
File "/usr/local/lib/python3.7/dist-packages/adafruit_bus_device/i2c_device.py", line 65, in init
while not i2c.try_lock():
File "/usr/local/lib/python3.7/dist-packages/adafruit_tca9548a.py", line 65, in try_lock
self.tca.i2c.writeto(self.tca.address, self.channel_switch)
File "/usr/local/lib/python3.7/dist-packages/busio.py", line 82, in writeto
return self._i2c.writeto(address, buffer, stop=stop)
File "/usr/local/lib/python3.7/dist-packages/adafruit_blinka/microcontroller/generic_linux/i2c.py", line 38, in writeto
self._i2c_bus.write_bytes(address, buffer[start:end])
File "/usr/local/lib/python3.7/dist-packages/Adafruit_PureIO/smbus.py", line 244, in write_bytes
self._device.write(buf)
OSError: [Errno 121] Remote I/O error

TC library error handling in multiplexer is not available

The issue is probably due to missing documentation:

The below code does work even if 0x70 is not available:
with board.I2C() as i2c:
tca = adafruit_tca9548a.TCA9548A(i2c, 0x70)

I only get an error when accessing a channel:
try:
shed_AHT20 = adafruit_ahtx0.AHTx0(tca[1])
except(IOError, RuntimeError, Exception) as error:
...

The error is not about 0x70 not available but AHTx0 with 0x38.

After that exception my code blocks. Is there any option to handle the error that 0x70 is not availble?
Did I miss that?

Issues installing this package

I have tried different versions of python to see if it helps, it does not.

Somewhere in this library there is some unicode characters that cant be decoded. I have installed other adafruit packages without issues.

I have also tried installing older versions of this package and get the same error.

Can anyone suggest what I can do?

install --progress-bar off adafruit-circuitpython-tca9548a
Looking in indexes: http://127.0.0.1:36628
127.0.0.1 - - [28/Nov/2023 18:15:52] "GET /adafruit-circuitpython-tca9548a/ HTTP/1.1" 200 -
Collecting adafruit-circuitpython-tca9548a
Using cached http://127.0.0.1:36628/adafruit-circuitpython-tca9548a/adafruit_circuitpython_tca9548a-0.7.2-py3-none-any.whl/
Requirement already satisfied: typing-extensions~=4.0 in c:\users\craig-pc\appdata\local\pipkin\cache\workspaces\572d60ec1d3303b24c9425c8f5c5f661\lib\site-packages (from adafruit-circuitpython-tca9548a) (4.8.0)
Requirement already satisfied: adafruit-circuitpython-typing in c:\users\craig-pc\appdata\local\pipkin\cache\workspaces\572d60ec1d3303b24c9425c8f5c5f661\lib\site-packages (from adafruit-circuitpython-tca9548a) (1.9.5)
Requirement already satisfied: Adafruit-Blinka in c:\users\craig-pc\appdata\local\pipkin\cache\workspaces\572d60ec1d3303b24c9425c8f5c5f661\lib\site-packages (from adafruit-circuitpython-tca9548a) (8.25.0)
Requirement already satisfied: adafruit-circuitpython-busdevice in c:\users\craig-pc\appdata\local\pipkin\cache\workspaces\572d60ec1d3303b24c9425c8f5c5f661\lib\site-packages (from adafruit-circuitpython-tca9548a) (5.2.6)
ERROR: Exception:
Traceback (most recent call last):
File "C:\Users\CRAIG-PC\AppData\Local\pipkin\cache\workspaces\572d60ec1d3303b24c9425c8f5c5f661\lib\site-packages\pip_vendor\pkg_resources_init_.py", line 3021, in _dep_map
return self._dep_map
File "C:\Users\CRAIG-PC\AppData\Local\pipkin\cache\workspaces\572d60ec1d3303b24c9425c8f5c5f661\lib\site-packages\pip_vendor\pkg_resources_init
.py", line 2815, in getattr
raise AttributeError(attr)
AttributeError: _DistInfoDistribution__dep_map

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "C:\Users\CRAIG-PC\AppData\Local\pipkin\cache\workspaces\572d60ec1d3303b24c9425c8f5c5f661\lib\site-packages\pip_vendor\pkg_resources_init_.py", line 3012, in _parsed_pkg_info
return self.pkg_info
File "C:\Users\CRAIG-PC\AppData\Local\pipkin\cache\workspaces\572d60ec1d3303b24c9425c8f5c5f661\lib\site-packages\pip_vendor\pkg_resources_init
.py", line 2815, in getattr
raise AttributeError(attr)
AttributeError: _pkg_info

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "C:\Users\CRAIG-PC\AppData\Local\pipkin\cache\workspaces\572d60ec1d3303b24c9425c8f5c5f661\lib\site-packages\pip_internal\cli\base_command.py", line 167, in exc_logging_wrapper
status = run_func(*args)
File "C:\Users\CRAIG-PC\AppData\Local\pipkin\cache\workspaces\572d60ec1d3303b24c9425c8f5c5f661\lib\site-packages\pip_internal\cli\req_command.py", line 247, in wrapper
return func(self, options, args)
File "C:\Users\CRAIG-PC\AppData\Local\pipkin\cache\workspaces\572d60ec1d3303b24c9425c8f5c5f661\lib\site-packages\pip_internal\commands\install.py", line 369, in run
requirement_set = resolver.resolve(
File "C:\Users\CRAIG-PC\AppData\Local\pipkin\cache\workspaces\572d60ec1d3303b24c9425c8f5c5f661\lib\site-packages\pip_internal\resolution\resolvelib\resolver.py", line 92, in resolve
result = self._result = resolver.resolve(
File "C:\Users\CRAIG-PC\AppData\Local\pipkin\cache\workspaces\572d60ec1d3303b24c9425c8f5c5f661\lib\site-packages\pip_vendor\resolvelib\resolvers.py", line 481, in resolve
state = resolution.resolve(requirements, max_rounds=max_rounds)
File "C:\Users\CRAIG-PC\AppData\Local\pipkin\cache\workspaces\572d60ec1d3303b24c9425c8f5c5f661\lib\site-packages\pip_vendor\resolvelib\resolvers.py", line 373, in resolve
failure_causes = self._attempt_to_pin_criterion(name)
File "C:\Users\CRAIG-PC\AppData\Local\pipkin\cache\workspaces\572d60ec1d3303b24c9425c8f5c5f661\lib\site-packages\pip_vendor\resolvelib\resolvers.py", line 213, in _attempt_to_pin_criterion
criteria = self._get_updated_criteria(candidate)
File "C:\Users\CRAIG-PC\AppData\Local\pipkin\cache\workspaces\572d60ec1d3303b24c9425c8f5c5f661\lib\site-packages\pip_vendor\resolvelib\resolvers.py", line 203, in _get_updated_criteria
for requirement in self._p.get_dependencies(candidate=candidate):
File "C:\Users\CRAIG-PC\AppData\Local\pipkin\cache\workspaces\572d60ec1d3303b24c9425c8f5c5f661\lib\site-packages\pip_internal\resolution\resolvelib\provider.py", line 237, in get_dependencies
return [r for r in candidate.iter_dependencies(with_requires) if r is not None]
File "C:\Users\CRAIG-PC\AppData\Local\pipkin\cache\workspaces\572d60ec1d3303b24c9425c8f5c5f661\lib\site-packages\pip_internal\resolution\resolvelib\provider.py", line 237, in
return [r for r in candidate.iter_dependencies(with_requires) if r is not None]
File "C:\Users\CRAIG-PC\AppData\Local\pipkin\cache\workspaces\572d60ec1d3303b24c9425c8f5c5f661\lib\site-packages\pip_internal\resolution\resolvelib\candidates.py", line 395, in iter_dependencies
for r in self.dist.iter_dependencies():
File "C:\Users\CRAIG-PC\AppData\Local\pipkin\cache\workspaces\572d60ec1d3303b24c9425c8f5c5f661\lib\site-packages\pip_internal\metadata\pkg_resources.py", line 199, in iter_dependencies
return self.dist.requires(extras)
File "C:\Users\CRAIG-PC\AppData\Local\pipkin\cache\workspaces\572d60ec1d3303b24c9425c8f5c5f661\lib\site-packages\pip_vendor\pkg_resources_init
.py", line 2736, in requires
dm = self.dep_map
File "C:\Users\CRAIG-PC\AppData\Local\pipkin\cache\workspaces\572d60ec1d3303b24c9425c8f5c5f661\lib\site-packages\pip_vendor\pkg_resources_init
.py", line 3023, in _dep_map
self.__dep_map = self.compute_dependencies()
File "C:\Users\CRAIG-PC\AppData\Local\pipkin\cache\workspaces\572d60ec1d3303b24c9425c8f5c5f661\lib\site-packages\pip_vendor\pkg_resources_init
.py", line 3032, in _compute_dependencies
for req in self.parsed_pkg_info.get_all('Requires-Dist') or []:
File "C:\Users\CRAIG-PC\AppData\Local\pipkin\cache\workspaces\572d60ec1d3303b24c9425c8f5c5f661\lib\site-packages\pip_vendor\pkg_resources_init
.py", line 3014, in parsed_pkg_info
metadata = self.get_metadata(self.PKG_INFO)
File "C:\Users\CRAIG-PC\AppData\Local\pipkin\cache\workspaces\572d60ec1d3303b24c9425c8f5c5f661\lib\site-packages\pip_vendor\pkg_resources_init
.py", line 1424, in get_metadata
return value.decode('utf-8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 2134: invalid start byte in METADATA file at path: c:\users\craig-pc\appdata\local\pipkin\cache\workspaces\572d60ec1d3303b24c9425c8f5c5f661\lib\site-packages\adafruit_circuitpython_typing-1.9.5.dist-info\METADATA
Error Command '['C:\Users\CRAIG-PC\AppData\Local\pipkin\cache\workspaces\572d60ec1d3303b24c9425c8f5c5f661\Scripts\python.exe', '-I', '-m', 'pip', '--no-color', '--disable-pip-version-check', '--trusted-host', '127.0.0.1', 'install', '--no-compile', '--use-pep517', '--upgrade-strategy', 'only-if-needed', 'adafruit-circuitpython-tca9548a', '--index-url', 'http://127.0.0.1:36628']' returned non-zero exit status 2.

Rpi Connection Timed out

I am having issues with running the starter code. The HW connection is according to docs. Getting this error:

Traceback (most recent call last):
  File "/home/bhagatshree/code/scanner.py", line 16, in <module>
    if tca[channel].try_lock():
  File "/home/bhagatshree/.local/lib/python3.9/site-packages/adafruit_tca9548a.py", line 62, in try_lock
    self.tca.i2c.writeto(self.tca.address, self.channel_switch)
  File "/usr/local/lib/python3.9/dist-packages/busio.py", line 196, in writeto
    return self._i2c.writeto(address, buffer, stop=stop)
  File "/usr/local/lib/python3.9/dist-packages/adafruit_blinka/microcontroller/generic_linux/i2c.py", line 52, in writeto
    self._i2c_bus.write_bytes(address, buffer[start:end])
  File "/usr/local/lib/python3.9/dist-packages/Adafruit_PureIO/smbus.py", line 320, in write_bytes
    self._device.write(buf)
TimeoutError: [Errno 110] Connection timed out

Please advice.

Deadlock when connected i2c device fails.

I've connected some Adafruit SHT31-D Temperature & Humidity Sensors to the TCA9548A but once in a while one of the sensors fails to read properly with a remote I/O error. This is probably caused by the long wiring but in my application it's not a big deal as the program just tries again.

At least that was the case before I used the TCA9548A with just 2 sensors on the i2c of my Raspberry Pi. As the reading was done in a try: / except: the program continued to run. The remote I/O error didn't cause the i2c bus to hang so most of the time the next reading was succesful.

But when using the TCA9548A it's causing a deadlock on this error:

Traceback (most recent call last):
  File "/home/pi/MainProgram.py", line 332, in ReadTempValue
    TemperatureValue = '{0:4.1f}'.format(THsensor.temperature)
  File "/usr/local/lib/python3.5/dist-packages/adafruit_sht31d.py", line 120, in temperature
    raw_temperature, _ = self._data()
  File "/usr/local/lib/python3.5/dist-packages/adafruit_sht31d.py", line 109, in _data
    i2c.readinto(data)
  File "/usr/local/lib/python3.5/dist-packages/adafruit_bus_device/i2c_device.py", line 97, in readinto
    self.i2c.readfrom_into(self.device_address, buf, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/adafruit_tca9548a.py", line 76, in readfrom_into
    return self.tca.i2c.readfrom_into(address, buffer, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/busio.py", line 55, in readfrom_into
    return self._i2c.readfrom_into(address, buffer, stop=stop)
  File "/usr/local/lib/python3.5/dist-packages/adafruit_blinka/microcontroller/generic_linux/i2c.py", line 44, in readfrom_into
    readin = self._i2c_bus.read_bytes(address, end-start)
  File "/usr/local/lib/python3.5/dist-packages/Adafruit_PureIO/smbus.py", line 155, in read_bytes
    return self._device.read(number)
OSError: [Errno 121] Remote I/O error

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/pi/MainProgram.py", line 336, in ReadTempValue
    TemperatureValue = '{0:4.1f}'.format(THsensor.temperature)
  File "/usr/local/lib/python3.5/dist-packages/adafruit_sht31d.py", line 120, in temperature
    raw_temperature, _ = self._data()
  File "/usr/local/lib/python3.5/dist-packages/adafruit_sht31d.py", line 106, in _data
    self._command(SHT31_MEAS_HIGHREP)
  File "/usr/local/lib/python3.5/dist-packages/adafruit_sht31d.py", line 100, in _command
    with self.i2c_device as i2c:
  File "/usr/local/lib/python3.5/dist-packages/adafruit_bus_device/i2c_device.py", line 175, in __enter__
    while not self.i2c.try_lock():
  File "/usr/local/lib/python3.5/dist-packages/adafruit_tca9548a.py", line 65, in try_lock
    self.tca.i2c.writeto(self.tca.address, self.channel_switch)
  File "/usr/local/lib/python3.5/dist-packages/busio.py", line 65, in writeto
    return self._i2c.writeto(address, buffer, stop=stop)
  File "/usr/local/lib/python3.5/dist-packages/adafruit_blinka/microcontroller/generic_linux/i2c.py", line 38, in writeto
    self._i2c_bus.write_bytes(address, buffer[start:end])
  File "/usr/local/lib/python3.5/dist-packages/Adafruit_PureIO/smbus.py", line 244, in write_bytes
    self._device.write(buf)
OSError: [Errno 121] Remote I/O error

When I run a debug I see it's waiting for a lock on the i2c bus:

(gdb) py-list
  54        """An object that must be locked to prevent collisions on a microcontroller resource."""
  55        _locked = False
  56
  57        def try_lock(self):
  58            """Attempt to grab the lock. Return True on success, False if the lock is already taken."""
 >59            if self._locked:
  60                return False
  61            self._locked = True
  62            return True
  63
  64        def unlock(self):
 

It seems the busio never releases the lock on the bus when running this setup and an error occures. But as it does without the TCA I assume there is some problem with the error handling in the TCA library.

Any ideas?

AttributeError: module 'adafruit_ssd1306' has no attribute 'SSD1306'

Trying to interface three 0.96" 128x64 OLEDs to a RPI3B. When running the program, I get the following error:

Traceback (most recent call last):
  File "/home/pi/Desktop/GPS Python Programs/Multiple Display/gpsoledmulti.py", line 48, in <module>
    tsl1 = adafruit_ssd1306.SSD1306(tca[0])
AttributeError: module 'adafruit_ssd1306' has no attribute 'SSD1306'
import serial
import board
from PIL import Image, ImageDraw, ImageFont
import adafruit_ssd1306
import adafruit_tca9548a

ser = serial.Serial("/dev/ttyS0", baudrate=9600, timeout=10)

i2c = board.I2C()  
tca = adafruit_tca9548a.TCA9548A(i2c)

tsl1 = adafruit_ssd1306.SSD1306(tca[0])
tsl2 = adafruit_ssd1306.SSD1306(tca[1])
tsl3 = adafruit_ssd1306.SSD1306(tca[2])

Updates examples

New example is desired to show the user how to add two or more sensors

possible conflict between main I2C and multiplexed I2C devices

I'm trying to have 17 of the AS7341 spectrometers working simultaneously, and their 0x39 address is not changeable. I have 16 working properly, with 8 on a TCA9548A at 0x70 and another 8 on a TCA9548A at 0x71. However, when I add a AS7341 directly to the main I2C line (and not on a multiplexer), then that's the only one that works properly, with the other 16 yielding values of a power of 2 (or a sum of two powers of 2).

With 16 sensors connected (on 2 multiplexers):
(104, 185, 226, 370, 1042, 1283, 1889, 884)
(100, 184, 240, 377, 997, 1368, 1874, 751)
(110, 182, 246, 373, 1049, 1422, 1871, 864)
(108, 191, 237, 353, 1050, 1307, 1842, 911)
(111, 182, 239, 357, 1017, 1265, 1725, 875)
(95, 195, 239, 374, 990, 1377, 1861, 673)
(103, 180, 234, 356, 1020, 1324, 1820, 932)
(87, 168, 235, 345, 986, 1312, 1776, 843)
(81, 154, 194, 375, 1000, 1327, 1441, 497)
(78, 143, 214, 378, 872, 1044, 1494, 501)
(102, 187, 237, 401, 923, 1139, 1678, 742)
(82, 170, 225, 437, 1046, 1465, 1314, 541)
(89, 198, 237, 421, 1014, 1173, 1829, 663)
(87, 203, 229, 426, 1018, 1315, 1888, 617)
(94, 185, 227, 336, 1083, 1243, 1700, 622)
(87, 131, 218, 357, 659, 1106, 1579, 828)
All values are correct and consistent.

With 17 connected (one on main I2C line):
(96, 153, 224, 256, 17, 1230, 1280, 628)
(100, 151, 224, 256, 800, 1094, 1282, 756)
(101, 149, 229, 257, 16, 1156, 1280, 596)
(100, 157, 228, 256, 16, 1024, 1280, 656)
(101, 149, 229, 256, 808, 1222, 1057, 612)
(85, 129, 228, 256, 784, 1094, 1313, 672)
(101, 146, 225, 256, 816, 1032, 1280, 672)
(84, 134, 225, 256, 784, 1029, 1024, 576)
(81, 155, 193, 384, 800, 1036, 1280, 208)
(69, 138, 196, 256, 784, 193, 1312, 224)
(96, 153, 224, 384, 784, 1089, 1024, 720)
(80, 132, 197, 384, 0, 1158, 1280, 528)
(80, 132, 224, 384, 824, 1094, 1281, 692)
(84, 132, 229, 384, 816, 1034, 1280, 624)
(96, 155, 229, 256, 0, 1220, 1056, 608)
(84, 130, 196, 256, 520, 1100, 1024, 564)
(117, 159, 229, 384, 824, 1229, 1313, 756)
Only this last 17th sensor yields correct values each time.

I found this closed issue that might refer to a problem that I don't know about. Is it possible to turn off an address on the main I2C? Or is there some other solution?

          You only use the mux address to change the output channel state. After that, it's I2C as usual. So there's a potential to have a conflict with multiple devices of same address on different muxes. The fix is to turn off all channels on muxes not being used: https://learn.adafruit.com/adafruit-tca9548a-1-to-8-i2c-multiplexer-breakout/wiring-and-test#multiple-multplexers-4-13 to "hide" the conflicting sensors.

Originally posted by @caternuson in #9 (comment)

TCA library deadlocks when i2c device fails

When the TCA is connected to the i2c device and the device throws an OSError then the TCA library has a chance to deadlock. I am unable to reproduce this error without the TCA library.

Traceback (most recent call last):
  File "RowTest1.py", line 32, in <module>
    res += "|O" if square.value == False else "|X"  # Reads value of sensor square over i2c
  File "/home/pi/SmartChessboard/env/lib/python3.7/site-packages/adafruit_mcp230xx/digital_inout.py", line 80, in value
    return _get_bit(self._mcp.gpio, self._pin)
  File "/home/pi/SmartChessboard/env/lib/python3.7/site-packages/adafruit_mcp230xx/mcp23017.py", line 63, in gpio
    return self._read_u16le(_MCP23017_GPIOA)
  File "/home/pi/SmartChessboard/env/lib/python3.7/site-packages/adafruit_mcp230xx/mcp230xx.py", line 36, in _read_u16le
    with self._device as i2c:
  File "/home/pi/SmartChessboard/env/lib/python3.7/site-packages/adafruit_bus_device/i2c_device.py", line 137, in __enter__
    while not self.i2c.try_lock():
  File "/home/pi/SmartChessboard/env/lib/python3.7/site-packages/adafruit_tca9548a.py", line 47, in try_lock
    while not self.tca.i2c.try_lock():
KeyboardInterrupt

The issue: #8 describes the exact same issue. This issue was resolved by the user by simply not using the TCA. Unfortunately this is not an option for me. Furthermore simply adding a sleep time before the next i2c request does not avoid the deadlock

Add ability to scan

Currently not implemented by this library. One could still scan via the main I2C bus, but there's not really a nice way to deal with changing the mux at the same time.

software reset

By passing dedicated GPIO Pin to TCA9548A object, we could define software reset function within this library.
Is this a valid feature..?

Thoughts & Comments..?

TypeError: i2c_bus must be of type I2C (with multiples SSD1306 display)

I'm trying to plug 8 SSD1306 display using a TCA9548A multiplexer (on a Adafruit NRF Sense board).
When I scan them, it correctly detects each displays

Unfortunately when I try to initialize the display, I get an TypeError as the tca channel object is not a I2C object.

import board
import adafruit_tca9548a
import displayio
import terminalio
import adafruit_displayio_ssd1306
from adafruit_display_text import label
# Create I2C bus as normal
displayio.release_displays()

i2c = board.I2C()  # uses board.SCL and board.SDA

# Create the TCA9548A object and give it the I2C bus
tca = adafruit_tca9548a.TCA9548A(i2c)
display_bus = displayio.I2CDisplay(tca[0], device_address=0x3C)
display = adafruit_displayio_ssd1306.SSD1306(display_bus, width=70, height=35)

text = "1"
text_area = label.Label(terminalio.FONT, text=text, scale=5, color=0xFFFF00, x=53, y=15)
display.show(text_area)
while True:
    pass
Traceback (most recent call last):
  File "code.py", line 14, in <module>
TypeError: i2c_bus must be of type I2C

Missing Type Annotations

There are missing type annotations for some functions in this library.

The typing module does not exist on CircuitPython devices so the import needs to be wrapped in try/except to catch the error for missing import. There is an example of how that is done here:

try:
    from typing import List, Tuple
except ImportError:
    pass

Once imported the typing annotations for the argument type(s), and return type(s) can be added to the function signature. Here is an example of a function that has had this done already:

def wrap_text_to_pixels(
    string: str, max_width: int, font=None, indent0: str = "", indent1: str = ""
) -> List[str]:

If you are new to Git or Github we have a guide about contributing to our projects here: https://learn.adafruit.com/contribute-to-circuitpython-with-git-and-github

There is also a guide that covers our CI utilities and how to run them locally to ensure they will pass in Github Actions here: https://learn.adafruit.com/creating-and-sharing-a-circuitpython-library/check-your-code In particular the pages: Sharing docs on ReadTheDocs and Check your code with pre-commit contain the tools to install and commands to run locally to run the checks.

If you are attempting to resolve this issue and need help, you can post a comment on this issue and tag both @FoamyGuy and @kattni or reach out to us on Discord: https://adafru.it/discord in the #circuitpython-dev channel.

The following locations are reported by mypy to be missing type annotations:

  • adafruit_tca9548a.py:45
  • adafruit_tca9548a.py:61
  • adafruit_tca9548a.py:67
  • adafruit_tca9548a.py:73
  • adafruit_tca9548a.py:90
  • adafruit_tca9548a.py:98

Allow manual muxing?

Should we provide some mechanism to manually set the TCA mux? For use cases where this library is being used in conjunction with I2C devices that do not have a CircuitPython driver.

Example:
https://forums.adafruit.com/viewtopic.php?f=60&t=177241

Maybe something like a new channel property?

tca.channel = 3

Could probably add a new class variable to track this also, to provide a read of current channel.

Add Mock Library to support development outside RPi

Hi, adding a mock package in this same library, would allow people to develop their code outside RPi

I am currently using the following way to mock adafruit_tca9548a outside RPi, and it works.

try:
    import RPi.GPIO as GPIO
    import adafruit_tca9548a
except:
    import Mock.GPIO as GPIO
    import adafruit_tca9548a.mock as adafruit_tca9548a

Thoughts..?

While accesing sensors on the RP2040 give results that are not as expected when not using the REPL

While accessing two sensors in this case:
BH1750
MMA8451

This is seeing mostly in the RP2040. Have tested with the SAMD51 and the nRF52840 without seeing this issue.

Error

>>> import test_two_sensors
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "test_two_sensors.py", line 12, in <module>
  File "/lib/adafruit_mma8451.py", line 120, in __init__
ValueError: No I2C device at address: 1d

test code

import time
import board
import adafruit_mma8451
import adafruit_tca9548a
import adafruit_bh1750

# import test_two_sensors

i2c = board.I2C()
tca = adafruit_tca9548a.TCA9548A(i2c)
sensor2 = adafruit_bh1750.BH1750(tca[4])
sensor = adafruit_mma8451.MMA8451(tca[1])


while True:
    x, y, z = sensor.acceleration
    print("Acceleration: x={0:0.3f}m/s^2 y={1:0.3f}m/s^2 z={2:0.3f}m/s^2".format(x, y, z))
    time.sleep(1)
    print("%.2f Lux" % sensor2.lux)
    time.sleep(1)

Other Information

  • The test is done using a file and not in writing the instructions in the REPL.
  • This behavior is seeing with other sensors as MPL3115A2. My tests are not conclusive if the BH1750 are in fault or is the RP2040, or the REPL.
  • Sometimes, while testing the first test will be ok, but then it will not work again, not even unplugging the RP2040 from the USB connection

PCA9546 not showing connected devices on ESP32S3 and ESP32S2

Feather: Adafruit Feather ESP32S3 4MB Flash 2MB PSRAM with ESP32S3
Board: PCA9546 4-Channel STEMMA QT Multiplexer
CircuitPython version: 8.0.0-beta.6 (Issues oalso on 7.3)
Example following: https://learn.adafruit.com/adafruit-pca9546-4-channel-stemma-qt-multiplexer/circuitpython-python

Description: Device has been setup following the example above. Also expereince the exact same issue on the ESP32-S2 Feather. I am unable to see any devices connected to the PCA9546 using the receommnded adafruit_tca9548a library. When running the exmaple code the output is as below and this is with or wihout devices connected to the PCA9546. Have swapped cables and also tried to different PCA9546 boards and get the same results. Any suggestions on how to correct this?

Channel 0:['0xb']
Channel 1:['0xb']
Channel 2:['0xb']
Channel 3:['0xb']

The code being run is per the example.

# SPDX-FileCopyrightText: 2021 Carter Nelson for Adafruit Industries
# SPDX-License-Identifier: MIT

# This example shows using TCA9548A to perform a simple scan for connected devices
import board
import adafruit_tca9548a

# Create I2C bus as normal
# i2c = board.I2C()  # uses board.SCL and board.SDA
i2c = board.STEMMA_I2C()  # For using the built-in STEMMA QT connector on a microcontroller

# Create the PCA9546A object and give it the I2C bus
mux = adafruit_tca9548a.PCA9546A(i2c)

for channel in range(4):
    if mux[channel].try_lock():
        print("Channel {}:".format(channel), end="")
        addresses = mux[channel].scan()
        print([hex(address) for address in addresses if address != 0x70])
        mux[channel].unlock()

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.