PCF8574 don't work with optocoupler

Hello everyone, I have a PCF8574 chip with the P0 door configured as input. The problem I have is that if I isolate the input with an optocoupler it doesn't work. If I apply voltage (5V) directly, it does work.

Making tests I added a BC337 transistor to the optocoupler output and it works.

The voltage at the output of the optocoupler is 1.5V when connected directly to PCF8574, however, if I connect it to the BC337 transistor the voltage is 4.50V

I do not understand why. Could you help me understand it?

Thank you.

The pins on pcf8574 don't have true input and output modes like an Arduino pin. They can be set only as two modes which are equivalent to INPUT_PULLUP and OUTPUT+LOW.

I'm not sure why your first circuit does not work, but perhaps the voltage drop of the opto is too much given the weak pullup of P0.

I would have connected pin 16 on the opto to the P0 and pin 15 to ground. Then when the opto is activated, it will pull the P0 pin to ground. No resistors needed (except the current limiting resistor on the opto input, of course).

The other thing in your diagram I find strange is that you seem to have a common ground on the 12V side and the 5V side. So why use an opto? Why not just use a voltage divider?

The pins on pcf8574 don't have true input and output modes like an Arduino pin. They can be set only as two modes which are equivalent to INPUT_PULLUP and OUTPUT+LOW.

I'm not sure why your first circuit does not work, but perhaps the voltage drop of the opto is too much given the weak pullup of P0.

In the arduino program I had the input configured as INPUT, I changed it to INPUT_PULLUP but it still doesn't work. (I've tried it with both circuits).

I would have connected pin 16 on the opto to the P0 and pin 15 to ground. Then when the opto is activated, it will pull the P0 pin to ground. No resistors needed (except the current limiting resistor on the opto input, of course).

I have performed the test with INPUT and INPUT_PULLUP but it does not work.

The other thing in your diagram I find strange is that you seem to have a common ground on the 12V side and the 5V side. So why use an opto? Why not just use a voltage divider?

You are correct, I use a single power supply, I have already tried it with a voltage divider but it does not work. I enclose schemes of what I have tried.


I do not understand, because when using the optocoupler with the transistor BC337 it works. Now I use the voltage divider with the transistor (as in the diagram) and it doesn't work.

I have noticed another problem. With the voltmeter the scheme where I only use the voltage divider, if I check the voltage without the input-5V cable the voltage is 4.85V but if I connect it to the PCF8574 the voltage drops to 0V.
With the voltage divider and the transistor, something similar happens, the voltage drops to 1.5V

Thank you very much for your help :slight_smile:

davidddp:
In the arduino program I had the input configured as INPUT, I changed it to INPUT_PULLUP but it still doesn't work. (I've tried it with both circuits).

You misunderstood what I was saying, please read my previous post again. You cannot configure the pcf chip's inputs as INPUT or INPUT_PULLUP, these are not alternative choices with this chip. I think you should post your code so that we can see what you changed from INPUT to INPUT_PULLUP.

davidddp:
Thank you very much for your help :slight_smile:

But did you try my suggestion?

You misunderstood what I was saying, please read my previous post again. You cannot configure the pcf chip's inputs as INPUT or INPUT_PULLUP, these are not alternative choices with this chip. I think you should post your code so that we can see what you changed from INPUT to INPUT_PULLUP.

/*
 KeyPressed on PIN1
 by Mischianti Renzo <http://www.mischianti.org>

 https://www.mischianti.org/2019/01/02/pcf8574-i2c-digital-i-o-expander-fast-easy-usage/
*/

#include "Arduino.h"
#include "PCF8574.h"

// Set i2c address
PCF8574 pcf8574(0x20);
unsigned long timeElapsed;

void setup(){
	Serial.begin(9600);

	pcf8574.pinMode(P0, INPUT);
	pcf8574.pinMode(P1, OUTPUT);

	pcf8574.begin();
}

void loop() {
	uint8_t val1 = pcf8574.digitalRead(P0);
	if (val1==HIGH) {
		pcf8574.digitalWrite(P1, HIGH);
		Serial.println("KEY PRESSED");
	}else{
		pcf8574.digitalWrite(P1, LOW);
	}
}

But did you try my suggestion?

