Bauteile · 12 Min. Lesezeit

Optokoppler: Funktion, PC817 und 4N35 am Arduino erklärt

Wie funktioniert ein Optokoppler? PC817- und 4N35-Pinbelegung, CTR und Widerstand berechnen, 12/24-V-Signale lesen, Netzspannung erkennen (H11AA1), Relais.

Ein Optokoppler (auch Optoisolator genannt) ist ein kleiner Baustein, der ein Signal zwischen zwei Schaltungen nur mit Licht überträgt, ohne elektrische Verbindung zwischen ihnen. Im Inneren sitzen eine Infrarot-LED und ein Fototransistor, der ihr gegenübersteht: Schaltet die Schaltung auf der einen Seite die LED ein, leitet der Transistor auf der anderen Seite. Weil zwischen beiden Seiten kein einziger Draht liegt, können Spannungsspitzen und Störungen deinen Mikrocontroller nicht erreichen, wenn du einen 24-V-Industriesensor, das 12-V-Bordnetz eines Autos oder einen Motortreiber an deinen Arduino anschließt.

In diesem Beitrag lernst du Schritt für Schritt, was in einem Optokoppler steckt, warum galvanische Trennung wichtig ist, die Pins und Kennwerte der beiden häufigsten Typen PC817 und 4N35, den Begriff CTR und die Widerstandsberechnung. Danach siehst du, wie du einen Arduino-Ausgang trennst, 12/24-V-Signale sicher liest, den Optokoppler mit ESP32 und Raspberry Pi Pico nutzt, welche Sicherheitsregeln bei der Netzspannungserkennung (H11AA1) gelten, wie der Optokoppler in Relaismodulen arbeitet und wie du mit dem MOC3021 einen Triac ansteuerst.

Was ist ein Optokoppler und wie funktioniert er?

Im Gehäuse eines Optokopplers sitzen zwei Chips, die sich gegenüberstehen. Auf der Eingangsseite befindet sich eine Infrarot-LED, die wie eine normale LED mit Strom betrieben wird. Auf der Ausgangsseite liegt ein Fototransistor, dessen Basis lichtempfindlich ist; statt Strom in die Basis zu schicken, fällt Licht darauf. Zwischen den beiden Chips liegt eine durchsichtige, aber elektrisch isolierende Kunststoffschicht. Diese Schicht ist so ausgelegt, dass sie Tausende Volt aushält.

  1. Die Schaltung auf der Eingangsseite schickt über einen Widerstand einige Milliampere durch die LED.
  2. Die LED sendet Infrarotlicht aus; dieses Licht durchquert die Isolierschicht und fällt auf den Fototransistor.
  3. Das Licht wirkt wie der Basisstrom des Fototransistors und lässt Strom zwischen Kollektor und Emitter fließen; der Transistor schließt wie ein Schalter.
  4. Geht die LED aus, endet das Licht, der Transistor sperrt wieder und der Ausgangskreis öffnet. Das Signal ist ohne Draht, nur mit Licht, auf die andere Seite gelangt.

Je nachdem, was auf der Ausgangsseite sitzt, gibt es verschiedene Optokoppler-Typen. In Hobbyprojekten werden meist Typen mit Fototransistor verwendet; zum Erkennen von Wechselspannung, zum Zünden eines Triacs oder zum Trennen schneller Datenleitungen brauchst du aber spezielle Typen:

TypBeispieleAusgangTypische Anwendung
Mit FototransistorPC817, EL817, 4N35, 4N25NPN-FototransistorDigitale Signaltrennung, 12/24-V-Eingänge lesen, Relaismodule
Darlington-Ausgang4N33, H11B1Darlington-TransistorHoher Ausgangsstrom bei sehr kleinem LED-Strom (aber langsamer)
WechselspannungseingangH11AA1, PC814Zwei antiparallele LEDs + FototransistorNetzspannung erkennen, Nulldurchgangserkennung
Triac-AusgangMOC3021, MOC3041, MOC3063FototriacTriac zünden, AC-Lasten schalten, SSRs
Schnelle Logik6N137, 6N138Fotodiode + Logikgatter oder TransistorMIDI, UART und schnelle digitale Leitungen trennen

Warum braucht man galvanische Trennung?

