0
\$\begingroup\$

Currently I'm working on a project where I want to use multiple scales in a fridge. When something will be taking out of the fridge the scale detects the different weight and send an event to my server. At this moment I can't figure out why it's not working...

I'm using a Raspberry Pi 4 Modal B with a pHat attached to the GPIO pins. Then the I2C signal goes to the first TCA9548A to use the bus with 8 different channels. After the first TCA9548A I have connected 3 more TCA9548A (with different addresses) for using multiple NAU7802 in my project. See image below.

(I need the 8 channels multiplexer because the I2C address of the NAU7802 is 0x2A and is hardware defined. A multiplexer/Mux is required to communicate to multiple NAU7802 sensors on a single bus.)

The problem that I'm facing is that the TCA9548A is working for the first two multiplexer. When the signal will go through the third multiplexer it can only find 1 NAU7802 sensor. (I have 3 connected to that mux). And the fourth multiplexer can only find 2 NAU7802 sensors. (I have 4 connected to that mux).

Now the strange thing is that when I connect only the first 3 multiplexers everything is working correctly. Why is the fourth multiplexer giving me this problem?

Products that I use:

  • SparkFun Qwiic pHAT v2.0 for Raspberry Pi
  • SparkFun Qwiic Mux Breakout - 8 Channel (TCA9548A)
  • SparkFun Qwiic Scale - NAU7802

Code (Python):

import qwiic_tca9548a
import PyNAU7802
import smbus2
import time
import json
import requests


def enable_port(mux: qwiic_tca9548a.QwiicTCA9548A, port):
    mux.enable_channels(port)


def disable_port(mux: qwiic_tca9548a.QwiicTCA9548A, port):
    mux.disable_channels(port)


def initialize_mux(address):
    mux = qwiic_tca9548a.QwiicTCA9548A(address=address)
    return mux


def create_instance():
    mux = []
    addresses = [*range(0x70, 0x77 + 1)]

    for address in addresses:
        instance = initialize_mux(address)

        if not instance.is_connected():
            continue

        print("Connected to mux {0} \n".format(address))

        instance.disable_all()

        mux.append({
            "instance": instance,
            "scales": [],
        })

    return mux


def create_bus():
    bus = smbus2.SMBus(1)
    return bus


def initialize_scales(mux):
    scales = []
    bus = create_bus()
    ports = [0, 1, 2, 3, 4, 5, 6, 7]

    for port in ports:
        enable_port(mux, port)
        nau = PyNAU7802.NAU7802()

        if not nau.begin(bus):
            # print(f"NOT CONNECTED TO SCALE: {port} \n")
            disable_port(mux, port)
            continue

        print(f"Connected to port: {port} with mux: {mux.address} \n")

        scales.append({
            "port": port,
            "nau": nau
        })

        disable_port(mux, port)

    print(f"scales initialised: {scales} with mux: {mux.address} \n")

    return scales


def get_calibration_data_file_name(mux):
    return "tare_mux_" + str(mux["instance"].address) + ".json"


def main():
    mux = create_instance()

    for i, val in enumerate(mux):
        mux[i]["scales"] = initialize_scales(mux[i]["instance"])


if __name__ == "__main__":
    main()

Terminal:

pi@raspberrypi:~ $ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: 70 71 72 73 -- -- -- --                         
pi@raspberrypi:~ $ python3 test_connecting_scales.py 
Connected to mux 112 

Connected to mux 113 

Connected to mux 114 

Connected to mux 115 

Connected to port: 0 with mux: 112 

Connected to port: 3 with mux: 112 

Connected to port: 4 with mux: 112 

Connected to port: 7 with mux: 112 

scales initialised: [{'port': 0, 'nau': <PyNAU7802.NAU7802.NAU7802 object at 0xb59a11d0>}, {'port': 3, 'nau': <PyNAU7802.NAU7802.NAU7802 object at 0xb59a1210>}, {'port': 4, 'nau': <PyNAU7802.NAU7802.NAU7802 object at 0xb59a1930>}, {'port': 7, 'nau': <PyNAU7802.NAU7802.NAU7802 object at 0xb59a1630>}] with mux: 112 

Connected to port: 0 with mux: 113 

Connected to port: 3 with mux: 113 

Connected to port: 4 with mux: 113 

Connected to port: 7 with mux: 113 

scales initialised: [{'port': 0, 'nau': <PyNAU7802.NAU7802.NAU7802 object at 0xb59a1b30>}, {'port': 3, 'nau': <PyNAU7802.NAU7802.NAU7802 object at 0xb59a1b50>}, {'port': 4, 'nau': <PyNAU7802.NAU7802.NAU7802 object at 0xb59a1a90>}, {'port': 7, 'nau': <PyNAU7802.NAU7802.NAU7802 object at 0xb59a1a70>}] with mux: 113 

Connected to port: 4 with mux: 114 

scales initialised: [{'port': 4, 'nau': <PyNAU7802.NAU7802.NAU7802 object at 0xb5a30ad0>}] with mux: 114 

Connected to port: 0 with mux: 115 

Connected to port: 3 with mux: 115 

scales initialised: [{'port': 0, 'nau': <PyNAU7802.NAU7802.NAU7802 object at 0xb5a309f0>}, {'port': 3, 'nau': <PyNAU7802.NAU7802.NAU7802 object at 0xb5a30a50>}] with mux: 115 

Connection: enter image description here

\$\endgroup\$
1
  • 2
    \$\begingroup\$ get yourself an oscilloscope and look at the signals on the I2C bus. Perhaps your pullup resistors are not sized correctly for the bus capacitance and the waveforms are distorted. \$\endgroup\$
    – vicatcu
    Sep 6 at 16:40
3
\$\begingroup\$

You have added an absurdly large amount of pull-up resistors to the I2C bus.

The Raspberry Pi or the chips you are talking to can't communicate with such strong total value of pull-ups.

The Raspberry Pi itself supposedly has 1.8k pull-ups. The interface hat has 2.2k pull-ups. Each of the TCA9548 modules have 4.7k pull-ups on the main port, and there's four of them.

Each mux port of the TCA9548 module also has a 4.7k pull-up which gets connected to the bus when the port is selected.

And finally, the NAU7802 module has 2.2k pull-ups on board.

So when a single mux port is enabled, all the above adds up to 395 ohms of total pull-up, adding up to 8.3mA of current. Luckily you only select one mux port at any given time.

That exceeds the amount of acceptable pull-up current, as many chips with standard I2C specs can reliably drive up to 3mA.

\$\endgroup\$
3
  • \$\begingroup\$ Thank you for your interesting answer. I honestly never looked into pull-up resistors before. According to SparkFun's website (learn.sparkfun.com/tutorials/i2c) it says: Most I2C devices offered in the SparkFun catalog usually include pull-up resistors for the SCL and SDA pins. If you have many I2C devices on the same bus, you may need to adjust the equivalent value for the pull-up resistors by disconnecting the pull-up resistors on a few of the devices. So I need to cut some jumper pads on the devices. What device(s) would you recommend to cut the I2C pull-up resistor? \$\endgroup\$
    – SDW
    Sep 6 at 22:36
  • \$\begingroup\$ @SDW You only need a single set of pull-ups per bus segment. Maybe remove ones you can easily modify. Like the all four mux boards can be made identical by cutting the pull-up pads, and/or the NAU7802 boards. Maybe the hat too, if the Pi has onboard pull-ups. \$\endgroup\$
    – Justme
    Sep 6 at 22:59
  • \$\begingroup\$ Everything is working correctly. Thank you so much for your time and replies! \$\endgroup\$
    – SDW
    Sep 8 at 12:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.