PCF8574 lib (Playground): problems/improvements?

hi,
using Rob Tillard's PCF8574 lib (Playground) Arduino Playground - PCF8574Class , I encountered an issue:

to read a single bit as input_pullup (e.g., 7) which is wired to a button switch --> GND, requires first to write this bit HIGH.

This is not documented!

Here is a simple source code:

//
//    FILE: pcf8574_simple1in1out.ino
//    Library PCF8574 AUTHOR: Rob Tillaart
//
// setup: 
// PCF8574 pin 7 as input_pullup: wired to switch, switch wired to GND
// PCF8574 pin 2 as output, wired to LED (+470 Ohm), then wired to +Vcc 
// (inverse logic: pin2 HIGH=off, LOW=on)
//

#include "PCF8574.h"
#include <Wire.h>

// adjust addresses if needed

PCF8574 PCF_20(0x20);     

void setup()
{
   Serial.begin(115200);
   Serial.println("\nTEST PCF8574\n");
   Wire.begin();
}

void loop()
{     
   byte val;
   PCF_20.write(7, 1);            // indispensible: first must set pin 7 as input_pullup
                                  // >>>>>>>>> not documented! <<<<<<<<<<
   val = PCF_20.read(7);          // read pin 7 (button, pressed to GND = LOW !
   Serial.println(val);
   
   PCF_20.write(2, val);          // write pin 2 (LED, wired to +Vcc), inverse logic !
   delay(200);
}
//
// END OF FILE
//

Because that is extremely cumbersome for frequent read calls of arbitrary pin numbers, I wrote a new extra method
readBitpullup(uint8_t pin)
for the lib, fusioning the read bit method with a prior write bit method:

uint8_t PCF8574::readBitpullup(uint8_t pin)  
{
  PCF8574::read8();
    _data |= (1<<pin);       //   set pin bit HIGH ==> input_pullup
  PCF8574::write8(_data); //   write entire byte 

  PCF8574::read8();         // <<<<<<<  indispensible ?!
  return (_data & (1<<pin)) > 0;
}

my questions now:

  1. is there a github page? it's not documented in the Playground!
  2. where to report this issue about the missing documentation for 1st write, then 2nd read instead, if not on a github page?
  3. the new method I suggested works, but reading a bit (input_pullup) is yet very complicated as it requires 3 i2c operations: 1st read8, then write8, then again read8...: as the last read8 is indispensible (tested): can that be done even shorter and quicker though?
  4. in the code example the output LED is wired to +Vcc (inverse logic); is it possible to wire the LED to GND instead, not risking to destroy the PCF8574 IC?
  5. for reading entire bytes (read8() ) : is it required to do a prior write8(0xFF) compellingly?

Here it is on GitHub:

I have also added that link to the Playground page.

Make sure to check whether the code on GitHub has been updated from the version on the Playground. The issues may have already been fixed. It's not ideal to have two copies of the code hosted on two websites because they tend to not be kept synced. It's also a little bit confusing because Rob Tillaart has all his libraries and sketches mashed into a single repository, but oh well.

thank you for the link, indeed the lib code has changed.
That should be updated in the playground, both for the source code listed, and the description!

There is now a new function
readButton
which is supposed to do the same as my suggested readBitpullup().

What's left are questions #4 + #5:

  1. in the code example the output LED is wired to +Vcc (inverse logic); is it possible to wire the LED to GND instead, not risking to destroy the PCF8574 IC?
  2. for reading entire bytes (read8() ) : is it required to do a prior write8(0xFF) compellingly? (edit: e.g. if 8 buttons are wired each and all by input_pullup

another problem:

about the new github link: Arduino/libraries/PCF8574 at master · RobTillaart/Arduino · GitHub
how to download the new PF8574 lib to install it to the sketch folder?

You have to download the whole repository, you can't download just the library.
Here's the download link: https://github.com/RobTillaart/Arduino/archive/master.zip
The library is located in the libraries/PCF8574 subfolder.

thank you, but that's odd... as I dont want all libs, just the PCF8574. I'll c+p then the single file codes.
Perhaps one might wish to suggest Rob to change that for single libs download?

2nd, there is an issue about the class begin() method in the new lib: it calls Wire.begin() at the start , but that fails with my esp8266:
Because I use a L293 shield for pins D1-D4, I have to adjust i2c to Wire.begin(D5,D6).
Calling PCf8574.begin then muddles all up.
On the other hand, on my Mega, my Nano and my Due I use the default settings.
So I think it's generally a bad idea to call Wire.begin from device lib methods:
A dedicated Wire.begin() or Wire.begin(SDA,SCL) should be once set by the user for the arbitrary i2c initialization, and after that a class.begin() w/o Wire.begin may init each class instance optionally.
Should that be reported at github?

3rd, I am unsure about the PCF8574 IC outputs itself: Is it allowed to apply actuators to GND instead of +Vc, or is the IC output current too much limited and may destroy the IC?
I remember darkly to once have read sth like that, but perhaps not for the PCF8574 but instead for another IC.

tito-t:
thank you, but that's odd... as I dont want all libs, just the PCF8574. I'll c+p then the single file codes.
Perhaps one might wish to suggest Rob to change that for single libs download?

Even though there are a lot of libraries and sketches, the repository it's still a small download so I think my way is faster but either one will work fine. But I do completely agree that it's inconvenient to have so many unrelated things in a single repository. It's not only the download/clone issue. I use a couple of the libraries from that repository so I am watching it but then I get notifications for every pull request or bug report to any of the libraries, even the ones I'm not interested in. It means he can't use GitHub releases, so I don't get notifications when a new version of the libraries are released. It also makes it difficult to sort through the commit history.

I'm actually surprised not to find an issue report about this. The closest one is here:
https://github.com/RobTillaart/Arduino/issues/11

any hints about the other questions? at least about the inverse logic: just actuator wired to to Vc seems to work though.

2nd, there is an issue about the class begin() method in the new lib: it calls Wire.begin() at the start , but that fails with my esp8266:
Because I use a L293 shield for pins D1-D4, I have to adjust i2c to Wire.begin(D5,D6).
Calling PCf8574.begin then muddles all up.
On the other hand, on my Mega, my Nano and my Due I use the default settings.
So I think it's generally a bad idea to call Wire.begin from device lib methods:
A dedicated Wire.begin() or Wire.begin(SDA,SCL) should be once set by the user for the arbitrary i2c initialization, and after that a class.begin() w/o Wire.begin may init each class instance optionally.
Should that be reported at github?

3rd, I am unsure about the PCF8574 IC outputs itself: Is it allowed to apply actuators to GND instead of +Vc, or is the IC output current too much limited and may destroy the IC?

I only know about the Playground/GitHub aspects of this topic. Hopefully someone else will join in here to answer your other questions.