Galvanische Trennung bedeutet, dass es zwischen zwei Schaltungen keinen direkten leitenden Pfad gibt: keine gemeinsame Masse, kein gemeinsamer Draht, Energie und Information werden auf anderem Weg (Licht, Magnetfeld) übertragen. Arduino-Pins vertragen höchstens 5 V (beim ESP32 und Pico 3,3 V). Die 24 V eines Industriesensors, die kurzen Spitzen von Hunderten Volt, die ein Motor beim Schalten erzeugt, oder in lange Kabel eingekoppelte Störungen können über eine gemeinsame Masse direkt bis zum Mikrocontroller gelangen. Der Optokoppler unterbricht diesen Weg physisch.

  • Schutz: Selbst wenn auf der Hochspannungsseite etwas ausfällt, bleibt der Schaden im Optokoppler; Arduino, der USB-Port deines Rechners und du bleiben sicher.
  • Störungen und Masseschleifen: Motoren, Relais und lange Kabel erzeugen Störungen auf der Masseleitung. Sind die Massen getrennt, gelangen diese Störungen nicht in die Signalleitung; das Thema gemeinsame Masse erklären wir ausführlich im Beitrag GND und gemeinsame Masse.
  • Unterschiedliche Spannungspegel: Weil der Ausgangstransistor von außen versorgt wird, wird aus einem 24-V-Signal leicht 3,3 V und aus einem 5-V-Signal 12 V. Ein Optokoppler ist also auch ein langsamer, aber robuster Pegelwandler.
  • Sicherheitsnormen: Bei netzbetriebenen Geräten muss die Benutzerseite vom Netz getrennt sein; Bauteile wie der PC817 bestehen eine Isolationsprüfung mit 5000 V eff.
Die Trennung funktioniert nur, solange die Massen beider Seiten getrennt bleiben. Verbindest du den Minuspol der 24-V-Seite "sicherheitshalber" mit der Arduino-Masse, ist der Optokoppler nur noch ein teures Stück Draht und der Schutz ist komplett weg. Lass die Eingangsseite von ihrer eigenen Quelle und die Ausgangsseite vom Arduino versorgen.

PC817 und 4N35: Pinbelegung und Kennwerte

PinPC817 (DIP-4)4N35 (DIP-6)
1Anode (LED +)Anode (LED +)
2Kathode (LED −)Kathode (LED −)
3EmitterNicht belegt
4KollektorEmitter
5KeinerKollektor
6KeinerBasis (meist offen gelassen)
KennwertPC8174N35
LED-Flussspannung (VF)Typ. 1,2 V, max. 1,4 V (bei 20 mA)Etwa 1,2–1,3 V
Maximaler LED-Strom50 mA60 mA
LED-SperrspannungMax. 6 VMax. 6 V
CTR50–600 % (bei 5 mA, 5 V; je nach Klasse)Mindestens 100 % (bei 10 mA, 10 V)
Kollektor-Emitter-Spannung (VCEO)35 V70 V
KollektorstromMax. 50 mAMax. 50 mA
SchaltzeitTyp. 3–4 µs (mit kleinem Lastwiderstand)Etwa 10 µs
Isolationsspannung5000 V eff5000 V eff

Beim PC817 ist Pin 1 mit einem Punkt markiert; der Buchstabe A, B, C oder D nach "PC817" auf dem Gehäuse gibt die CTR-Klasse an. Bauteile wie EL817, LTV817 und KP1010 sind pinkompatible Alternativen zum PC817. Der 4N35 hat sechs Beine, deshalb ist sein Basisanschluss herausgeführt; meist lässt du ihn offen, in sehr störungsreicher Umgebung kann ein hochohmiger Widerstand (z. B. 1 MΩ) zwischen Basis und Emitter das Abschalten beschleunigen.

Was ist CTR und wie berechnet man die Widerstände?

CTR (Current Transfer Ratio, Stromübertragungsverhältnis) ist das Verhältnis des Kollektorstroms, den der Ausgangstransistor führen kann, zum LED-Strom: CTR = IC / IF × 100 %. Bei einem Optokoppler mit 100 % CTR kannst du zum Beispiel bei 5 mA durch die LED höchstens etwa 5 mA am Ausgang entnehmen. Die CTR ändert sich mit der Temperatur, sinkt über die Jahre durch Alterung der LED und schwankt selbst zwischen Bauteilen desselben Typs stark. Deshalb legst du die Schaltung immer auf den kleinsten Wert im Datenblatt aus.

PC817-KlasseCTR-Bereich (IF = 5 mA)Ausgangsstrom bei 5 mA LED-Strom
PC817A80–160 %4–8 mA
PC817B130–260 %6,5–13 mA
PC817C200–400 %10–20 mA
PC817D300–600 %15–30 mA
Ohne Buchstabe50–600 %2,5–30 mA (vom schlechtesten Fall ausgehen)

LED-Vorwiderstand: Die Eingangsseite wird genau wie eine LED berechnet: R = (UVersorgung − VF) / IF. Für 10 mA aus dem 5-V-Pin eines Arduino Uno ergibt sich (5 − 1,2) / 0,010 = 380 Ω; ein üblicher 330-Ω-Widerstand liefert etwa 11,5 mA, 390 Ω etwa 9,7 mA. Beim ESP32 ergibt (3,3 − 1,2) / 0,010 = 210 Ω, du nimmst also 220 Ω. Die Pins des Raspberry Pi Pico sind standardmäßig auf 4 mA Treiberstärke eingestellt; hier reichen etwa 4,5 mA mit 470 Ω. Wenn du nicht von Hand rechnen willst, nutze das Werkzeug LED-Vorwiderstand.

