What is being measured on the Collector of an optocoupler?

I am using an HCPL-817 optocoupler (Datasheet here) between two Arduino Pro Minis (both 5v version). Please see the attached diagram.

On the Sending Arduino, the following code writes pins 8 (an LED) and 12 (the optocoupler) HIGH for 3 seconds and then LOW for 3 seconds.

int OptoSignal = 12;
int LEDSignal = 8;

void setup() 
{
  pinMode(OptoSignal, OUTPUT);
  pinMode(LEDSignal, OUTPUT);
}

void loop() 
{
  digitalWrite(LEDSignal, HIGH);
  digitalWrite(OptoSignal, HIGH);
  delay(3000);
  digitalWrite(OptoSignal, LOW);
  digitalWrite(LEDSignal, LOW);
  delay(3000);
}

On the receiving Arduino, the following code reads the value on pin A1 every 100 ms.

int OptoSignalIn = A1;
int Reading_OptoSignal;

void setup() 
{
  pinMode(A1, INPUT_PULLUP);
  Serial.begin(9600);
}

void loop() 
{
  Reading_OptoSignal = analogRead(OptoSignalIn);
  Serial.println(Reading_OptoSignal);
  delay(100);
}

When pins 8 and 12 on the sending Arduino are written HIGH (ie the led and the infrared-led in the optocoupler are turned on), the Reading_OptoSignal value is approximately 18.

When pins 8 and 12 on the sending Arduino are written LOW (ie the led and the infra-red led in the optocoupler are turned off), the Reading_OptoSignal value is approximately 1020.

Years ago, I cobbled together a home-made optocoupler using an LED and a photoresistor. When the LED was turned on, the reading of the photoresistor increased. I expected the same behavior with the HCPL-817, that is, when pins 8 and 12 are written HIGH, I expected the Reading_OptoSignal value to increase not decrease.

Why does the value decrease when pins 8 and 12 are written HIGH? Is it due to the fact that the HCPL-817 uses a phototransistor, rather than a photoresistor? What exactly is being measured on pin A1 of the Receiving Arduino?

image

I have been using the 817 since a long time....
When a HIGH is written to the LED part of the 817 this triggers the output transistor to conduct, pulling the output LOW.
If You don't like this use code like this:

Reading_OptoSignal = !analogRead(OptoSignalIn);

Note the negating character !

Yes
There is an inversion in the optocoupler.

image


Reading_OptoSignal = analogRead(OptoSignalIn);
Use
Reading_OptoSignal = digitalRead(OptoSignalIn);

This won't work because analogRead() of a collector voltage can not normally be 0.

Optocouplers are not designed for transmission of analog signals. Use digitalRead() to obtain the logic state.

Yes of course. Use digital read or check for values above or below 512...

The lovely thing about the photo-transistor's output performance is that it works equally well as a high-side or low-side switch. However, this won't invert the output signal. To invert, you could connect:

  • Vcc→IRLED→Resistor→Arduino Output or
  • Vcc→Resistor→IRLED→Arduino Output

Similar to hoe the relay modules work. The Digital Output needs to be LOW to turn on your LED.