Please share your wiring design as it looks you don’t know how to properly wire I2C devices
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
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?
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.
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.
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.
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.
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 .
Oh well, if it’s a Pi I would definitely use a proper level shifting. That’s a whole different story compared to a 8266 at ~$2.