Ausgangswiderstand (Pull-up): Damit der Transistor voll durchschaltet (in die Sättigung geht), muss der vom Pull-up gezogene Strom kleiner sein, als die CTR zulässt. Ein 10-kΩ-Pull-up an 5 V braucht nur 0,5 mA. Bei einem PC817 ohne Buchstaben beträgt die schlechteste CTR 50 %, also würden für 0,5 mA schon 1 mA durch die LED reichen; mit 5–10 mA lässt du mindestens fünffache Reserve. Auch der interne Pull-up des Arduino (etwa 20–50 kΩ) ist dafür ideal. Ein kleinerer Pull-up macht das Signal schneller, braucht aber mehr Strom; ein größerer braucht weniger Strom, lässt den Transistor aber langsamer abschalten.

FallVersorgungsspannungZiel-LED-StromEmpfohlener WiderstandWiderstandsleistung
Ansteuerung von einem Arduino-Uno-Pin5 V~10 mA330 Ω1/4 W reicht
Ansteuerung von einem ESP32-Pin3,3 V~10 mA220 Ω1/4 W reicht
Ansteuerung von einem Raspberry-Pi-Pico-Pin3,3 V~4,5 mA470 Ω1/4 W reicht
12-V-Signal lesen12 V~5 mA2,2 kΩ1/4 W (verbraucht 0,05 W)
24-V-Signal lesen24 V~5 mA4,7 kΩ1/4 W (verbraucht 0,11 W)
Musst du am selben Eingang sowohl 12 V als auch 24 V lesen, wähle 4,7 kΩ: Bei 24 V fließen etwa 4,8 mA, bei 12 V etwa 2,3 mA. Selbst mit 50 % CTR liegen 2,3 mA weit über den 0,1–0,25 mA, die der interne Pull-up braucht; dieselbe Schaltung arbeitet bei beiden Spannungen zuverlässig.

Anschlusstabelle: Arduino Uno, ESP32 und Raspberry Pi Pico

PC817-PinAufgabeArduino UnoESP32Raspberry Pi Pico
1 (Anode), Ausgang trennenDas Board treibt die LEDD9 → 330 Ω → Pin 1GPIO 25 → 220 Ω → Pin 1GP15 → 470 Ω → Pin 1
2 (Kathode), Ausgang trennenLED-RückleitungGNDGNDGND
4 (Kollektor), Eingang lesenDas Board liest das SignalD2 (INPUT_PULLUP)GPIO 27 (INPUT_PULLUP)GP14 (PULL_UP)
3 (Emitter), Eingang lesenGND der LeseseiteGNDGNDGND
1 und 2, Eingang lesenExternes Signal (12/24 V)An die externe Quelle, nicht ans BoardAn die externe Quelle, nicht ans BoardAn die externe Quelle, nicht ans Board
Der häufigste Fehler ist, die LED ohne Vorwiderstand anzuschließen: 5 V direkt an Pin 1 und 2 zerstören die LED in Sekunden. Der zweithäufigste ist ein verdreht eingesetztes Bauteil; die LED verträgt in Sperrrichtung nur 6 V, 12 V oder 24 V falsch herum zerstören sie. Eine 1N4148-Diode in Sperrrichtung (Kathode an Anode) parallel zum Eingang beseitigt dieses Risiko.

Einen Arduino-Ausgang galvanisch trennen

Hier schaltet der Arduino die LED des Optokopplers, und der Ausgangstransistor schließt den Eingang einer anderen Schaltung wie ein Schalter kurz. So kannst du zum Beispiel den "Trigger"-Eingang eines 12-V-Geräts, den Fernauslöser-Eingang einer Kamera, einen SPS-Eingang oder einen anderen Mikrocontroller mit anderer Spannung sicher ansteuern. Weil der Ausgangstransistor auf 35 V und 50 mA begrenzt ist, kann er keine Relaisspule, keinen Motor und keinen LED-Streifen direkt treiben; für solche Lasten setzt du auf der anderen Seite einen Transistor oder einen MOSFET ein.

C++ (Arduino IDE)
1// PC817 ile yalıtılmış çıkış / Isolated output with a PC817
2// D9 -> 330 ohm -> PC817 pin 1 (anot / anode), pin 2 (katot / cathode) -> Arduino GND
3// Pin 4 ve 3 diğer devrenin girişini kısa devre eder (kuru kontak gibi)
4// Pins 4 and 3 short the other circuit's input (like a dry contact)
5const int OPTO_LED_PIN = 9;
6const unsigned long ON_MS = 2000;
7const unsigned long OFF_MS = 3000;
8
9bool isOn = false;
10unsigned long lastSwitch = 0;
11
12void setup() {
13  pinMode(OPTO_LED_PIN, OUTPUT);
14  digitalWrite(OPTO_LED_PIN, LOW);
15}
16
17void loop() {
18  unsigned long waitTime = isOn ? ON_MS : OFF_MS;
19  if (millis() - lastSwitch >= waitTime) {
20    lastSwitch = millis();
21    isOn = !isOn;
22    digitalWrite(OPTO_LED_PIN, isOn ? HIGH : LOW);   // HIGH: optokuplör iletir / HIGH: optocoupler conducts
23  }
24}