I have tested the voltage divider and the change of the pins. The rest maybe I did not understand.

Yon need to be absolutely clear on one point to start with.

Are you talking about connecting an input to an Arduino - in which case you use just a voltage divider, no opto-coupler and INPUT rather than INPUT_PULLUP?

Or are you connecting an input to a PCF8574 in which case INPUT or INPUT_PULLUP are simply meaningless and you need to either connect the optocoupler output between the PCF8574 and ground with no extra components on that output side, or else your BC337 directly between the PCF8574 and ground with a 22k resistor in series with the base and possibly a 10k resistor between base and ground in case there is a residual voltage on your 12 V input.

Yon need to be absolutely clear on one point to start with.

Are you talking about connecting an input to an Arduino - in which case you use just a voltage divider, no opto-coupler and INPUT rather than INPUT_PULLUP?

Hello, what I intend to do is use an optocoupler with the PCF8574 chip.

Or are you connecting an input to a PCF8574 in which case INPUT or INPUT_PULLUP are simply meaningless and you need to either connect the optocoupler output between the PCF8574 and ground with no extra components on that output side, or else your BC337 directly between the PCF8574 and ground with a 22k resistor in series with the base and possibly a 10k resistor between base and ground in case there is a residual voltage on your 12 V input.

I have tried the following scheme and it works correctly. After the 22k resistor I have a voltage of 5.5V

Which is better, use an optocoupler or a transistor?

Thank you.

That circuit is OK, but not optimum as you are relying the 10k to pull down the input against the built-in pullup.

It makes more sense to connect the transistor collector to the PCF8574 input and its emitter to ground. It then pulls the input firmly to ground when the transistor is biased on and the pullup in the PCF8574 pulls it HIGH when the transistor is off. You generally do not then require to add a pullup resistor to the collector.

Actually, I would be somewhat surprised if this does not work: :astonished:
Input01.png

Input01.png

It makes more sense to connect the transistor collector to the PCF8574 input and its emitter to ground. It then pulls the input firmly to ground when the transistor is biased on and the pullup in the PCF8574 pulls it HIGH when the transistor is off. You generally do not then require to add a pullup resistor to the collector.

I've tried what you say but it doesn't work. The scheme I have followed is this:
(I have also changed the program setting from INPUT to INPUT_PULLUP).

I have also tried the circuit that has provided me, but it does not work for me. At the output of the diode, I have no voltage, and if I remove the diode and disconnect P0 then I have 5V but if I connect the P0 cable then the voltage drops to 0V.

I do not understand anything :frowning:

PaulRB:
. . .

I would have connected pin 16 on the opto to the P0 and pin 15 to ground. Then when the opto is activated, it will pull the P0 pin to ground. No resistors needed (except the current limiting resistor on the opto input, of course).

. . .

I would agree with this based on the first circuit in the OP. P0 is an input pin. The logic is, however, inverted so that if the opto coupler is active, a digitalRead of P0 gives a LOW, otherwise it is HIGH. I’d add a 100k pull-up resistor on P0, though.
See http://www.ti.com/lit/ds/symlink/pcf8574.pdf section 9.2 for an example circuit.

Try this scheme, with 100K resistor works fine for me.


That would work oK. :grinning:

Paul__B:


That would work oK. :grinning:

It would, but what's the point? What is the opto-isolator isolating? Neither the shared grounds or the input signal!

PaulRB:
It would, but what's the point? What is the opto-isolator isolating? Neither the shared grounds or the input signal!

But, possibly converting a 5volt input to a 3.3 volt compatible output (which maybe also could have been achieved by a voltage divider resistor pair).
Maybe such a demonstration of using an opto-coupler as an input to a PCF857x would also help the (original) OP.

I am reasonably sure what I posted in #7 should work just fine where isolation is not critical, and that it is pretty clear that the OP had a wiring problem,

I was just saying that stamy1's approach would work and if you discriminate between the two grounds shown as belonging to the different sections of the circuit, it would isolate.

OK. I did a quick simulation of two variants of preparing an input for a PCF857x. No model exists for the device itself so I've used a 100k pullup.

0V from input circuit:

12 volts from input circuit:

The bold blue voltages are the output voltages of the respective circuits, and would be input to the PCF device.