Problem with pcf8574

Hi guys. I've made a macro keyboard 2 years ago with a pro micro and i wanted to reprogram actions but since i re uploaded the code (that was previously working fine), it seems that the pcf8574 state of all pins is always HIGH (1). Button pressed or not, always 1.

Maybe something changed in the library (GitHub - xreef/PCF8574_library: PCF8574 library. i2c digital expander for Arduino, Raspberry Pi Pico and rp2040 boards, esp32, SMT32 and ESP8266. Can read write digital values with only 2 wire. Very simple to use and encoder support.), i don't know.

Here is a simple code i tried running to focus on pcf8574, got 11111111 always:

#include <PCF8574.h>
#define adresseDuModulePCF8574 0x22           // Adresse i2c du PCF8574 (attention : dépend de la configuration des broches A2/A1/A0 de cette puce)

PCF8574 pcf8574(adresseDuModulePCF8574);

// ========================
// Initialisation programme
// ========================
void setup() {
  delay (5000);
  // Initialisation de la liaison série (pour communication : arduino -> PC)
  Serial.begin(9600);
  Serial.println(F("===================================================================="));
  Serial.println(F("Exemple 2 (tuto PCF8574) : lecture des ENTREES P7 à P0, en utilisant"));
  Serial.println(F("                           une librairie disponible sous Arduino IDE"));
  Serial.println(F("===================================================================="));
  Serial.println("");

  // Définition des E/S P7 à P0 du PCF8574 en ENTRÉE
  //      Nota : cela DOIT précéder l'initialisation du PCF8574 qui suit, utilisant la fonction begin (ceci est spécifique à cette librairie)
  pcf8574.pinMode(P0, INPUT);
  pcf8574.pinMode(P1, INPUT);
  pcf8574.pinMode(P2, INPUT);
  pcf8574.pinMode(P3, INPUT);
  pcf8574.pinMode(P4, INPUT);
  pcf8574.pinMode(P5, INPUT);
  pcf8574.pinMode(P6, INPUT);
  pcf8574.pinMode(P7, INPUT);

  // Initialisation du PCF8574
  Serial.print(F("Initialisation du pcf8574 : "));
  if (pcf8574.begin()){
    Serial.println(F("REUSSIE"));
    Serial.println("");
  } else {
    Serial.println(F("ECHEC"));
    Serial.println(F("Arrêt du programme."));
    while(1);
  }

}


// =================
// Boucle principale
// =================
void loop() {

  // Lecture des entrées
  uint8_t valP0 = pcf8574.digitalRead(P0);
  uint8_t valP1 = pcf8574.digitalRead(P1);
  uint8_t valP2 = pcf8574.digitalRead(P2);
  uint8_t valP3 = pcf8574.digitalRead(P3);
  uint8_t valP4 = pcf8574.digitalRead(P4);
  uint8_t valP5 = pcf8574.digitalRead(P5);
  uint8_t valP6 = pcf8574.digitalRead(P6);
  uint8_t valP7 = pcf8574.digitalRead(P7);

  // Affichage des valeurs sur le port série
  Serial.print(valP7);
  Serial.print(valP6);
  Serial.print(valP5);
  Serial.print(valP4);
  Serial.print(valP3);
  Serial.print(valP2);
  Serial.print(valP1);
  Serial.print(valP0);
  Serial.println("");         // Retour à la ligne

  // On attend un peu, puis on reboucle !
  delay(1000);
  
}

I don't manage to make the pcf8574 commands working as before and it's driving me crazy. Tks in advance for your help !

I would check to see which library you are actually using. There are pcf8574 and PCF8574 (note case) in the library manager and they are different from the GitHub one you reference.

Also the pinmode() should probably be set after the begin().

Hi oldcurmudgeon!

I use this one from Renzo Mischianti, v2.3.7.

As far as i know, in this library, the pinmode has to be set before. But i can try for sure !

Tks for your answer.

Edit: I tried and if i put the pinmode after the begin, the begin fail.

That is a very complex library with a lot of function you don't need for simple buttons. On a digital read it, by default, doesn't read the pin if it thinks it knows the value.

Try adding true to the digitalRead(). For example digitalRead(P0,true) to force it to actually read the pin.

I assume the buttons are connected to ground when on.

Added true to force read and nothing changed, still 11111111

All pcf8574 buttons are connected to vcc and are wired to each P0...P7 (while all buttons non pcf8574 are connected to gnd and each to arduino micro pins).



Please provide a schematic. The mode set on the PCF8574 is a misnomer, it really only has an output mode where the output is low or a weak pullup for high. This is called quasi-bidirectional. In high mode the pin can be pulled low to indicate a low. As an output, low mode can sink about 20 ma, high mode can only source about 100 ua. All the details are in the data sheet.

When used with buttons typically the button is connected between the pin and ground. A high is written to the pin, which activates the weak pull up. The pin is then read and a low indicates a button press.

It drives me nut... All was working fine for more than 2 years so it must be a code update problem. So frustrating... I might convert this project with a matrix layout and get rid of this ***** PCF :face_with_head_bandage:

Those pesky little nifty pcf8574 I have i few working on my boards,
after trying a lot of different libery's it was clear just use wire.h

#include <Wire.h>
#define PCF8574_ADDR 0x20 // Hex
  Wire.begin();;
  Wire.beginTransmission(PCF8574_ADDR);  // Address of PCF8574 
  Wire.write(0xFF);                      // 0B11111111 aka 255
  Wire.endTransmission();
  Wire.requestFrom(PCF8574_ADDR, 1);
  currentByte = Wire.read(); 

in arduno.h you can find;

#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit))) //sets a bit HIGH
#define bitClear(value, bit) ((value) &= ~(1UL << (bit))) // setes a bit LOW
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))

so , uint8_t x bitRead(currentByte,4) will put current state of that bit into x bit values are 0-7

Ok, ty, i will check that and save that code for future projects !

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.