Auf der Ausgangsseite verbindest du den Kollektor (Pin 4) mit der Plusseite bzw. dem Eingang der anderen Schaltung und den Emitter (Pin 3) mit deren GND; bei vertauschter Polung leitet der Transistor nicht. Weil ein PC817 zum Ein- und Ausschalten einige bis einige zehn Mikrosekunden braucht, wird ein durchgeleitetes PWM-Signal oberhalb einiger kHz verzerrt. Für schnelle Signale (UART, MIDI, hochfrequente PWM) nimmst du schnelle Optokoppler wie den 6N137 oder digitale Isolator-ICs.

12/24-V-Signale sicher lesen

Signale von induktiven Industriesensoren, SPS-Ausgängen, Türkontakten, dem Zündschloss eines Autos oder einem 12-V-Klingeltaster kannst du nicht direkt an einen Arduino-Pin anschließen. Die Lösung: Du schickst das Signal durch die LED des Optokopplers. Für 24 V kommt ein 4,7-kΩ-Widerstand in Reihe zur LED, für 12 V ein 2,2-kΩ-Widerstand; der Ausgangstransistor arbeitet mit dem internen Pull-up des Arduino. Liegt Spannung an, leuchtet die LED, der Transistor leitet und der Arduino-Pin liest LOW. Die Logik ist also invertiert; das berücksichtigst du im Code.

  1. Verbinde den Pluspol der 24-V-Quelle über einen 4,7-kΩ-Widerstand mit Pin 1 (Anode) des PC817.
  2. Verbinde den Minuspol der Signalquelle (24-V-GND) mit Pin 2 (Kathode). Diese Masse nicht mit dem Arduino verbinden.
  3. Setze optional eine 1N4148-Diode in Sperrrichtung zwischen Pin 1 und 2 (Kathode an Pin 1); sie schützt vor Verpolung.
  4. Verbinde Pin 4 (Kollektor) des PC817 mit Pin D2 des Arduino und Pin 3 (Emitter) mit Arduino-GND.
  5. Lade den Code unten hoch und öffne den Seriellen Monitor mit 9600 Baud. Legst du 24 V an, solltest du "24V VAR / present" sehen.
C++ (Arduino IDE)
1// PC817 ile 12/24 V sinyal okuma / Reading a 12/24 V signal with a PC817
2// PC817 pin 4 (kolektör / collector) -> D2, pin 3 (emetör / emitter) -> Arduino GND
3const int OPTO_PIN = 2;
4const unsigned long DEBOUNCE_MS = 20;    // kontak sıçramasına karşı / against contact bounce
5
6int lastReading = HIGH;
7int stableState = HIGH;
8unsigned long lastChange = 0;
9unsigned long pulseCount = 0;
10
11void setup() {
12  Serial.begin(9600);
13  pinMode(OPTO_PIN, INPUT_PULLUP);       // dahili pull-up yeterli / internal pull-up is enough
14}
15
16void loop() {
17  int reading = digitalRead(OPTO_PIN);
18  if (reading != lastReading) {          // değişim var, zamanı başlat / change seen, start the timer
19    lastChange = millis();
20    lastReading = reading;
21  }
22  if (millis() - lastChange > DEBOUNCE_MS && reading != stableState) {
23    stableState = reading;
24    // Mantık ters: 24 V varsa LED yanar, transistör iletir, pin LOW olur
25    // Inverted logic: with 24 V present the LED is on, the transistor conducts, the pin reads LOW
26    if (stableState == LOW) {
27      pulseCount++;
28      Serial.print("24V VAR / present, sayac / count: ");
29      Serial.println(pulseCount);
30    } else {
31      Serial.println("24V YOK / absent");
32    }
33  }
34}

Der Code enthält ein einfaches Entprellen, das nur Werte akzeptiert, die 20 ms lang unverändert bleiben; bei Signalen von mechanischen Kontakten oder Relais ist das Pflicht. Weil wir mit millis() statt delay() lesen, kann der Arduino nebenbei andere Aufgaben erledigen. Im Bordnetz eines Autos steigt die 12-V-Leitung bei laufendem Motor auf 14,4 V, und es treten kurze, hohe Spitzen auf; hier ist es eine gute Vorsichtsmaßnahme, den Widerstand auf 3,3 kΩ zu erhöhen und am Eingang eine TVS-Diode einzusetzen.

Optokoppler mit ESP32 und Raspberry Pi Pico

Weil ESP32 und Pico mit 3,3 V arbeiten, dürfen sie nicht einmal direkt an 5-V-Signale angeschlossen werden. Das Schöne am Optokoppler: Der Ausgangstransistor ist ein offener Kollektor, die Ausgangsspannung bestimmt also allein die Spannung, an der der Pull-up hängt. Mit dem internen Pull-up bleibt der Ausgang automatisch bei 3,3 V; selbst wenn auf der Eingangsseite 24 V anliegen, erreichen den ESP32 höchstens 3,3 V. Der folgende ESP32-Code zählt per Interrupt die Impulse eines induktiven 24-V-Sensors oder Durchflussmessers:

