Wemos D1 does not support two mcp23017?

I have been trying for days the installation of two MCP23017 on I2C wemos D1. In practice this happens: It reads only one or the one at address 0x20 or the one at 0x21. He doesn’t read them both. If I connect both of them, the reading is blocked and if I disconnect the wire either at 23017 ox20 or at 23017 0x21 “sda” the wemos resumes with the only address left.
The outputs for I2C are the classic D1 and D2.
I’ve also tried adding additional bias resistors but nothing changes.
Of course I changed several wemos and mcp23017 but always with the same result.
I also tried to power everything at 3.3v (the mcp23017s are powered at 5vcc) but again no result. It appears to have no power to power two SDA SCLs for this type of chip.

I ask you if you have any experiences to share with wemos and 2 or more mcp23017s, it looks like it doesn’t have the power to power two chips.

Please share your wiring design as it looks you don’t know how to properly wire I2C devices :wink:

I understand your doubts but I know the i2c protocol well. I have been implementing it for years on self-built pcbs equipped with micro 16f and 18f. I used it with rpi4 before burning the sda port due to an extra voltage.
now i am transferring all my entities to esphome. i have three distinct pcb and i didn’t want to use three ESP modules but only a wemos d1 with three mcp23017.
So trust that the connections are correct, what I ask is only confirmation from those who use esphome with these devices.

And your yaml’s too!

Ok here the two pcb where I’m doing the tests.


sorry, this is the correct image. The addresses are 0x20 and 0x21

esphome:
  name: antifurto-e-riscaldamento

esp8266:
  board: d1_mini

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:
  password: "xxxxxxxxxxxxxxxxxxxxxxxxxx"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Antifurto-E-Riscaldamento"
    password: "yyyyyyyyyyyyy"

captive_portal:
#-----------------------------------
i2c:
  sda: GPIO4 #D2
  scl: GPIO5 #D1
  frequency: 50kHz
  scan: True
  
 # Example configuration entry
mcp23017:
  - id: 'mcp23017_antifurto'
    address: 0x20
  - id: 'mcp23017_riscaldamento'
    address: 0x21 

# MCP23017 su PCB "periferica lavanderia"
# INGRESSI da antifurto porte A
binary_sensor:
  - platform: gpio
    name: "MCP23017 Pin #0"
    pin:
      mcp23xxx: mcp23017_antifurto
      # Use pin number A0
      number: 0
      # One of INPUT or INPUT_PULLUP
      mode: INPUT_PULLUP
      inverted: False

  - platform: gpio
    name: "MCP23017 Pin #1"
    pin:
      mcp23xxx: mcp23017_antifurto
      # Use pin number A1
      number: 1
      # One of INPUT or INPUT_PULLUP
      mode: INPUT_PULLUP
      inverted: False
      
  - platform: gpio      
    name: "MCP23017 Pin #2"
    pin:
      mcp23xxx: mcp23017_antifurto
      # Use pin number A2
      number: 2
      # One of INPUT or INPUT_PULLUP
      mode: INPUT_PULLUP
      inverted: False
      
  - platform: gpio
    name: "MCP23017 Pin #3"
    pin:
      mcp23xxx: mcp23017_antifurto
      # Use pin number A3
      number: 3
      # One of INPUT or INPUT_PULLUP
      mode: INPUT_PULLUP
      inverted: False
  
  - platform: gpio  
    name: "MCP23017 Pin #4"
    pin:
      mcp23xxx: mcp23017_antifurto
      # Use pin number A4
      number: 4
      # One of INPUT or INPUT_PULLUP
      mode: INPUT_PULLUP
      inverted: False
      
  - platform: gpio      
    name: "MCP23017 Pin #5"
    pin:
      mcp23xxx: mcp23017_antifurto
      # Use pin number A5
      number: 5
      # One of INPUT or INPUT_PULLUP
      mode: INPUT_PULLUP    
      inverted: False

  - platform: gpio   
    name: "MCP23017 Pin #6"
    pin:
      mcp23xxx: mcp23017_antifurto
      # Use pin number A6
      number: 6
      # One of INPUT or INPUT_PULLUP
      mode: INPUT_PULLUP    
      inverted: False
      
  - platform: gpio
    name: "MCP23017 Pin #7"
    pin:
      mcp23xxx: mcp23017_antifurto
      # Use pin number A7
      number: 7
      # One of INPUT or INPUT_PULLUP
      mode: INPUT_PULLUP    
      inverted: False

