I2C multiplexer TCA9548A problem with ESPHome 2021.10.1

I have been running a Wemos D1 Mini Pro with a TCA9548A I2C Multiplexer and some BH1750 sensors successfully for weeks, but while updating ESPHome from version 2021.9.3 to version 2021.10.1 I was getting some errors about options that have been removed.

This is an excerpt from the install log:

INFO Reading configuration /config/esphome/d1pv2-01.yaml…
INFO Detected timezone ‘Europe/Amsterdam’
Failed config

tca9548a: [source /config/esphome/d1pv2-01.yaml:45]

  • [source /config/esphome/d1pv2-01.yaml:45]
    address: 112
    id: multiplex0

    This option has been removed.
    scan: True [source /config/esphome/d1pv2-01.yaml:47]
    sensor.bh1750: [source /config/esphome/d1pv2-01.yaml:71]
    platform: bh1750
    name: D1PV2-01 BH1750 Illuminance 1
    id: d1pv2_01_bh1750_1

This option has been removed, please see the tca9584a docs for the updated way to use multiplexers.
multiplexer: [source /config/esphome/d1pv2-01.yaml:75]
id: multiplex0
channel: 6
resolution: 0.5
measurement_duration: 69
update_interval: 30s
accuracy_decimals: 2

This is the applicable part from the ESPHome config.yaml:

# I2C setup
i2c:
  sda: 4
  scl: 5
  scan: false

# I2C Multiplexer setup
tca9548a:
  - address: 0x70
    id: multiplex0
    scan: true

# LUX sensors setup
sensor:
  - platform: bh1750
    name: "D1PV2-01 BH1750 Illuminance 1"
    id: d1pv2_01_bh1750_1
    multiplexer:
      id: multiplex0
      channel: 6
    resolution: 0.5
    measurement_duration: 69
    update_interval: 30s
    accuracy_decimals: 2

The strange thing is that I cannot find any info in the current ESPHome release notes about changes to the TCA9548A, and also the TCA9548A documentation is still exactly the same as one month ago.
Does anybody have a clue what is going wrong here?

This problem is still not solved.
Whatever are try, it currently is impossible to upgrade this ESP8266 setup to ESPHome version 2021.10.1
Was anyone with a comparable set-up (ESP8266 with an I2C multiplexer) able to upgrade?

I have exactly the same combination here (8266 + tca9548a) and I witness the exact same problem: Compile errors “This option has been removed.” since ESPHome 21.10.
Didn’t have time to try which option exactly throws the error. Maybe on the weekend.

Thanks Jörg!
Although it is an unfortunate problem it is good to know that I am not the only one.
There must have been something broken in this new release.
The compile errors mention these options as being removed for my set-up:

In the tca9548a setup:
scan: true
In the sensor setup:
multiplexer:

But I have no idea at the moment how to work around that.

OK, so I think that I found the location of these “option has been removed” warnings in the ESPHome Source Code. These come from two “init.py” files:

esphome/esphome/components/i2c/__init__.py

def i2c_device_schema(default_address):
    """Create a schema for a i2c device.
    :param default_address: The default address of the i2c device, can be None to represent
      a required option.
    :return: The i2c device schema, `extend` this in your config schema.
    """
    schema = {
        cv.GenerateID(CONF_I2C_ID): cv.use_id(I2CBus),
        cv.Optional("multiplexer"): cv.invalid(
            "This option has been removed, please see "
            "the tca9584a docs for the updated way to use multiplexers"
        ),
    }
    if default_address is None:
        schema[cv.Required(CONF_ADDRESS)] = cv.i2c_address
    else:
        schema[cv.Optional(CONF_ADDRESS, default=default_address)] = cv.i2c_address
    return cv.Schema(schema)

esphome/esphome/components/tca9548a/__init__.py

CONF_BUS_ID = "bus_id"
CONFIG_SCHEMA = (
    cv.Schema(
        {
            cv.GenerateID(): cv.declare_id(TCA9548AComponent),
            cv.Optional(CONF_SCAN): cv.invalid("This option has been removed"),
            cv.Optional(CONF_CHANNELS, default=[]): cv.ensure_list(
                {
                    cv.Required(CONF_BUS_ID): cv.declare_id(TCA9548AChannel),
                    cv.Required(CONF_CHANNEL): cv.int_range(min=0, max=7),
                }
            ),
        }
    )
    .extend(i2c.i2c_device_schema(0x70))
    .extend(cv.COMPONENT_SCHEMA)
)