C++ (Arduino IDE)
1// ESP32: 24 V endüstriyel sensörden darbe sayma / counting pulses from a 24 V industrial sensor
2// PC817 pin 4 -> GPIO 27, pin 3 -> ESP32 GND
3const int OPTO_PIN = 27;
4
5volatile unsigned long pulseCount = 0;
6volatile unsigned long lastPulseUs = 0;
7
8void IRAM_ATTR onPulse() {
9  unsigned long now = micros();
10  if (now - lastPulseUs > 2000) {        // 2 ms'den kısa parazitleri yok say / ignore glitches shorter than 2 ms
11    pulseCount++;
12    lastPulseUs = now;
13  }
14}
15
16void setup() {
17  Serial.begin(115200);
18  pinMode(OPTO_PIN, INPUT_PULLUP);
19  attachInterrupt(digitalPinToInterrupt(OPTO_PIN), onPulse, FALLING);   // 24 V gelince pin düşer / pin falls when 24 V arrives
20}
21
22void loop() {
23  static unsigned long lastPrint = 0;
24  if (millis() - lastPrint >= 1000) {
25    lastPrint = millis();
26    noInterrupts();
27    unsigned long count = pulseCount;
28    pulseCount = 0;
29    interrupts();
30    Serial.printf("Saniyedeki darbe / Pulses per second: %lu\n", count);
31  }
32}

Das IRAM_ATTR vor der Interrupt-Funktion legt den Code in den schnellen Speicher; beim ESP32 wird es für Interrupt-Funktionen empfohlen. Der 2-ms-Filter entfernt falsche Impulse, die durch das langsame Abschalten des Optokopplers oder Kabelstörungen entstehen. Mehr zu Interrupts findest du im Beitrag Arduino Interrupt. Auf dem Raspberry Pi Pico erledigst du das Gleiche mit MicroPython so; dieses Beispiel liest den Eingang und sendet zusätzlich über einen zweiten PC817 ein getrenntes Signal auf die andere Seite:

MicroPython
1# Raspberry Pi Pico: PC817 ile yalıtılmış giriş / isolated input with a PC817
2# PC817 pin 4 -> GP14, pin 3 -> Pico GND, LED sürme / LED drive: GP15 -> 470 ohm -> pin 1
3from machine import Pin
4import time
5
6opto_in = Pin(14, Pin.IN, Pin.PULL_UP)     # dahili pull-up / internal pull-up
7opto_out = Pin(15, Pin.OUT)                # ikinci PC817'nin LED'i / LED of a second PC817
8
9last_state = opto_in.value()
10while True:
11    state = opto_in.value()
12    if state != last_state:
13        time.sleep_ms(20)                  # sıçramayı bekle / wait out the bounce
14        state = opto_in.value()
15        if state != last_state:
16            last_state = state
17            if state == 0:                 # ters mantık: 0 = gerilim var / inverted: 0 = voltage present
18                print("24V VAR / present")
19                opto_out.value(1)          # karşı tarafa yalıtılmış sinyal / isolated signal to the other side
20            else:
21                print("24V YOK / absent")
22                opto_out.value(0)
23    time.sleep_ms(5)

Netzspannung erkennen: H11AA1 und Sicherheit

230 V Netzspannung ist lebensgefährlich. Wenn du keine Erfahrung hast, baue keine netzverbundene Schaltung selbst; nutze fertige, gekapselte und zertifizierte AC-Erkennungsmodule. Stecke die Netzseite nie auf ein Steckbrett, berühre nichts, solange die Schaltung unter Spannung steht, und baue die gesamte Schaltung zusammen mit einer Sicherung in ein isolierendes Gehäuse.

Um zu erkennen, ob eine Steckdose oder ein Lampenkreis Spannung führt, oder um die Nulldurchgänge des Netzes zu finden, nutzt man Optokoppler mit Wechselspannungseingang wie den H11AA1. Im Inneren sitzen zwei antiparallel geschaltete LEDs; deshalb erzeugt er in beiden Halbwellen Licht und hat kein Problem mit Sperrspannung. Für 230 V eff kommen zwei 47-kΩ-Widerstände in Reihe zum Eingang: Durch die insgesamt 94 kΩ fließen etwa 2,4 mA eff (3,5 mA im Scheitelwert), und jeder Widerstand setzt etwa 0,28 W um. Deshalb wählst du mindestens 0,5-W-, besser 1-W-Widerstände; zwei Widerstände halbieren außerdem die Spannung an jedem einzelnen. Auf der Ausgangsseite leitet der Transistor mit einem 10-kΩ-Pull-up an 5 V die meiste Zeit, solange Spannung anliegt; nur in der Nähe der Nulldurchgänge, wenn die LEDs dunkel werden, entsteht ein kurzer HIGH-Impuls. Am 50-Hz-Netz siehst du etwa 100 Impulse pro Sekunde.