# MCP23017 su PCB "periferica lavanderia"
# MCP23017 - ingressi porte B
  - platform: gpio
    name: "MCP23017 Pin #8"
    pin:
      mcp23xxx: mcp23017_antifurto
      # Use pin number B0
      number: 8
      mode: INPUT_PULLUP
      inverted: False
      
  - platform: gpio
    name: "MCP23017 Pin #9"
    pin:
      mcp23xxx: mcp23017_antifurto
      # Use pin number B1
      number: 9
      mode: INPUT_PULLUP
      inverted: False
 
  - platform: gpio
    name: "MCP23017 Pin #10"
    pin:
      mcp23xxx: mcp23017_antifurto
      # Use pin number B2
      number: 10
      mode: INPUT_PULLUP
      inverted: False 

  - platform: gpio
    name: "MCP23017 Pin #11"
    pin:
      mcp23xxx: mcp23017_antifurto
      # Use pin number B3
      number: 11
      mode: INPUT_PULLUP
      inverted: False

  - platform: gpio
    name: "MCP23017 Pin #12"
    pin:
      mcp23xxx: mcp23017_antifurto
      # Use pin number B4
      number: 12
      mode: INPUT_PULLUP
      inverted: False

  - platform: gpio
    name: "MCP23017 Pin #13"
    pin:
      mcp23xxx: mcp23017_antifurto
      # Use pin number B5
      number: 13
      mode: INPUT_PULLUP
      inverted: False

  - platform: gpio
    name: "MCP23017 Pin #14"
    pin:
      mcp23xxx: mcp23017_antifurto
      # Use pin number B6
      number: 14
      mode: INPUT_PULLUP
      inverted: False

  - platform: gpio
    name: "MCP23017 Pin #15"
    pin:
      mcp23xxx: mcp23017_antifurto
      # Use pin number B7
      number: 15
      mode: INPUT_PULLUP
      inverted: False
 
#--------------------------------- 
# MCP23017 su PCB "riscaldamento"
# Individual inputs
#binary_sensor:
  - platform: gpio
    name: "open bagno matrimoniale"
    pin:
      mcp23xxx: mcp23017_riscaldamento
      # Use pin number 5 for B4
      number: 12
      mode:
        input: true
        pullup: true
      inverted: true

  - platform: gpio
    name: "open bagno piano terra"
    pin:
      mcp23xxx: mcp23017_riscaldamento
      # Use pin number 6 for B5
      number: 13
      mode:
        input: true
        pullup: true
      inverted: true

  - platform: gpio
    name: "open bagno piano camere"
    pin:
      mcp23xxx: mcp23017_riscaldamento
      # Use pin number 7 for B6
      number: 14
      mode:
        input: true
        pullup: true
      inverted: true