But how to solve this?
Probably the docs still have to be updated?

The new config syntax is shown in this issue report. I have copied the example YAML below.
It uses dedicated bus_ids for each channel of the multiplexer, and the sensors now have to reference the new bus_ids instead of a multiplexer id and channel.

But wait!
You should not recompile your ESPHome YAMLs just now!
There is still an issue in ESPHome 21.10.1 that will prevent the new multiplexer code from working correctly. See this PR which will be rolled out with ESPHome 2021.10.2.

New syntax for I2C multiplexers

i2c:
  sda: 21
  scl: 22
  scan: True
  id: i2c0

tca9548a:
  - address: 0x77
    id: multiplex0
    i2c_id: i2c0
    channels: 
      - bus_id: multiplex0channel0
        channel: 0
      - bus_id: multiplex0channel1
        channel: 1
      - bus_id: multiplex0channel2
        channel: 2
      - bus_id: multiplex0channel3
        channel: 3
      
#    scan: true

ads1115:
  - address: 0x48
    i2c_id: multiplex0channel3

1 Like

ESPHome 2021.10.2 has already been released. The update should appear in HA very soon and with it the new multiplexer syntax should become usable.

1 Like

Thanks Jörg! All clear now. :+1:

After the upgrade to 2021.10.2 I will modify my Yaml code accordingly and recompile.

Yes!
After updating ESPHome to 2021.10.2 and modifying the ESP8266 Yaml in accordance with the now also updated docs for the TCA9548A compiling went fine, and every is working again.