C++ (Arduino IDE)
1// H11AA1 ile şebeke gerilimi var mı? / Is mains voltage present? (H11AA1)
2// H11AA1 pin 5 (kolektör / collector) -> D2, pin 4 (emetör / emitter) -> GND, 10k pull-up -> 5V
3const int AC_PIN = 2;
4const unsigned long TIMEOUT_MS = 40;     // 50 Hz'de 2 tam periyot / 2 full cycles at 50 Hz
5
6volatile unsigned long pulses = 0;
7unsigned long lastLowSeen = 0;
8unsigned long lastReport = 0;
9
10void onZeroCross() {
11  pulses++;                              // her sıfır geçişinde bir darbe / one pulse per zero crossing
12}
13
14void setup() {
15  Serial.begin(9600);
16  pinMode(AC_PIN, INPUT);                // harici 10k pull-up kullanılıyor / external 10k pull-up in use
17  attachInterrupt(digitalPinToInterrupt(AC_PIN), onZeroCross, RISING);
18}
19
20void loop() {
21  if (digitalRead(AC_PIN) == LOW) {
22    lastLowSeen = millis();              // gerilim varken çıkış çoğunlukla LOW / output is mostly LOW while voltage is present
23  }
24  bool mainsOn = (millis() - lastLowSeen) < TIMEOUT_MS;
25
26  if (millis() - lastReport >= 1000) {   // saniyede bir rapor / report once per second
27    lastReport = millis();
28    noInterrupts();
29    unsigned long count = pulses;
30    pulses = 0;
31    interrupts();
32    Serial.print(mainsOn ? "Sebeke VAR / Mains ON" : "Sebeke YOK / Mains OFF");
33    Serial.print("  sifir gecisi / zero crossings: ");
34    Serial.print(count);                 // 50 Hz'de yaklaşık 100 / about 100 at 50 Hz
35    Serial.print("  frekans / frequency: ");
36    Serial.print(count / 2);
37    Serial.println(" Hz");
38  }
39}

Der Code liefert zwei Informationen: War der Ausgang in den letzten 40 ms mindestens einmal LOW, liegt Netzspannung an; und die Hälfte der per Interrupt gezählten Impulse ergibt die Netzfrequenz. Darauf solltest du bei fertigen Modulen und auf deiner eigenen Platine achten: Lass zwischen den Netzleiterbahnen und der Niederspannungsseite mindestens 6–8 mm Abstand (Kriechstrecke), setze eine Sicherung in den Netzeingang, führe nie eine Leiterbahn zwischen den beiden Seiten des Optokopplers hindurch und betreibe die Schaltung nur in einem geschlossenen Gehäuse.

Der Optokoppler im Relaismodul und der JD-VCC-Jumper

Relaismodul mit Optokoppler-Eingang
Viele Relaismodule haben auf der Eingangsseite einen PC817-Optokoppler; für eine vollständige Trennung musst du den JD-VCC-Jumper entfernen.

Die meisten 1-, 2-, 4- und 8-Kanal-Relaismodule auf dem Markt haben am Eingang jedes Kanals einen PC817. Der Strom vom VCC-Pin fließt über einen Widerstand und eine Anzeige-LED zur LED des Optokopplers; wird der IN-Pin auf LOW gezogen, schließt sich der Stromkreis und das Relais zieht an. Deshalb arbeiten diese Module meist Low-aktiv. Im Auslieferungszustand steckt jedoch der JD-VCC-Jumper, und die Relaisspule wird aus demselben VCC und GND versorgt: Der Optokoppler ist da, eine Trennung gibt es aber nicht. Die Grundlagen zu Relaismodulen findest du im Beitrag Was ist ein Relaismodul?.

EinstellungVerdrahtungTrennung
JD-VCC-Jumper gestecktArduino 5V → VCC, GND → GND, Pin → INKeine; Störungen der Relaisspule gelangen in die Versorgung des Arduino
Jumper entferntArduino 5V → VCC, Pin → IN; Arduino-GND wird nicht verbunden. Separate 5-V-Quelle → JD-VCC und GNDVollständig; beide Seiten teilen nur das Licht im Optokoppler

Hinweis: Triac ansteuern mit dem MOC3021

Willst du statt eines Relais einen lautlosen, funkenfreien AC-Schalter, nimmst du einen Triac (z. B. BT136) und einen Optokoppler mit Triac-Ausgang zur Ansteuerung. Der MOC3021 ist phasenunabhängig (Random Phase): Er zündet den Triac in dem Moment, in dem die LED leuchtet, und eignet sich daher zusammen mit einer Nulldurchgangserkennung für einen Dimmer. MOC3041 und MOC3063 haben eine Nulldurchgangsschaltung; sie zünden nur, wenn die Spannung durch null geht, erzeugen beim Ein- und Ausschalten weniger Störungen, eignen sich aber nicht zum Dimmen. Die LED des MOC3021 kann bis zu 15 mA zum Zünden brauchen; bei 5 V ist 220 Ω (etwa 17 mA) ein passender Wert, 330 Ω kann bei manchen Exemplaren zu wenig sein. Wie in den Datenblättern kommt zwischen Triac-Gate und MOC3021 ein Widerstand von etwa 360 Ω, bei induktiven Lasten wie Motoren zusätzlich ein RC-Snubber über den Triac. Fertige SSR-Module (Halbleiterrelais) enthalten genau diesen Aufbau.