# Individual outputs
switch:
  - platform: gpio
    name: "riduzione°C camere"
    pin:
      mcp23xxx: mcp23017_riscaldamento
      # Use pin number 21 for A0
      number: 0
      mode: OUTPUT
      inverted: False
      
  - platform: gpio
    name: "riduzione°C piano terra"
    pin:
      mcp23xxx: mcp23017_riscaldamento
      # Use pin number 22 for A1
      number: 1
      mode: OUTPUT
      inverted: False
 
  - platform: gpio
    name: "riduzione°C bagno terra"
    pin:
      mcp23xxx: mcp23017_riscaldamento
      # Use pin number 23 for A2
      number: 2
      mode: OUTPUT
      inverted: False 

  - platform: gpio
    name: "riduzione°C bagno matrim"
    pin:
      mcp23xxx: mcp23017_riscaldamento
      # Use pin number 24 for A3
      number: 3
      mode: OUTPUT
      inverted: False

  - platform: gpio
    name: "riduzione°C bagno camere"
    pin:
      mcp23xxx: mcp23017_riscaldamento
      # Use pin number 25 for A4
      number: 4
      mode: OUTPUT
      inverted: False

  - platform: gpio
    name: "riduzione°C taverna"
    pin:
      mcp23xxx: mcp23017_riscaldamento
      # Use pin number 26 for A5
      number: 5
      mode: OUTPUT
      inverted: False

  - platform: gpio
    name: "avvia alta T° caldaia"
    pin:
      mcp23xxx: mcp23017_riscaldamento
      # Use pin number 27 forA6
      number: 6
      mode: OUTPUT
      inverted: False

  - platform: gpio
    name: "out pin D0 a micro"
    pin: GPIO16
    id: out_pin_D0
    inverted: yes
    
  - platform: gpio
    name: "out pin D5 a micro"
    pin: GPIO14
    id: out_pin_D5
    #inverted: yes
    
  - platform: gpio
    name: "out pin D6 a micro"
    pin: GPIO12
    id: out_pin_D6
    inverted: yes

  - platform: gpio
    name: "out pin D7 a micro"
    pin: GPIO13
    id: out_pin_D7
    #inverted: yes    

  - platform: gpio
    name: "out pin D8 a opto"
    pin: GPIO15
    id: out_pin_D8
    inverted: yes   
    

and this is the code for the two mcp23017.

I am also attaching the wemos log where you can see that only one chip is found

1 Like

Nevermind I need new glasses. I now see the address line.

̶H̶i̶,̶ ̶
̶I̶’̶m̶ ̶n̶o̶ ̶e̶x̶p̶e̶r̶t̶.̶ ̶B̶u̶t̶ ̶h̶a̶v̶e̶ ̶a̶ ̶f̶e̶w̶ ̶W̶.̶I̶.̶P̶.̶ ̶p̶r̶o̶j̶e̶c̶t̶s̶ ̶t̶h̶a̶t̶ ̶u̶s̶e̶’̶s̶ ̶M̶C̶P̶2̶3̶0̶1̶7̶ ̶p̶o̶r̶t̶ ̶e̶x̶p̶a̶n̶d̶e̶r̶.̶
̶
̶T̶h̶e̶ ̶s̶c̶h̶e̶m̶a̶t̶i̶c̶s̶ ̶d̶o̶ ̶n̶o̶t̶ ̶s̶h̶o̶w̶ ̶a̶n̶y̶ ̶a̶d̶d̶r̶e̶s̶s̶i̶n̶g̶ ̶o̶f̶ ̶t̶h̶e̶ ̶M̶C̶P̶2̶3̶0̶1̶7̶ ̶i̶c̶.̶ ̶W̶h̶e̶n̶ ̶u̶s̶e̶i̶n̶g̶ ̶t̶w̶o̶ ̶o̶r̶ ̶m̶o̶r̶e̶ ̶I̶C̶’̶s̶ ̶t̶o̶g̶e̶t̶h̶e̶r̶ ̶y̶o̶u̶ ̶w̶e̶l̶l̶ ̶n̶e̶e̶d̶ ̶t̶o̶ ̶a̶d̶d̶r̶e̶s̶s̶ ̶t̶h̶e̶ ̶I̶C̶’̶s̶

Quote form https://www.best-microcontroller-projects.com/mcp23017.html

MCP23017 Addressing

The 23017 has three input pins to allow you to set a different address for each attached MCP23017. Addresses available are specified in the I2C control byte and each device is selected by the I2C sequence below:

mcp23017 hardware address

The above corresponds to a hardware address for the three lines A0, A1, A2 corresponding to the input pin values at the IC. You must set the value of these hardware inputs as 0V or (high) volts and not leave them floating otherwise they will get random values from electrical noise and the chip will do nothing!

The four left most bits are fixed a 0100 (specified by a consortium who doles out address ranges to manufacturers).

