I've been dealing with an issue for the life of me I cannot figure out. I'm using a PCF8575 GPIO expander/mux. the circuit is simply 22->SCL, 21->SDA and GND/VCC.
my expander works at first, but once i just place my finger near the black plastic CPU my boards timing stops working. the script prints a value once every 500ms, but switches to 2 logs every 1 second and stops detecting inputs.
I've tried
- different sketches
- pull up resistors on SDA/SCL (4.4k/10k)
- lots of different logging debugging
- multiple boards and expanders. no change
If I add a log statement inside the loop I get hundreds of statements all with the same timestamp. Its almost as if the expander is somehow breaking the timing or causing a code execution slowdown. I'm really lost for words here
void setup(){
Serial.begin(115200);
pcf8575.pinMode(P0, INPUT);
}
unsigned long thing = 0;
void loop() {
if ((millis() - thing) > 500) {
thing = millis();
Serial.println("here " + String(expander.digitalRead(P0)));
}
}
output after a touch
21:16:04.078 -> here 0
21:16:04.078 -> here 0
21:16:05.546 -> here 0
21:16:05.546 -> here 0
it prints once every 500ms, how can it now show 2 logs with the timestamp? is the expander over I2C internally messing up timing?
Interesting, it sounds like a hardware problem. Post an annotated schematic showing exactly how you have wired it, be sure to include all connections, power supplies, etc.
Are you using a PCF8575 chip or a board that contains a PCF8575?
If a board then post a link to where you bought it.
If it is a chip then you need a lot more than just:-
You need pull up resistors on each I2C line and you need to pull the inputs A0 to A4 to the appropriate logic level to define address the chip presents.
Have you tried actually addressing the chip over the I2C bus?
I can see no reference to this in your code.
using a PCF8575 breakout board like this.
okay i wasnt sure about the pull ups ive read to use them and i tried adding them but it didn't fix my issue. im pretty sure the chip is hardcoded to 0x20, but what do you mean about pulling the inputs? i see on the back of my PCF there's copper pads for A0-A2.
i initialize like this
PCF8575 expander(0x20);
addressing it with the Wire library? I tried some of the examples like this
// Instantiate Wire for generic use at 400kHz
TwoWire I2Cone = TwoWire(0);
// Instantiate Wire for generic use at 100kHz
TwoWire I2Ctwo = TwoWire(1);
//PCF8575 pcf8575(&I2Ctwo, 21,22,0x20);
but never got it to work. i got better results using the PCF library itself like in my original post's sketch
Connecting them to the ground or Vdd.
Is your code missing something? There are no I2C libraries used.
You seem also to be using a chip powered by 5V on a system that uses 3V3 signals. Your board has no level shifters, so you are exposing your ESP32 to 5V which could damage it.
Your original code shows no libraries being imported.
Those links need to have solder blobs on them to set the address.
The blobs are from center to the ground on the right to make them a 0,
or from center to left to set them to a 1.
You also need to put a blob of solder from Vcc to Vdo link if you want to run it off the same voltage as the rest of the board.
1 Like
I think this may have been one of the issues. When I switched from arduino->esp i forgot to change things to 3v. i recall now having unpredictable behavior when i had 5v on an analog input. I went and changed my expander to be powered by 3v and the results are way more consistent now. that's a big help thank you! my inputs are buttons, when they get pressed and get pulled high (to 3v) the mux gets pretty warm. definitely not hot, far from it, but noticeably warmer everytime a button is pressed and held.
in terms of soldering on the board like you mentioned. first for A inputs, how would i decide whether I need them 1 or 0? my question being since it seems to be working, what is the benefit of doing it/how do i decide 1 or 0? it seems to be addressable by 0x20 already
You also need to put a blob of solder from Vcc to Vdo link if you want to run it off the same voltage as the rest of the board.
sorry, could you clarify this a bit more? when you say the rest of the board do you mean the mcu or mux? if i now power the VCC header through 3v, what happens if i bridge VCC/VDO?
thanks so much!!!
The data sheet shows you the relationship between the state of the A pins with the address you get.
This is the diagram you need to see what that is:-
This means that if all the A pins are set to zero then the address of the chip will be 0x20. If all the address pins are set to 1 then you will get 0x27 as the address.
If these pins are not connected to anything they are known as floating and can pick up interference. You are in fact just a big blob of salty water ( we all are ) and you act as an antenna so as you touch or get close to the chip you increase the amount of interference pickup you get and you could therefore change the address of your chip on the fly.
Are these the outputs from the PCF8575? I can see no other switches on the ESP32.
You are subjecting the PCF8575 to 5V on there output pins. For a chip now powered off 3V3 this exceeds the power rail and so will get hot and eventually the chip will burn out.
It will work, but this is only needed if one of the A pins is connected to be a 1.
1 Like
Understood I can then solder the pins to solidify the address thank you.
Are these the outputs from the PCF8575? I can see no other switches on the ESP32.
in my diagram, expander's pin P0 (input) is connected to the lightswitch button. Which in the diagram was previously pulled between GND/5V, which I now converted to GND/3V. I've now entirely removed 5V from the circuit and only use 3V. Its consistent now but was just concerned whether it should even be a little bit warm.
It will work, but this is only needed if one of the A pins is connected to be a 1.
okay cool, so if I put all the A pins to 0 to solidify the 0x20 address and power VCC through 3v I can leave this unbridged?
Yes.
I would not expect it to be warm at all.
This is from the data sheet about the input / output pins:-
This quasi-bidirectional I/O can be used as an input or output without the use of a control signal for data direction.
At power-on the I/Os are HIGH. In this mode only a current source (IOH) to VDD is active. An additional strong pull-up to VDD (IOHt) allows fast rising edges into heavily loaded outputs. These devices turn on when an output is written HIGH, and are switched off by the negative edge of SCL. The I/Os should be HIGH before being used as inputs. After power-on as all the I/Os are set HIGH all of them can be used as input. Any change in setting of the I/Os as either inputs or outputs can be done with the write mode. Warning: If a HIGH is applied to an I/O which has been written earlier to LOW, a large current (IOL) will flow to VSS.
1 Like
thanks!
any suggestions on things to try in relation to heat or ideas on what could be wrong?
before with 5v and multiple inputs it got hot so now at 3v its drastically reduced. but i feel itstill shouldnt even really be warm
In looking at your schematic i do not see up resistors. If in fact they are missing I can see where it will cause problems such as you were experiencing. Also A0, A1, and A2 are missing, they can't be left open but I always connect them to power or ground. Here is a link to the PCF8575. https://www.ti.com/lit/ds/symlink/pcf8575.pdf?ts=1686957671872&ref_url=https%253A%252F%252Fwww.google.com%252F
Can you please post your FULL CODE in a new post. The code in post 1 was not complete.
Please post an understandable schematic of your input switch. The one you posted doesn't make sense to me. Also update what schematic you posted before to reflect the voltage changes you have made. Again in a new post.
No they can't be left open. Maybe on some boards they are pulled down with a resistor, but not on the one the OP is using. Remember there are a lot of differences between the data sheet of a device and the reality of what board they are mounted on, when it comes to wiring them up.
1 Like
Here's my updated schematic with 3v and pullups. what didn't make sense to you about my button? the 2 pins are exposed and when a button is pushed it connects the 2 pins together
and ive been trying with adding a secondary button on P1
and my sketch
#include <Wire.h>
#include "PCF8575.h" // Required for PCF8575
/** PCF8575 instance */
PCF8575 expander(0x20);
void setup() {
Serial.begin(115200);
Wire.begin();
expander.begin();
expander.pinMode(P0, INPUT);
expander.pinMode(P1, INPUT);
}
unsigned long timer = 0;
void loop() {
if ((millis() - timer) > 1000) {
timer = millis();
Serial.println(String(expander.digitalRead(P0)) + " " + String(expander.digitalRead(P1)));
}
}
the PCF library being from here
Sorry I missed the oops. They Cannot Be left open is correct and they can be directly connected to VCC or Ground.
Thanks for the update.
I can't see it on the schematic. All I can see it a dotted box saying "Light switch". This seems to be wired with a pull down resistor. As I mentioned in Post #13
The way to wire a switch here is to pull it down only when the switch is pressed. So to my way of thinking the switch should be between the input and ground.
While your arrangement would work with a normal input this chip does not provide a normal input arrangement. It is a bit of an oddity in the I/O world. However, there seems to be an obsession in the Arduino for switches with an external pull down connected to a high pull up.
This is conventionally not the way engineers wire up switches.
1 Like