Projektideen mit Optokopplern

  • Industriesensor-Leser: Zähle mit einem induktiven 24-V-Näherungssensor Teile auf einem Förderband und zeige die Zahl auf einem LCD an.
  • Zündungserkennung im Auto: Wecke den ESP32, wenn die Zündung eingeschaltet wird, und starte die Autokamera oder einen Datenlogger.
  • Stromausfall-Alarm: Lass mit einem fertigen AC-Erkennungsmodul einen Summer ertönen oder eine Nachricht aufs Handy senden, wenn das Netz ausfällt.
  • Türklingel-Erkennung: Lies die vorhandene 12-V-Klingelleitung galvanisch getrennt aus und sende eine Benachrichtigung, wenn es klingelt.
  • Getrennte Relaisplatine: Schalte eine 230-V-Lampe mit einem Relaismodul, dessen JD-VCC-Jumper du entfernt hast und das du aus einer separaten Quelle versorgst.
  • MIDI-Eingang: Lies mit einem 6N138 MIDI-Noten eines elektronischen Instruments am Arduino ein.

Häufige Fehler und Lösungen

SymptomWahrscheinliche UrsacheLösung
Der Ausgang ändert sich nieLED verpolt oder ohne Vorwiderstand angeschlossen und durchgebranntPrüfen, ob Pin 1 der mit dem Punkt ist; die LED im Diodenmessbereich des Multimeters testen
Die Logik arbeitet invertiertBei anliegender Spannung geht der Pin auf LOW; das ist normalLOW im Code als "Spannung vorhanden" auswerten
Der Ausgang geht nicht ganz auf LOW (bleibt bei 1–2 V)LED-Strom zu klein, CTR reicht nicht oder Pull-up zu kleinLED-Vorwiderstand verkleinern oder Pull-up vergrößern (z. B. 10 kΩ)
Das PWM-Signal wird verzerrtDer PC817 ist oberhalb einiger kHz zu langsamPull-up verkleinern oder einen schnellen Optokoppler wie den 6N137 nehmen
Der Arduino startet trotz Trennung neuDie Massen beider Seiten wurden verbundenGND der Eingangsseite vom Arduino trennen; beim Relaismodul den JD-VCC-Jumper entfernen
Zufällige FehlauslösungenLanges Kabel, Störungen, prellende KontakteIn Software entprellen, Kabel kürzen, 100-nF-Kondensator parallel zur LED
So testest du einen Optokoppler am einfachsten: Versorge die LED-Seite mit 5 V über 330 Ω und schließe ein Multimeter im Widerstandsbereich zwischen Kollektor und Emitter an. Leuchtet die LED, solltest du einen kleinen Widerstand sehen, ist sie aus, einen sehr großen. Mit diesem einfachen Test findest du ein defektes Bauteil, bevor es in die Schaltung kommt.

Ein Optokoppler ist der günstigste Weg, ein Arduino-Projekt vom Schreibtisch zu holen und es sicher mit den 12-V-, 24-V- und 230-V-Signalen der echten Welt sprechen zu lassen: Ein Bauteil für wenige Cent trennt dein Board und deinen Rechner von der Hochspannung. In der BlueGrays-App findest du die Projekte zum Schalten einer 230-V-Lampe mit Relais, zur intelligenten Beleuchtung und zur Bewässerung, Schritt für Schritt mit Schaltplan und Code.

Häufige Fragen

Wofür braucht man einen Optokoppler?

Ein Optokoppler überträgt ein Signal zwischen zwei Schaltungen mit Licht, ganz ohne elektrische Verbindung. So trennt er eine Hochspannungs- oder störungsreiche Schaltung von einem empfindlichen Mikrocontroller wie dem Arduino. Er wird zum Lesen von Industriesensoren, in Relaismodulen und in Schaltungen zur Netzspannungserkennung eingesetzt.

Wie ist die Pinbelegung des PC817?

Der PC817 hat vier Beine: Pin 1 an der Ecke mit dem Punkt ist die Anode der LED, Pin 2 die Kathode. Auf der gegenüberliegenden Seite ist Pin 3 der Emitter und Pin 4 der Kollektor des Fototransistors.

Welchen Vorwiderstand braucht ein Optokoppler?

Der Widerstand ergibt sich aus R = (Versorgungsspannung − 1,2 V) / LED-Strom. Gute Startwerte sind 330 Ω für einen 5-V-Arduino-Pin, 220 Ω für einen ESP32, 2,2 kΩ für ein 12-V-Signal und 4,7 kΩ für ein 24-V-Signal.