Just for completeness (the example from the ESPHome Issue report #2598 appears to be incorrect): the updated TCA9548A doc now specifies this for the multiplexer setup:

# Example configuration entry
tca9548a:
  - address: 0x70
    id: multiplex0
    i2c_id: i2c0
    channels:
      - bus_id: multiplex0channel0
        channel: 0
      - bus_id: multiplex0channel1
        channel: 1

# Individual I2C Devices
sensor:
  - platform: bmp280
    i2c_id: multiplex0channel1
1 Like

Hi,
I’m new esphome user and unfortunately facing the issue with trying to compile using above multiplexer setup :(.
First of all can’t even save code with ‘i2c_id: i2c0’
Do you have any idea why ?
I use esphome 2021.10.2

Hi Rafał,
Can you give some more background info? In which interface are you trying to save the code, and can you show your code and any error messages that you get?

Hi Rafał,
if your i2c_id: line does not compile, this is probably because you forgot the i2c: definition for the bus in your YAML. This may happen because the example code in the tca9548a page is incomplete (= reduced to the essential parts). Here is a full example. But you still have to add your usual intro segments like esphome:, wifi:, logger:, api: and ota:.

i2c:
  - id: bus_a
    #scl: D1
    #sda: D2
    #scan: false
    frequency: 50kHz

tca9548a:
  - id: multiplex0
    i2c_id: bus_a
    #address: 0x70
    channels:
      - bus_id: multiplex0channel0
        channel: 0
      - bus_id: multiplex0channel1
        channel: 1
      - bus_id: multiplex0channel2
        channel: 2

sensor:
  - platform: sht3xd
    address: 0x45
    i2c_id: multiplex0channel0
    temperature:
      name: "KWL Zuluft, Temperatur"
      id: sht_1_temperature
      state_class: measurement
    humidity:
      name: "KWL Zuluft, Luftfeuchte"
      id: sht_1_humidity
      state_class: measurement
  - platform: sht3xd
    address: 0x45
    i2c_id: multiplex0channel1
    temperature:
      name: "KWL Abluft, Temperatur"
      id: sht_2_temperature
    humidity:
      name: "KWL Abluft, Luftfeuchte"
      id: sht_2_humidity
  - platform: sht3xd
    address: 0x45
    i2c_id: multiplex0channel2
    temperature:
      name: "KWL Außenluft, Temperatur"
      id: sht_3_temperature
    humidity:
      name: "KWL Außenluft, Luftfeuchte"
      id: sht_3_humidity

Hi Jörg,
You’re the Men. Looking at yours example I’ve notice that in i2c dafinition you give id to i2c bus - that’s somthing I did miss. I was confused by the configuration description - * i2c_id** (Optional): The I²C Bus ID Defaults to false, - insted of → should refer to i2c bus configuration id :(,
Thanks for your accurate hint,
Now the code is compiling, In the evening I’ll check if it works :),

1 Like

I’m still puzzling about something related to the I2C Multiplexer usage.
In the TCA9548A docs it currently is not specified that one can and/or should specify the I2C “address” for sensors, like you do in your example:

sensor:
  - platform: sht3xd
    address: 0x45
    i2c_id: multiplex0channel0

I did not specify these addresses in my current config, and I also did set the “scan:” option for the I2C bus as “false”:

# I2C setup
i2c:
  sda: 4
  scl: 5
  scan: false
  id: i2c0

# I2C Multiplexer setup
tca9548a:
  - address: 0x70
    id: mpx0
    i2c_id: i2c0
    channels:
     - bus_id: mpx0ch2
       channel: 2
     - bus_id: mpx0ch3
       channel: 3
     - bus_id: mpx0ch4
       channel: 4
     - bus_id: mpx0ch5
       channel: 5
     - bus_id: mpx0ch6
       channel: 6

# LUX sensors setup
sensor:
  - platform: bh1750
    name: "D1PV2-01 BH1750 Illuminance 1"
    id: d1pv2_01_bh1750_1
    i2c_id: mpx0ch6
    resolution: 0.5
    measurement_duration: 69
    update_interval: 30s
    accuracy_decimals: 2

But everything is working as expected, and in the ESPHome compilation and install log the correct I2C address is shown (0x23 for the BH1750).

[23:36:39][C][bh1750.sensor:027]: BH1750 ‘D1PV2-01 BH1750 Illuminance 1’
[23:36:39][C][bh1750.sensor:027]: Device Class: ‘illuminance’
[23:36:39][C][bh1750.sensor:027]: State Class: ‘measurement’
[23:36:39][C][bh1750.sensor:027]: Unit of Measurement: ‘lx’
[23:36:39][C][bh1750.sensor:027]: Accuracy Decimals: 2
[23:36:39][C][bh1750.sensor:028]: Address: 0x23
[23:36:39][C][bh1750.sensor:048]: Resolution: 0.5
[23:36:39][C][bh1750.sensor:049]: Update Interval: 30.0s

So how can this be functioning without telling ESPHome which addresses to use?
There must still be some I2C scanning happening in the background?

If you omit the address the sensor component will use a default value. For your BH1750 this is 0x23.
Have a look into the docs of BH1750:

  • address (Optional, int): Manually specify the I²C address of the sensor. Defaults to 0x23 (address if address pin is pulled low). If the address pin is pulled high, the address is 0x5C.

In my case I needed an address that deviated from the default of my SHT3X-D component (0x45 instead of 0x44). So I had to use the address property.


The scan: option really only changes the log output (and costs a bit of boot time).
It is not necessary for normal operation. But it shows, which I2C clients are found on the bus and displays them in the log. This is very helpful when the ESP does not connect to your I2C clients and you are analyzing the problem.
If you set scan: to true (or omit it, which defaults to true), you will find something like this in your log:

image

This does not mean that the ESP will use these addresses. It is a simple scan that shows you the clients that are available on the bus. You still have to connect them using the address property of a corresponding sensor in your YAML (or the default address of a sensor, as explained above).

2 Likes

Thanks again Jörg :+1:

I missed that default value, but it is completely clear now.

And this is also good to know, because I assumed that the scan outcome would be used by ESPHome for the sensor set-up.

1 Like

@Jpsy Hi know its 2 years later no but Im struggeling since 3 days with my DHT20 sensors (basically aht10; I2C communication) connected via a TCA9548A to an ESP32 in ESPHome.

I tried the example config of the ESP Home Website aswell as your givin YAML Code, I always get the notification in the log that the communication with the aht10 failed.

captive_portal:



i2c:
  id: bus_a
  sda: 21
  scl: 22
  scan: True
  frequency: 50kHz
  

tca9548a:
- id: multiplex0
  i2c_id: bus_a
  address: 0x70
  channels:
    - bus_id: multiplex0channel0
      channel: 0

sensor:
  - platform: aht10 
    address: 0x38
    i2c_id: multiplex0channel0
    temperature:
      name: "2.dht20 Temperature"
      id: aht_2_temperature
    humidity:
      name: "2.dht20 Humidity"
      id: aht_2_humidity     
    update_interval: 2s

And the log says me the following:

[22:35:24][I][i2c.arduino:069]: Results from i2c bus scan:
[22:35:24][I][i2c.arduino:075]: Found i2c device at address 0x38
[22:35:24][C][tca9548a:033]: TCA9548A:
[22:35:24][C][tca9548a:034]:   Address: 0x70
[22:35:24][C][aht10:136]: AHT10:
[22:35:24][C][aht10:137]:   Address: 0x38
[22:35:24][E][aht10:139]: Communication with AHT10 failed!
[22:35:24][C][aht10:141]:   Temperature '2.dht20 Temperature'
[22:35:24][C][aht10:141]:     Device Class: 'temperature'
[22:35:24][C][aht10:141]:     State Class: 'measurement'
[22:35:24][C][aht10:141]:     Unit of Measurement: '°C'
[22:35:24][C][aht10:141]:     Accuracy Decimals: 2
[22:35:24][C][aht10:142]:   Humidity '2.dht20 Humidity'
[22:35:24][C][aht10:142]:     Device Class: 'humidity'
[22:35:24][C][aht10:142]:     State Class: 'measurement'
[22:35:24][C][aht10:142]:     Unit of Measurement: '%'
[22:35:24][C][aht10:142]:     Accuracy Decimals: 2
[22:35:24][C][captive_portal:088]: Captive Portal:
[22:35:24][C][mdns:112]: mDNS:
[22:35:24][C][mdns:113]:   Hostname: esphometest
[22:35:24][C][ota:093]: Over-The-Air Updates:
[22:35:24][C][ota:094]:   Address: esphometest.local:3232
[22:35:24][C][ota:097]:   Using Password.
[22:35:24][C][api:138]: API Server:
[22:35:24][C][api:139]:   Address: esphometest.local:6053
[22:35:24][C][api:141]:   Using noise encryption: YES


The weird thing for me is that it finds the DHT20/AHT10 (Address 0x38) but not the Multiplexer (Address: 0x70)

Do you or anybody else know whats wrong?

In the picture below you can see my wiring:

Hi @miiiIta and welcome to this forum!

The first thing I noticed here is that you are missing all pull-up resistors on the I2C busses on both sides of the TCA9548A. This can very well ruin your I2C communication and make it unstable. Missing pull-ups are an issue that is found so often on I2C circuit diagrams on the web that I always wonder how all these circuits could ever have worked.

You have to add the following pull-ups
3.3V –[ ]– SCL
3.3V –[ ]– SDA
3.3V –[ ]– SC0
3.3V –[ ]– SD0
(And also to the other SCn / SDn if they are in use.)

The resistance of the pull-ups is rather uncritical. 4.7 kΩ should be fine in most cases.

I also recommend to clamp A0 / A1 / A2 to GND and !RST to 3.3V.

Check the datasheet of TCA9548A. There is a circuit diagram of a typical application on page 18:

Hi @Jpsy Thanks for answering, I tried out the wiring as recommended (see in the pictures) but actually with the resistors (5,1K) the log tells me no I2C devices found. Without the resistors same as before: I2C devices found (0x38) but later communication with AHT10 failed

Im almost giving up and buy DHT11 which only neet any gpio :smiley:

Looks all good to me.
What is your I2C frequency? Start low (50kHz) and only increase it if it works flawlessly.
Do you have the parts at hand to build a second circuit without reusing any parts from the existing unit? This is what I usually do when I try to spot defective hardware. When the second one works I swap parts until it fails.