PyRaspBeta

Optocoupler

An optocoupler puts a light beam where a wire would be: an infrared LED and a phototransistor sit in one package with no electrical connection between them. It costs $0.30 and does two jobs at once — it passes a signal across a barrier (a different voltage domain, a noisy motor circuit, mains), and it converts current into current. Drive the input LED and the output transistor conducts; stop, and it lets go. The two sides never share a conductor, so a fault on one cannot reach the other.

Optocoupler (PC817)

Pins

PinWhat it isType
AAnode (+, input LED)passive
KCathode (−, input LED)passive
CCollector (output)passive
EEmitter (output)passive
  • Optocoupler() — Optocoupler (PC817) — $0.30
  • Pins: 4
  • Aliases: anode → A, cathode → K, collector → C, emitter → E

A/K are the input LED: about 1.2 V across it, driven through a series resistor like any LED. C/E are the output phototransistor: its collector current is the input current times the current transfer ratio (100 % in this model, 50–600 % on real parts), so a few milliamps in can switch a few milliamps out. The output still needs a load — a pull-up resistor on the collector is the usual one.

Wiring it in circuit.py

A GPIO driving the input, and the isolated side read back on another pin:

circuit.py
from wiring import *

pi = Pi()
opto = Optocoupler()
r1 = Resistor(330)          # input: about 6 mA through the infrared LED
r2 = Resistor(10000)        # output pull-up; the opto pulls the pin low when lit

pi.GPIO17 >> r1 >> opto.anode
opto.cathode >> pi.GND

pi.V3_3 >> r2 >> opto.collector
opto.emitter >> pi.GND
opto.collector >> pi.GPIO27

The anode/cathode/collector/emitter aliases are A/K/C/E. The output side could just as well run from 5 V, or from a supply the Pi knows nothing about: the only thing crossing the gap is light.

Driving it in main.py

main.py
from gpiozero import Button, OutputDevice
from time import sleep

drive = OutputDevice(17)
sensed = Button(27)   # internal pull-up: the opto pulls the pin low when its LED is lit

while True:
    drive.on()
    sleep(0.2)
    print("isolated side:", "lit" if sensed.is_pressed else "dark")
    drive.off()
    sleep(0.2)
    print("isolated side:", "lit" if sensed.is_pressed else "dark")

Electrical notes

  • The model's input is a real infrared LED junction: about 1.2 V at 6 mA through 330 Ω from 3.3 V. Its current is what the output transistor sees, scaled by the transfer ratio.
  • The output is a phototransistor, so it behaves like a transistor with no base pin: it saturates (a few tens of millivolts) when the light is strong, and in between it is a current source — that in-between region is what makes optos useful for analogue signals too.
  • Isolation is a property of the package, not the model's numbers: no element connects A/K to C/E, so the simulator can never leak current across the gap.
  • Real parts specify the transfer ratio at a given input current and degrade with age; the model keeps one figure for the whole range.

Simulator vs real hardware

  • A real PC817 is rated 50 mA on each side. The model warns at the ratings of the parts inside it — the 5 mm LED (30 mA) and the 2N3904 (200 mA, 0.625 W) — and with burn out on it damages them.
  • Real optos are slow — tens of microseconds — which matters for fast signals; the model switches instantly, so it is not the part to learn switching speed from.
  • The light is invisible: the model's LED colour is the infrared one, so nothing glows on the board. That is what the part looks like in real life too.