Using an i2c multiplexer with mcp9600s

I can successfully use 2 mcp9600 thermocouple amplifiers via the following code on a Raspberry Pi 4. By successful I mean not only am I able to get the code to run without error, but the thermocouple readouts are accurate and responsive to changes in temperature.

import mcp9600
import time
from datetime import datetime
import threading

# Function to read temperature from MCP9600
def read_temperature(sensor_name, m, filename):
    while True:
        temp = m.get_hot_junction_temperature()
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        with open(filename, "a") as file:
            file.write(f"{timestamp}, Sensor {sensor_name}: {temp:.4f} °C\n")
        print(f"{timestamp}, Sensor {sensor_name}: {temp:.4f} °C")
        time.sleep(30.0)

# Define MCP9600 instances for each thermocouple
background = mcp9600.MCP9600(i2c_addr=0x67)
plant = mcp9600.MCP9600(i2c_addr=0x66)

# Create threads for each MCP9600
thread1 = threading.Thread(target=read_temperature, args=("Background", background, "Background_temperature_log.txt"))
thread2 = threading.Thread(target=read_temperature, args=("Plant", plant, "plant_temperature_log.txt"))

# Start the threads
thread1.start()
thread2.start()

# Join the threads to main thread
thread1.join()
thread2.join()

I would like to use 3 or more mcp9600’s so I got an Adafruit TCA9548A 1-to-8 I2C Multiplexer Breakout. The example code given for running multiple sensors via the i2c multiplexer suggests that the formatting of the code should be similar for any i2c device, however it uses circuitpython, so I perhaps that is why I am unable to route my individual mcp9600’s via the multiplexer.

Here is what I’m trying:

import time
import board
import mcp9600
import adafruit_tca9548a

# Create I2C bus as normal
i2c = board.I2C()  # uses board.SCL and 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
t1 = mcp9600.MCP9600(tca[0])
t2 = mcp9600.MCP9600(tca[1])

but I get the following error:
Traceback (most recent call last):
  File "/home/thermologger/.venv/lib/python3.11/site-packages/tca9548a_multisensor.py", line 14, in <module>
    t1 = mcp9600.MCP9600(tca[1])
         ^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/thermologger/.venv/lib/python3.11/site-packages/mcp9600/__init__.py", line 191, in __init__
    self._mcp9600.select_address(self._i2c_addr)
  File "/home/thermologger/.venv/lib/python3.11/site-packages/i2cdevice/__init__.py", line 198, in select_address
    raise ValueError("Address {:02x} invalid!".format(address))
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: unsupported format string passed to TCA9548A_Channel.__format__

If I specifically import adafruit_mcp9600 and then assign the thermocouple like this:

t1 = adafruit_mcp9600.MCP9600(tca[0])

I don’t get an error but then the apparent readings from the thermocouples are all identical and not responsive to changes in temperature.

I should also note than when I run the following:

sudo i2cdetect -y 1

I can see i2c devices at 0x66 and 0x67 (the mcp9600’s), and 0x70 (the multiplexer).

If you run CircuitPython code on a Pi4, you also have to install Blinka. This is an abstraction-layer that emulates the MCU on the Pi4. I am using this on a regular basis, it works just fine.

Sorry, should have clarified - Blinka is already installed.

Your venv: is this a pure CircuitPython venv? I.E. did you also load the CircuitPython version of the MCP9600 driver, the I2C-stuff and so on? Your import for the mcp9600 makes me wonder…