ADS1115 Module 4C, 4D addressing fail in ESP Home

I don’t see any answers listed, but had a problem using multiple ADS1115 modules on an I2C bus. Address Hex 48 and 49 were no problem, but when I took the addr pin to SDA or SCL there was no reading, just bus error reports.

I did a lot of looking on the internet for the problem and even used a scope to see the bus activity simply cease when I attempted a 4D or 4C probe.

Anyway should anyone be head scratching over this, I noticed that there was a pull down 10K resistor on the ADDR pin of the ADS1115. This seems to serve no useful purpose other than to oppose the pull up 10k’s that connect to the SDA and SCL lines.

Removal of the 10K pulldown sorted the problem, but obviously the ADDR pin needs to be actually wired to ground when using 0x48.

The pulldown and ten k tpullup resistors are common to most modules and enabling the internal pullups in my ESP32’s had no effect on the address fail.

Anyway, if anyone is wondering why any more than two ADS1115’s causes problems, it takes seconds with an iron to solve.

I currently have no issue with my CT clamp setup where I use 4 ADS1115 modules. No modifications to the modules required. These where the modules I used.

Relevant part of the esphome file.

i2c:
  sda: ${power_in_sda}
  scl: ${power_in_scl}
  id: power_in

ads1115:
  - address: 0x48 # GND
    id: ads_power_in
    continuous_mode: on
  - address: 0x49 # VCC
    id: ads_2
    continuous_mode: on
  - address: 0x4a # SDA
    id: ads_3
    continuous_mode: on
  - address: 0x4b # SCL
    id: ads_4
    continuous_mode: on

