I have a PCF8574 and I'm trying to control 8 LEDs that are connected to it via the ESP32's SDA and SCL pins.
The SDA and SCL wires are 80cm long and made from Cat5e (Ethernet cable).
The problem I'm encountering is that sometimes the LED control works, but at other times, it does not. For instance, when I send the command "00000000," the LEDs are supposed to be ON , but sometimes they remain OFF so I have to resend the command multiple times to get the desired result.
I'm looking for a way to diagnose and address this issue. Is there a method to check if the command has been accepted or determine why it's not being accepted consistently?
unsigned long ms_LCD = 0; // millis();
String lcd="11111111";//all OFF
void setup(){
Wire.begin(); //LCD I2C
Wire.setClock(100000); // Set I2C clock speed to 100 kHz
}
void loop(
if (millis() - ms_LCD > 2000) { //update lcd every 2 sec
String lcd_tmp = lcd;
if (throttle_out == 0) {
lcd_tmp[7] = '1';
lcd_tmp[6] = '1';
} else if (throttle_out < 26) {
lcd_tmp[7] = '0';
lcd_tmp[6] = '1';
} else {
lcd_tmp[7] = '1';
lcd_tmp[6] = '0';
}
if (lcd != lcd_tmp) {
Serial.println(lcd_tmp);
lcd = lcd_tmp;
Wire.beginTransmission(0x20); // I2C address
Wire.write(strtol(lcd_tmp.c_str(), NULL, 2)); // Write the updated LED state to the PCF8574 using c_str()
Wire.endTransmission();
}
ms_LCD = millis();
}
}
Reviewing your partial code, I can't see a problem, but it could be a heck of a lot more efficient and simpler! Looks like it was written by someone more used to Python or Visual BASIC.
EDIT: actually I can see a problem, but it's probably the usual result of posting only part of your code instead of complete code. The variable lcd is declared local to setup(), so would not be accessible from loop(). That would cause a compile error.
Are the pullups, the PCF8574 and LEDs all running at 3v?
If not, are you using a level shifter on the I2C signals to convert between the
3v and the 5v i2c buses.
i.e. you should not hook the 3v processor i2c signals to a 5v I2C bus which is what you have if you run the PCF8574 and the LEDs at 5v.
Also for a bit of robustness, you could alter the code to retry the write operation if the i2c write fails.
Just keep in mind that it may never work in some situations.
i.e. don't write the code so it can get hung in loop doing continuous retries.
That is telling me you have noise on those lines and or they are way to long. I2C was designed for IC to IC on the same board, not a network. If you want to use the lower value resistors that is OK but you need to check the data sheets for each device on the bus to see if they will drive that much current. If there are other pull up resistors on the bus they form a parallel network and need to also be taken into account also. Switch to something like CAN designed for talking to wires. CAN's bus impedance is about 60 ohms, not several K ohms.
80 cm is pretty long for I2C, but should not cause such issues.
Also you mention you use CAT5 cable. Do not try to put SDA and SCL on the same pair, you will get crosstalk. Ideally both SCL and SDA are each paired with a ground return. Use a separate pair for the 5V supply, and the remaining pair for an additional ground connection.
If for some reason you can use only two pairs (four wires) bundle SCL with GND and SDA with the 5V.
For pull-up resistor: the minimum value as per I2C specifications is 1k. If you're using a breakout board for the PCF8574 it likely has 10k pull-up resistors on board as well. Keep that in mind.