PCF8574 - read and write individual bits with one chip?

Hi,

I'd like to use some of the I/O ports of one PCF8574 to write and some to read from, as is possible with pins of Arduino itself. That is, when in READ-mode a pin should be a high-impedance input.

In the datasheet of the 8574 I see it mentioned that the P0..P7 I/O ports can be "quasi-bidirectional", but I don't understand how to configure that using the Wire library. There is a PCF8574 class by Rob Tillaart, but that is a layer on top of a full 8-bit read and 8-bit write, if I understand correctly, reading the source.

I need this to read a collection of eight 12-position rotary switches that are all wired in parallel. I'm "scanning" the 12 pins of the rotaries, and read the center pins of the individual switches to know the switch's setting. So, I use a bit pattern sent to two PCF8574's : (1111) 1111 1111 1110 to see if the setting is position 1, (1111) 1111 1111 1101 to sense position 2, etc. With a third PCF8574 I read 8 rotary's center pins. Due to the wiring of the rotaries a "1" written may well connect with the "0" in the pattern, which is not good for the 8574. I would like the 1's in the pattern to be not a logic "HIGH", but a high-impedance input instead. How do I do that?

Thanks!

as is possible with pins of Arduino itself.

No it is not basically possible to read individual bits on the Arduino, however there is a function that makes it appear that it does. It is the same with the PCF8574 you can only read / write a byte at a time, but you can write software so it looks like you are accessing just one bit at a time.

I need this to read a collection of eight 12-position rotary switches

Not a good chip to do that with. You would be much better off wiring up a bunch of resistors to the switch and feed the output to an analogue input. This diagram shows how this is done with nine switches, but it can easily be extended to 12.

Resiator input.jpg

Grumpy_Mike:
This diagram shows how this is done with nine switches, but it can easily be extended to 12.

Aha, I like that idea! Thanks!

For my latest design I'd need 6 or 7 PCF8574's; I now think I best switch to an Arduino Mega. It has exactly the pin behaviour I want, and it has more than enough pins for my purpose, without I/O expanders. With that many 8574's a Mega is cheaper and "cleaner" than the I2C setup too.

Actually, it makes much more sense to wire the resistors like this:


(With ground included as one of the switch positions. Ignore the reference to +12 V!)

Why is it more sensible rather than just another way?

Because your circuit required a resistor to ground and calculation of odd resistor values to achieve a linear progression.

Using a series chain allows all resistors to be the same value (possibly an array resistor if implemented on a PCB or is easier to assemble directly to the switch lugs if not using a PCB) and the code can reliably use a simple integer division of the analog read rather than thresholds.

rickj:
In the datasheet of the 8574 I see it mentioned that the P0..P7 I/O ports can be "quasi-bidirectional", but I don't understand how to configure that using the Wire library.

Just to explain a bit on the "quasi-bidirectional" i/o pins a bit since it is not documented very well in the 8574 data sheet.
And it isn't necessarily obvious, even when looking at the electrical characteristics section.

You read or write to the 8 bit i/o port which either reads or writes the bits for all 8 pins at once.

The PCF8574 can drive a pin low but it has almost no drive capability on the high side.
The 1/HIGH state is essentially like a pullup resistor an cannot drive any current, where as the 0/LOW is actually driven and can sink current.
This is how they support the "quasi-bidirectional" i/o.
If you want to use a pin as an input you must set its bit to 1.
While it will cause a HIGH output on the corresponding i/o pin, it can be pulled low if connected to another output.

To compare it to the Arduino pin output modes.
A 0 bit is like setting the pin to OUTPUT and then setting the pin to LOW
A 1 bit is like setting the pin to INPUT_PULLUP

When you read the PCF8574 i/o register you will always read the level that is present on the i/o pins.

--- bill

bperrybap:
To compare it to the Arduino pin output modes.
A 0 bit is like setting the pin to OUTPUT and then setting the pin to LOW
A 1 bit is like setting the pin to INPUT_PULLUP

OK! A port can sink ca 25 mA, but only drive 300 micro ampere, max. What happens, actually, if the attached circuitry connects a "1" with a "0" of the same 8574? Is there an internal protection against this situation?

I had not intended it to happen, but it did, and I noticed the 8574 got hot, so I understood something was wrong. (The device still works fine.)

A similar situation happens with certain matrix keyboards attached to a 8475. In one schematic I saw they use a 220 ohm series resistor to "protect against shorts when pressing keys". (I now use 1k.)

OK! A port can sink ca 25 mA, but only drive 300 micro ampere, max. What happens, actually, if the attached circuitry connects a "1" with a "0" of the same 8574? Is there an internal protection against this situation?

No protection.
You must never connect two outputs together. Current flows limited only by the source impedance and sink impedance. This normally exceeds the maximum permitted current for one or both devices.

Quote
OK! A port can sink ca 25 mA, but only drive 300 micro ampere, max. What happens, actually, if the attached circuitry connects a "1" with a "0" of the same 8574? Is there an internal protection against this situation?
No protection.
You must never connect two outputs together. Current flows limited only by the source impedance and sink impedance. This normally exceeds the maximum permitted current for one or both devices.

By just reading this post it reminded me that joke saying:

In Rome a group of nuns looking for a souvenir: a store there has a parrot and they ask for it.

The clerk explains that the parrot, if you pull it from the right leg, prays the Pater Noster. So it does the clerk and the parrot prays the Pater Npster.

The nuns are amazed, the cleck insists and explains that pulling the left leg the parrot prays the Ave Maria. He does soand the parrot prays as explained. The nuns are astonished.

Almost without recovering from the miracle, the youngest of the nuns asks "what if you throw both at the same time?". The parrot responds, "Well hell, I'll fall."

(Reading the entire thread answer and question have every sense).

Regards

Before the nuns metaphors run out of hand, this is the schematic, before and after. I just realized that what I need may just be the diodes to protect against the "1" being connected to a "0":

I had simply not seen that with certain constellations of the switch positions those could get connected... The diodes are a bit like a wired-OR in a way.

Before the nuns metaphors run out of hand, this is the schematic, before and after. I just realized that what I need may just be the diodes to protect against the "1" being connected to a "0":

OK. OK. :confused: I told that it was just because that post (the question has all the meaning reading the whole thread). :sweat_smile:

Best regards.