sensor:
  # Default Ground 0x48
  - id: ads_power_in_A0
    platform: ads1115
    multiplexer: 'A0_GND'
    gain: 1.024    
    ads1115_id: ads_power_in
    internal: true
  - id: ctclamp_100a_black
    platform: ct_clamp
    sensor: ads_power_in_A0
    name: "Current 100A Black"
    update_interval: 10s
    filters:
      - calibrate_linear:
          - 0.000 -> 0
          - 1.000 -> 100.0
      - clamp:
          min_value: 0
          max_value: 100.0
  - id: ads_power_in_A1
    platform: ads1115
    multiplexer: 'A1_GND'
    gain: 1.024
    ads1115_id: ads_power_in
    internal: true
  - id: ctclamp_100a_red
    platform: ct_clamp
    sensor: ads_power_in_A1
    name: "Current 100A Red"
    update_interval: 10s
    filters:
      - calibrate_linear:
          - 0.000 -> 0
          - 1.000 -> 100.0
      - clamp:
          min_value: 0
          max_value: 100.0    
  - id: ads_1_A2
    platform: ads1115
    multiplexer: 'A2_GND'
    gain: 1.024
    ads1115_id: ads_power_in
    internal: true
  - id: ctclamp_30a_fridge
    platform: ct_clamp
    sensor: ads_1_A2
    name: "Current Fridge"
    update_interval: 10s
    filters:
      - calibrate_linear:
          - 0.000 -> 0
          - 1.000 -> 15.0
      - clamp:
          min_value: 0
          max_value: 15.0
  - id: ads_1_A3
    platform: ads1115
    multiplexer: 'A3_GND'
    gain: 1.024
    ads1115_id: ads_power_in
    internal: true
  - id: ctclamp_15A_pool
    platform: ct_clamp
    sensor: ads_1_A3
    name: "Current Pool"
    update_interval: 10s
    filters:
      - calibrate_linear:
          - 0.001 -> 0.0
          - 1.000 -> 15.0
      - clamp:
          min_value: 0
          max_value: 15.0
  # Realtime Power
  - id: power_100a
    platform: template
    name: "RT Power 100A"            
    lambda: |-
      return ((id(ctclamp_100a_black).state * 114) + (id(ctclamp_100a_red).state * 114));
    update_interval: 10s
    device_class: power
    unit_of_measurement: W
    state_class: measurement  
  - id: power_30a_fridge
    platform: template
    name: "RT Power Fridge"
    lambda: |-
      return id(ctclamp_30a_fridge).state * 114;
    update_interval: 10s
    device_class: power
    unit_of_measurement: W
    state_class: measurement
  - id: power_15a_pool
    platform: template
    name: "RT Power Pool"
    lambda: |-
      return id(ctclamp_15A_pool).state * 114;
    update_interval: 10s
    device_class: power
    unit_of_measurement: W
    state_class: measurement
  # Daily Total Power
  - name: "Daily Power 100A"
    platform: total_daily_energy   
    unit_of_measurement: kWh
    power_id: power_100a
    accuracy_decimals: 2
    filters:
      - multiply: 0.001
    device_class: energy
  - name: "Daily Power Fridge"
    platform: total_daily_energy   
    unit_of_measurement: kWh
    power_id: power_30a_fridge
    accuracy_decimals: 2
    filters:
      - multiply: 0.001
    device_class: energy
  - name: "Daily Power Pool"
    platform: total_daily_energy   
    unit_of_measurement: kWh
    power_id: power_15a_pool
    accuracy_decimals: 2
    filters:
      - multiply: 0.001
    device_class: energy

  # VCC 0x49
  - id: ads_2_A0
    platform: ads1115
    multiplexer: 'A0_GND'
    gain: 1.024
    ads1115_id: ads_2
    internal: true
  - id: ctclamp_cold_storage
    platform: ct_clamp
    sensor: ads_2_A0
    name: "Current Basement Cold storage"
    update_interval: 10s
    filters:
      - calibrate_linear:
          - 0.000 -> 0
          - 1.000 -> 15.0
      - clamp:
          min_value: 0
          max_value: 15.0
  - id: ads_2_A1
    platform: ads1115
    multiplexer: 'A1_GND'
    gain: 1.024
    ads1115_id: ads_2
    internal: true
  - id: ctclamp_dishwasher
    platform: ct_clamp
    sensor: ads_2_A1
    name: "Current Dish Washer"
    update_interval: 10s
    filters:
      - calibrate_linear:
          - 0.001 -> 0
          - 1.000 -> 15.0
      - clamp:
          min_value: 0
          max_value: 15.0
  - id: ads_2_A2
    platform: ads1115
    multiplexer: 'A2_GND'
    gain: 1.024
    ads1115_id: ads_2
    internal: true
  - id: ctclamp_kitchen_island
    platform: ct_clamp
    sensor: ads_2_A2
    name: "Current Kitchen Island"
    update_interval: 10s
    filters:
      - calibrate_linear:
          - 0.001 -> 0
          - 1.000 -> 20.0
      - clamp:
          min_value: 0
          max_value: 20.0 
  - id: ads_2_A3
    platform: ads1115
    multiplexer: 'A3_GND'
    gain: 1.024
    ads1115_id: ads_2
    internal: true
  - id: ctclamp_water_heater
    platform: ct_clamp
    sensor: ads_2_A3
    name: "Current Water Heater"
    update_interval: 10s
    filters:
      - calibrate_linear:
          - 0.000 -> 0
          - 1.000 -> 15.0
      - clamp:
          min_value: 0
          max_value: 15.0
  # Realtime Power
  - id: power_bsmt_cold_storager
    platform: template
    name: "RT Power Basement Cold Storage"
    lambda: |-
      return id(ctclamp_cold_storage).state * 114;
    update_interval: 10s
    device_class: power
    unit_of_measurement: W
    state_class: measurement
  - id: power_dishwasher
    platform: template
    name: "RT Power Dishwasher"
    lambda: |-
      return id(ctclamp_dishwasher).state * 114;
    update_interval: 10s
    device_class: power
    unit_of_measurement: W
    state_class: measurement
  - id: power_kitchen_island
    platform: template
    name: "RT Power Kitchen Plugs"
    lambda: |-
      return id(ctclamp_kitchen_island).state * 114;
    update_interval: 10s
    device_class: power
    unit_of_measurement: W
    state_class: measurement
  - id: power_water_heater
    platform: template
    name: "RT Power Water Heater"
    lambda: |-
      return id(ctclamp_water_heater).state * 114;
    update_interval: 10s
    device_class: power
    unit_of_measurement: W
    state_class: measurement
  # Daily Power
  - name: "Daily Power Basement Cold Storage"
    platform: total_daily_energy      
    unit_of_measurement: kWh
    power_id: power_bsmt_cold_storager
    accuracy_decimals: 2
    filters:
      - multiply: 0.001
    device_class: energy
  - name: "Daily Power Dishwasher"
    platform: total_daily_energy      
    unit_of_measurement: kWh
    power_id: power_dishwasher
    accuracy_decimals: 2
    filters:
      - multiply: 0.001
    device_class: energy
  - name: "Daily Power Kitchen Island Plugs"
    platform: total_daily_energy      
    unit_of_measurement: kWh
    power_id: power_kitchen_island
    accuracy_decimals: 2
    filters:
      - multiply: 0.001
    device_class: energy
  - name: "Daily Power Water Heater"
    platform: total_daily_energy      
    unit_of_measurement: kWh
    power_id: power_water_heater
    accuracy_decimals: 2
    filters:
      - multiply: 0.001
    device_class: energy

  # SDA 0x4a
  - id: ads_3_A0
    platform: ads1115
    multiplexer: 'A0_GND'
    gain: 1.024
    ads1115_id: ads_3
    internal: true
  - name: "Current Kitchen Left"
    id: ctclamp_kitchen_left
    platform: ct_clamp
    sensor: ads_3_A0
    update_interval: 10s
    filters:
      - multiply: 1.3
      - calibrate_linear:
          - 0.000 -> 0
          - 1.000 -> 20.0
      - clamp:
          min_value: 0
          max_value: 20.0
  - id: ads_3_A1
    platform: ads1115
    multiplexer: 'A1_GND'
    gain: 1.024
    ads1115_id: ads_3
    internal: true
  - name: "Current Kitchen Right"
    id: ctclamp_kitchen_right
    platform: ct_clamp
    sensor: ads_3_A1
    update_interval: 10s
    filters:
      # - multiply: 1.3
      - calibrate_linear:
          - 0.000 -> 0
          - 1.000 -> 20.0
      - clamp:
          min_value: 0
          max_value: 20.0    
  - platform: ads1115
    multiplexer: 'A2_GND'
    gain: 1.024
    id: ads_3_A2
    ads1115_id: ads_3
    internal: true
  - name: "Current Dryer P1"
    id: ctclamp_dryer_p1
    platform: ct_clamp
    sensor: ads_3_A2
    update_interval: 10s
    filters:
      # - multiply: 1.3
      - calibrate_linear:
          - 0.000 -> 0
          - 1.000 -> 30.0
      - clamp:
          min_value: 0
          max_value: 30.0    
  - platform: ads1115
    multiplexer: 'A3_GND'
    gain: 1.024
    id: ads_3_A3
    ads1115_id: ads_3
    internal: true
  - name: "Current Dryer P2"
    id: ctclamp_dryer_p2
    platform: ct_clamp
    sensor: ads_3_A3
    update_interval: 10s
    filters:
      # - multiply: 0.875
      - calibrate_linear:
          - 0.001 -> 0
          - 1.000 -> 30.0
      - clamp:
          min_value: 0
          max_value: 30.0

  # Realtime Power
  - id: power_kitchen_wall
    platform: template
    name: "RT Power Kitchen Wall"
    lambda: |-
      return (id(ctclamp_kitchen_left).state * 114) + (id(ctclamp_kitchen_right).state * 114);
    update_interval: 10s
    device_class: power
    unit_of_measurement: W
    state_class: measurement
  # Daily Power
  - name: "Daily Power Kitchen Wall"
    platform: total_daily_energy      
    unit_of_measurement: kWh
    power_id: power_kitchen_wall
    accuracy_decimals: 2
    filters:
      - multiply: 0.001
    device_class: energy
  - id: power_dryer
    platform: template
    name: "RT Power Dryer"
    lambda: |-
      return (id(ctclamp_dryer_p1).state * 114) + (id(ctclamp_dryer_p2).state * 114);
    update_interval: 10s
    device_class: power
    unit_of_measurement: W
    state_class: measurement
  # Daily Power
  - name: "Daily Power Dryer"
    platform: total_daily_energy      
    unit_of_measurement: kWh
    power_id: power_dryer
    accuracy_decimals: 2
    filters:
      - multiply: 0.001
    device_class: energy


  # SCL 0x4b
  - platform: ads1115
    multiplexer: 'A0_GND'
    gain: 1.024
    id: ads_4_A0
    ads1115_id: ads_4
    internal: true
  - id: ctclamp_microwave
    platform: ct_clamp
    sensor: ads_4_A0
    name: "Current Microwave"
    update_interval: 10s
    filters:
      - calibrate_linear:
          - 0.000 -> 0
          - 1.000 -> 15.0
      - clamp:
          min_value: 0
          max_value: 15.0
  - id: power_microwave
    platform: template
    name: "RT Power Microwave"
    lambda: |-
      return id(ctclamp_microwave).state * 114;
    update_interval: 10s
    device_class: power
    unit_of_measurement: W
    state_class: measurement
  - name: "Daily Power Microwave"
    platform: total_daily_energy      
    unit_of_measurement: kWh
    power_id: power_microwave
    accuracy_decimals: 2
    filters:
      - multiply: 0.001
    device_class: energy

  - platform: ads1115
    multiplexer: 'A1_GND'
    gain: 1.024
    id: ads_4_A1
    ads1115_id: ads_4
    internal: true
  - id: ctclamp_washer
    platform: ct_clamp
    sensor: ads_4_A1
    name: "Current Washer"
    update_interval: 10s
    filters:
      - calibrate_linear:
          - 0.001 -> 0
          - 1.000 -> 15.0
      - clamp:
          min_value: 0
          max_value: 15.0
  - id: power_washer
    platform: template
    name: "RT Power Washer"
    lambda: |-
      return id(ctclamp_washer).state * 114;
    update_interval: 10s
    device_class: power
    unit_of_measurement: W
    state_class: measurement
  - name: "Daily Power Washer"
    platform: total_daily_energy      
    unit_of_measurement: kWh
    power_id: power_washer
    accuracy_decimals: 2
    filters:
      - multiply: 0.001
    device_class: energy

  - platform: ads1115
    multiplexer: 'A2_GND'
    gain: 1.024
    id: ads_4_A2
    ads1115_id: ads_4
    internal: true
  - id: ctclamp_stove_p1
    platform: ct_clamp
    sensor: ads_4_A2
    name: "Current Stove P1"
    update_interval: 10s
    filters:
      - calibrate_linear:
          - 0.000 -> 0
          - 1.000 -> 50.0
      - clamp:
          min_value: 0
          max_value: 50.0
  - platform: ads1115
    multiplexer: 'A3_GND'
    gain: 1.024
    id: ads_4_A3
    ads1115_id: ads_4
    internal: true
  - id: ctclamp_stove_p2
    platform: ct_clamp
    sensor: ads_4_A3
    name: "Current Stove P2"
    update_interval: 10s
    filters:
      - calibrate_linear:
          - 0.000 -> 0
          - 1.000 -> 50.0
      - clamp:
          min_value: 0
          max_value: 50.0
  - id: power_stove
    platform: template
    name: "RT Power Stove"
    lambda: |-
      return (id(ctclamp_stove_p1).state * 114) + (id(ctclamp_stove_p2).state * 114);
    update_interval: 10s
    device_class: power
    unit_of_measurement: W
    state_class: measurement
  - name: "Daily Power Stove"
    platform: total_daily_energy      
    unit_of_measurement: kWh
    power_id: power_stove
    accuracy_decimals: 2
    filters:
      - multiply: 0.001
    device_class: energy    

Odd!
Thanks for the info.
I tried code of identical functionality, even stripping it down to simply one new ESP32 and a single ADS1115 channel.
I did set the bus frequency to 10kHz and actually put in the pullup functions for SCL/ SCA in addition to the module mounted 10K’s

The modules I used are identical to yours also.

I am happy that my system works now and will refit the boards in my water monitoring system.

It did concern me that there were not more reports apart from listings some years back!

I have spare modules and the fault occurs on any Arduino scanning addressing routine also, so it will be an interesting endeavour to try to unearth a mathematical reason for the problem.

The problem has to be the dragging down of the data line though, I say this because after I removed the 10k from addr to ground on the module, I wired the addr to ground and did a scan using an Arduino ESP32 example.
As expected it came up with address found at 0x48.
Now simply adding 10K from ground to the SCL or SDA pin, kills the comms and the Arduino monitor comes back with “nothing found”.

This “system” is simply an ESP32, USB cable and the board with a 10K load on the bus, which is exactly what would happen if 0x4C or 0X4D were selected.

My final boards, ESP32’s and laptop / servers are different from the setup I first encountered the problem with and somehow logic suggests that a digital signal pulled up with 10k is going to be in trouble when fed into a 10k to ground?

Oh well, a bit of detection will be needed.