So the MCP23017 I2C address range is 32 decimal to 37 decimal or 0x20 to 0x27 for the MCP23017.

Hope it’s of help.

I think i’ve read once that you have to define two i2c buses (not on different pins, just definition).
look HERE if it helps…

Thank you. I had already read this post along with many others but the result is always this: if I use only one chip, everything is fine. If I physically add the second wemos it doesn’t see any chips. I remove one and magically what remains (be it 0x20 or 0x21) is read, after a reset of course.

I have already used the wemos with display + expander of various types and have never had any problems.
Have patience but I only ask those who use two MCP23017 with the wemos on the same I2C channel if they work. I doubt that wemos only carries one.
I want to be sure that it is feasible otherwise I change direction and install three wemos (what a waste).

I have multiple MCP23017 devices on the same bus with no problems. A quick scan of the code seems to be OK.

Depending on the board you have, you may need to have a 4k7 resistor on each of the SDA and SCL lines to pull them to 3v3. You only need one per line and that should be fine for the I2C bus. I don’t seem to see the pull ups on your schematic?

1 Like

Also, not that I think it matters, but it’s better practice to use a 10k resistor to pull the A1, A2 and A3 lines high or low to set the id of the chip. Your schematic shows them being tied to 3v3 and ground, depending on the chip.

As I say, it should work fine as shown. You just need to check if 4k7 pull ups on the SDA and SCL lines helps. I suspect it will.

Definitely do this!
I found that the I2C signals on my bus without pullups were so distorted that my scope could not decode them. Funny enough the bus was still working. But adding another client to the bus finally killed it.
With pullups it is all working fine again.

1 Like

Now it seems to work. After a couple of reboots wemos saw the two chips. I hope it remains stable.
I soldered the two 4.7 resistors and actually on the oscilloscope the waveform is almost perfect. I also filtered the 3.3 with a nice 47 micro capacitor and a by pass.
What can I say … I thought the stock pullups were enough.
Thanks for your help, as always the community responds and I am grateful to you for this.
Thanks to both Jpsy and branchespark for the solution.

1 Like

They actually should be sufficient. I am still not sure whether the internal pullups are activated at all in I2C mode. This might even be a bug in ESPHome.

The docs say

Please note the ESP will enable its internal 10kΩ pullup resistors for these pins, so you usually don’t need to put on external ones.

Already. I had read this too. Maybe the problem is a bug like jpsy says or 10k is too high to drive the bus with multiple devices. The fact is that with 4.7k resistors and a distance of about 30cm (with shielded cable) at the moment it works. Now I’m trying with the third mcp23017, always with a distance of 30 cm and shielded cable. We would see.

1 Like

Another reason could be the fact that you run your MCP with 5 Volt while the internal pullups only pull against 3.3. I have the same situation in my setup.

The datasheet of MCP 23017 specifies a minimum high value for SCL and SDA of 0.8 Vdd.
So at Vdd = 5 Volt you need min 4 Volt high levels on clock and data. Pullups against 3.3 cannot ensure that.

1 Like

I always add external pull-ups, too. Had too many problems without them. It seems that they are just too big valued,especially at longer distances, like BMP sensor a few metres away from module.
Another thing that jpsy already noticed is power supply. You really should power MCP on 3.3V, not on 5V. I missed that detail in your schematic… if you need more power on MCp outputs use ULN200x chips for that (they are open collector transistors).

I am actually running my MCPs on 5 Volt too. So I can drive 3 Volt LEDs without an additional driver stage. I somewhat brutally use 4.7k pullups against 5V for SCL and SDA. This is definitely beyond the specs of the ESP. But I never had any problems with this setup.

This is definitely cleaner though.

Well, unless you use white or blue led’s you can drive them from 3.3V quite fine…

But, generally it shouldn’t be a problem combining 5 and 3.3V as example above. But, to be sure there are level converters available, like this one

For my home automation I don’t care about the loads because I interface in and out of the mcp23017 with opto or array or single. The pcb gets a little more complicated but I avoid any problem. Problem that cost me the burning of the SDA port on the RP4, as already explained in other post :rage: .