Was bedeutet CTR beim Optokoppler?

CTR (Stromübertragungsverhältnis) ist das Verhältnis des Stroms, den der Ausgangstransistor führen kann, zum LED-Strom. Bei einem Optokoppler mit 100 % CTR kannst du bei 5 mA LED-Strom höchstens etwa 5 mA am Ausgang entnehmen. Lege die Schaltung immer auf die kleinste CTR im Datenblatt aus.

Was ist der Unterschied zwischen PC817 und 4N35?

Beide sind Optokoppler mit Fototransistor-Ausgang. Der PC817 hat vier Beine, ist günstig und hat je nach Klasse eine CTR von 50–600 %. Der 4N35 hat sechs Beine, führt den Basisanschluss heraus und verträgt Kollektorspannungen bis 70 V.

Kann ein Optokoppler 230 V Netzspannung erkennen?

Ja, mit Optokopplern mit Wechselspannungseingang wie dem H11AA1 und ausreichend belastbaren Vorwiderständen lassen sich Netzspannung und Nulldurchgänge erkennen. Netzspannung ist aber lebensgefährlich; ohne Erfahrung solltest du fertige, gekapselte AC-Erkennungsmodule verwenden.

Alle Projekte ansehen
220V Glühbirne mit Druckknopf (Push)
#19Fortgeschritten
Premium

220V Glühbirne mit Druckknopf (Push)

Solange du den Knopf gedrückt hältst, leuchtet eine echte 220-Volt-Glühbirne, und sobald du loslässt, geht sie aus. Das schwache Signal des Arduino kann die Birne nicht direkt einschalten, deshalb sit

4.4(30)
38
220-V-Glühbirne mit Taster ein- und ausschalten
#20Fortgeschritten
Premium

220-V-Glühbirne mit Taster ein- und ausschalten

Willst du eine echte Glühbirne aus dem Haushalt mit einem kleinen Taster ein- und ausschalten? Bei jedem Druck schaltet der Arduino ein Relais um und die Lampe geht an, beim nächsten Druck wieder aus.

4.5(33)
44
220-V-Glühbirne mit Fernbedienung schalten
#21Fortgeschritten
Premium

220-V-Glühbirne mit Fernbedienung schalten

Schalte eine echte Glühbirne in deiner Wohnung mit einer Fernbedienung ein und aus, ohne vom Sofa aufzustehen. Der Arduino liest das unsichtbare Lichtsignal der Fernbedienung; die Einschalttaste lässt

4.4(22)
30
Intelligente Treppen- und Korridorbeleuchtung
#82Mittel
Premium

Intelligente Treppen- und Korridorbeleuchtung

Betrittst du die Treppe oder den Flur, gehen die Lichter Stufe für Stufe in deiner Laufrichtung an. An jedem Ende sitzt ein Abstandssensor; an welchem du auch vorbeigehst, die acht LEDs leuchten von d

5.0(35)
51
ESP32 Intelligente Beleuchtung (PIR + LDR + Relais + OLED)
#141Fortgeschritten
Premium

ESP32 Intelligente Beleuchtung (PIR + LDR + Relais + OLED)

Verwandle deinen Flur, dein Badezimmer oder deine Speisekammer mit dem ESP32 in intelligente Beleuchtung! Mit einem PIR-Bewegungssensor, einem LDR-Lichtsensor und einem Relaismodul realisieren wir das klassische Szenario "Licht geht an, wenn im Dunkeln Bewegung erkannt wird" — bei Tageslicht bleibt das Licht trotz Bewegung aus, was tagsüber Energie spart. Das Licht bleibt 30 Sekunden lang an; bei anhaltender Bewegung wird der Timer zurückgesetzt und das Licht bleibt länger an. Das SSD1306 OLED-D

4.3(6)
11
Intelligente Bewässerungsstation
#83Fortgeschritten
Premium

Intelligente Bewässerungsstation

Ein Gärtner, der deine Pflanzen von selbst gießt, damit sie im Urlaub nicht vertrocknen. Ein Bodenfeuchtesensor misst, wie nass die Erde ist; wird sie trocken, lässt der Arduino die Wasserpumpe ein pa

5.0(42)
57
Automatische Beleuchtung mit dem ESP32-PIR-Bewegungssensor
#121Mittel
Premium

Automatische Beleuchtung mit dem ESP32-PIR-Bewegungssensor

In diesem Projekt werden wir mithilfe des PIR-Bewegungssensors HC-SR501 Personen erkennen, die den Raum betreten, und die LED automatisch einschalten. Wir überwachen die Leuchtdauer der LED mit millis(); bei jedem HIGH-Messwert des Sensors wird der Zeitpunkt der letzten Bewegung aktualisiert, und die LED erlischt frühestens 10 Sekunden nach dem letzten HIGH-Messwert. Der aktuelle Code wartet außerdem in jedem Schleifendurchlauf mit delay(50) für 50 ms, sodass die Anwendungsschleife nicht vol

4.4(24)
38