Lüftersteuerung mit OBD1-Diagnose Opel Manta B / Motronic 1.5.1

Eine kombinierte temperaturabhängige Lüftersteuerung und Bosch-Motronic-Blinkcode-Diagnose, gebaut um einen Arduino Pro Mini, eine 3-stellige 7-Segment-Anzeige und einen Drehgeber. Eingebaut in eine 3D-gedruckte Blende im Manta-B-Stil.

Hardware

Arduino Pro Mini 5 V / 16 MHz · 3-stellige 7-Segment (Common Cathode) · Rotary Encoder PEC16 · NTC im Spannungsteiler · 2 × Relais SRD-05VDC-SL-C · Optokoppler 4N25 · DC/DC-Wandler 5 V

Software

Lüfter-Automatik mit Schwelle & Nachlauf · manueller Override · Schwellwert-Edit · Helligkeit 5–100 % · Diagnose mit Auto-Kalibrierung · Sitzungs-Historie als Ringpuffer (32 × 10 Codes)

Diagnose

Liest Bosch-Motronic 1.5/1.5.1 Blinkcodes über die Diagnoseleitung (massegeschaltet, aktiv LOW). Decodiert auto-kalibriert anhand 3 × Code 12. Speichert pro Sitzung bis zu 10 Codes, löscht den ECU-Speicher.

Schaltplan auf einen Blick

Schaltplan Lüftersteuerung mit Diagnose

Bedienung

Quelle: Anleitung/Lüftersteuerung Endnutzeranleitung.odt

Automatikbetrieb

Lüfter schaltet automatisch ein, sobald die Temperatur die eingestellte Schalttemperatur überschreitet. Beim Unterschreiten läuft er noch 5 s nach.

Dauer EIN (manueller Override)

  • Aktivieren: Drehknopf kurz drücken (< 0,5 s). Display blinkt sehr schnell.
  • Beenden: erneut kurz drücken oder Temperatur sinkt unter Schwelle oder Nachlaufzeit nach Zündung-AUS abgelaufen.

Schalttemperatur einstellen

  • Drehknopf länger als 1 s halten → Wert blinkt schnell.
  • Drehen stellt zwischen 25 °C und 130 °C ein. Nach 5 s ohne Drehung wird gespeichert.

Helligkeit einstellen

  • Aktivieren: bei eingeschalteter Zündung doppelt klicken.
  • Drehen ändert in 5-%-Schritten zwischen 5 % und 100 %.
  • Kurzer Klick bestätigt & speichert. Nach 5 s ohne Drehung wird automatisch gespeichert.

Steuergerät auslesen (Diagnose)

  • Aktivieren: Zündung EIN, Drehknopf länger als 10 s drücken.
  • Lauflicht zeigt Beginn der Auto-Kalibrierung (3 × Code 12 als Referenz).
  • Danach werden die gespeicherten Fehlercodes auf der Anzeige rotierend angezeigt.
  • Nach erneutem 3 × Code 12 → Display zeigt CLR, die Codes werden in der ECU gelöscht.
  • Die Sitzung wird automatisch als P1 in die Historie geschrieben.

Fehlercode-Historie

  • Aktivieren: Zündung AUS, Drehknopf länger als 5 s drücken.
  • Display zeigt 3 s den Speicherplatz (P1, P2, …), dann die enthaltenen Codes rotierend.
  • Drehen wechselt zur nächsten/vorherigen Sitzung (6 Encoder-Schritte = 1 Sitzungssprung).
  • Beenden: Drehknopf kurz drücken.

Hardware

Pinbelegung Arduino Pro Mini

PinFunktionBeschaltung
D11Segment ACommon-Cathode 7-Segment, HIGH = AN
D9Segment B
D8Segment C
D7Segment D
D6Segment E
D5Segment F
D4Segment G
D12Digit 1 (Hunderter, links)NPN-Treiber, HIGH = EIN
D13Digit 2 (Zehner, mitte)NPN-Treiber, HIGH = EIN
D0 ⚠Digit 3 (Einer, rechts)NPN-Treiber. Konflikt mit RX beim Upload abklemmen
D2Encoder CLKINPUT_PULLUP
D3Encoder DTINPUT_PULLUP
D1Encoder SW (Taster)INPUT_PULLUP
A6„Tür offen" / Anzeige erzwingenanalog, aktiv LOW, externer 10 kΩ Pullup
A7Zündung I1analog, aktiv LOW via Optokoppler 4N25, ext. 10 kΩ Pullup
A3Diagnose-Signal Motronicdigital, aktiv LOW, INPUT_PULLUP
A2Diagnose-UmschaltrelaisTransistor BC337 + Freilaufdiode 1N4007
A0Lüfter-RelaisTransistor BC337 + Freilaufdiode 1N4007
A1NTC TemperaturfühlerSpannungsteiler mit Vorwiderstand

Schaltplan

Vollständiger Schaltplan

Bauteilliste

BauteilTypDatenblatt (lokal)
MikrocontrollerArduino Pro Mini 5 V / 16 MHz (ATmega328P)Pro Mini PDF
SpannungsversorgungDC/DC-Wandler 12 → 5 VDC/DC PDF
Diode (Freilauf)1N40071N4007 PDF
DrehgeberBourns PEC16-4220F-S0024 (24 Detents, mit Taster)PEC16 PDF
KFZ-Stecker6,3 mm FlachsteckerStecker PDF
KondensatorKeramik 100 nF100 nF PDF
Optokoppler4N254N25 PDF
PinheaderStandard-2,54-mmBild
RelaisSongle SRD-05VDC-SL-C, 5 V Spule, 10 A KontaktSRD PDF
TransistorBC337 NPN, 800 mA, TO-92BC337 PDF
7-Segment-Anzeige0,36" 11 Pin, 3 Ziffern, gemeinsame Anode (gelb)Bild

Hinweis zur Anzeige: Das Datenblatt nennt „gemeinsame Anode", die Firmware behandelt die Anzeige aber als Common-Cathode (HIGH = AN). Bitte real verifizieren — das ist die häufigste Fehlerquelle bei diesem Projekt.

3D-Modell & Gehäuse

Im Ordner 3D Druck/ liegen STL-Dateien für die Manta-B-Temperaturanzeige-Blende, Drehknopf, Klammer und Gehäusedeckel/-boden. Final-Versionen:

  • Manta B Temperaturanzeige Blende V3.stl – Frontblende
  • Manta B Temperaturanzeige Drehknopf Opel.stl – Drehknopf
  • Manta B Temperaturanzeige Gehäuse Deckel V2.stl + Boden V2.stl – Gehäuse
  • Manta B Temperaturanzeige Klammer mit Platine.stl – Halterung

Platine & Schaltplan

Direktansicht der KiCad-Dateien (Schaltplan + Original-PCB + Lochraster-Edition) und ein interaktiver Bestückungsplan für die Lochraster-Edition.

Schaltplan (KiCad)

Pan = Ziehen mit der Maus · Zoom = Mausrad · Doppelklick = anfitten · Pin/Net-Hover für Details.

Original-PCB (66 × 46 mm)

Die ursprünglich entworfene Leiterplatte. Hinweis sie hat 8 Pad-Konflikte (Bauteile teilen Bohrlöcher), die in der Lochraster-Edition behoben sind.

Lochraster-Edition (60,96 × 45,72 mm)

Konfliktfreie Anordnung auf 25 × 19 = 475 Löchern, alle Pins exakt auf 2,54-mm-Raster (außer K1 Pin 11 / COM, herstellerseitig off-grid). Kein Kupfer-Routing — die Verdrahtung erfolgt manuell mit Litze auf der Lötseite (71 Drahtbrücken).

Lochraster-Bestückungsplan (interaktiv)

25 × 19 = 475 Löcher, 2,54 mm Raster. Hover über einen Pin zeigt Bauteil + Net + alle verbundenen Pins. Wähle ein Net, um es zu markieren — die Drahtbrücken werden als Linien angezeigt.

Lade Layout…
auf Raster (2,54 mm) off-grid (K1.11) hervorgehobenes Net Bauteilkörper

IST vs. Verbesserung — was wurde geändert?

Original-PCB

Größe
66,04 × 45,72 mm
Lochraster
26 × 18 = 468
Bauteile
39 (alle THT)
Pad-Konflikte
8 Bauteile auf gleichem Bohrloch
Off-Board-Pads
5 Pins ragen über Edge.Cuts hinaus
Routing
Kupferleiterbahnen (FR4-Fertigung)
Buildbar
nicht so — nur mit Korrekturen

Lochraster-Edition

Größe
60,96 × 45,72 mm −5 mm
Lochraster
25 × 19 = 475
Bauteile
39 (alle THT, identisch)
Pad-Konflikte
0 komplett konfliktfrei
Off-Grid-Pins
1 K1.COM (Finder 36.11 Hardware-Limit)
Routing
71 Drahtbrücken (≈ 795 mm), keine Ätzung nötig
Buildbar
ja auf Standard-Punktraster

Korrigierte Bauteilpositionen

RefOriginal-PositionLochraster-PositionGrund
Q3col 3 rows 4–6col 4 rows 4–6Pin-Überlappung mit Q1 (gleiche Spalte)
C1(16,1)–(16,3)(10,1)–(10,3)Pin 1 lag auf U1.3 (anderes Net)
C2(10,1)–(10,3)(14,1)–(14,3)Platz für umgesetztes C1
U1cols 14,15,16 row 1cols 11,12,13 row 1Platz für umgesetztes K1
K1cols 17–22, rows 1+6cols 15–20, rows 1+6Pin 14 lag auf J8.2 (anderes Net)
D1cols 17–21 row 13cols 17–21 row 16Pin 1 lag auf J2.3
Q4cols 19–21 row 15cols 19–21 row 14Pin 1 lag auf J5.3
R14(15,10)–(15,14)(12,11)–(16,11)Pin 2 lag auf U2.4 (GND)

Eingesparter Platz

Die Lochraster-Edition spart 301 mm² (10 %) gegenüber der Original-PCB. Mehr ist nicht möglich, weil zwei Bauteile die Mindestgröße bestimmen:

  • J3 (1 × 16 Pin-Header zum Front-Panel) → mindestens 16 Reihen oder Spalten
  • 9 × 1 × 3 KFZ-Stecker auf der rechten Kante, gestapelt im 2-Reihen-Pitch → mindestens 18 Reihen Höhe

Eine echte SMD-Variante würde anders aussehen — aber der Wunsch war: nur THT, identische Footprints.

Fehlercodes

Die Fehlercode-Tabelle ist jetzt im Emulatoren → Fehlercodes-Tab.

Firmware-Architektur

Modus-State-Machine

Reihenfolge der Anzeige­priorität (höchste zuerst): History → Diagnose → Setting (Schwelle/Helligkeit) → Normalbetrieb.

NORMAL (Temp/Blank) SETTING_THRESH SETTING_BRIGHT DIAGNOSIS CLR_FLASH (1 s) HISTORY long ≥1 s + I1 double-click + I1 long ≥10 s + I1 long ≥5 s + ¬I1 3 × Code 12 automatisch nach 1 s kurzer Klick Klick / Timeout 5 s Klick / Timeout 5 s

EEPROM-Layout (optimierte Firmware v2)

0
Anzahl gespeicherter Sitzungen (0..32)
1
Head-Index (0..31, 255 = leer)
2..31
reserviert
32..383
32 Sitzungen × 11 Bytes = [len][code1..code10]
400..415
Schwellwert-Slots (8 × [seq][value]) — Wear-Leveling
416..431
Helligkeits-Slots (8 × [seq][value]) — Wear-Leveling

Der Wear-Leveling-Mechanismus wählt beim Lesen den Slot mit der höchsten Sequenznummer, schreibt beim Speichern in den nächsten freien Slot mit Sequenznummer+1. Das verteilt 100 000 EEPROM-Schreibzyklen auf 8 Slots → effektiv 800 000 Schreibvorgänge.

PID-Lüfterregelung (v2)

Statt der ursprünglichen Bang-Bang-Steuerung („Temperatur > Schwelle ⇒ Relais EIN, sonst AUS plus 5 s Nachlauf") regelt v2 die Lüfterleistung als kontinuierliche Stellgröße 0–100 % mit einem PID-Regler und gibt sie über Slow-PWM (Default 30 s Periode) auf das Relais aus.

Algorithmus
error = T - Sollwert         (>0 ⇒ zu heiß)
P     = Kp · error
I     += Ki · error · dt     (Conditional-Integration
                              gegen Wind-up,
                              eingefroren in Deadband)
D     = Kd · dT/dt           (Derivative on
                              Measurement, kein
                              Setpoint-Kick)
output = clip(P + I + D, 0, 100) %
Slow-PWM auf Relais
elapsed = (now - cycleStart) % CFG_PID_PWM_MS
on_ms   = output% · CFG_PID_PWM_MS / 100
relay   = (elapsed < on_ms)

Override (kurzer Klick) zwingt die Duty unbedingt auf 100 %.

Default-Tuning: Kp = 5 %/°C · Ki = 0.5 %/(°C·s) · Kd = 2 %·s/°C · Slow-PWM = 30 s · Deadband = 0.5 °C.

⚠ Hardware-Konsequenz: Das verbaute SRD-05VDC-SL-C ist ein mechanisches Relais mit ca. 100 000 Schaltzyklen. Slow-PWM mit 30 s Periode ergibt im ungünstigsten Fall 120 Zyklen/Stunde → ~830 h Nutzungsdauer. Für Dauerbetrieb sollte das Relais durch einen Logik-Pegel-N-MOSFET (z. B. IRLZ44N) oder ein SSR ersetzt werden. Die Pinbelegung bleibt identisch.

Notfall-Rückfallebene: Mit #define CFG_USE_PID 0 in der Firmware wird wieder die klassische Bang-Bang-Logik aktiv – falls man auf der Strecke vorerst auf Nummer sicher gehen will.

Diagnose-Decoder (Auto-Kalibrierung)

Das Bosch-Motronic-Steuergerät sendet Codes als zweistellige Blink-Sequenzen, getrennt durch lange Pausen. Beispiel Code 12: 1 Blitz → kurze Pause → 2 Blitze → lange Pause → nächster Code.

Beim Diagnose-Start sendet das Steuergerät 3 × Code 12 als Startcode. Die Firmware misst dabei automatisch die Pausenzeiten und leitet daraus die Schwelle „kurze vs. lange Pause" ab. So funktioniert die Erkennung auch dann zuverlässig, wenn ein Steuergerät mit leicht abweichendem Timing arbeitet.

Quellcode-Übersicht

readEncoderAndButtons()Encoder + Klick + Long-Press / Double-Click
handleMirrorMode()Übergang in den Diagnose-Modus
processDiagnosisSignal()Decoder-State-Machine (Pulse → Code)
updateRelay()Lüfter-Logik (Auto / Override / Nachlauf)
updateDisplay()Modus-Priorität, ruft Display-Helfer auf
saveSessionToEEPROM() / loadSessionByRelativeIndex()Ringpuffer für Sitzungen

Optimierungsplan

Klicke eine Karte an, um sie als nächste Verbesserung vorzumerken. Auswahl wird lokal gespeichert.

0 ausgewählt

Software vollständig umgesetzt

NTC-Linearisierung (Steinhart/Beta)
erledigt Korrekte Temperatur statt linearer Approximation.
Nicht-blockierender ECU-Clear
erledigt Kein delay(1000) mehr im Loop.
Adaptive Pausen-Schwelle
erledigt Schwelle aus Kalibrier-Messung statt fester 2000 ms.
Encoder mit Quadratur-Tabelle
erledigt Ein Klick = ein Schritt.
Tasten-Entprellung in Software
erledigt 5 ms-Filter, saubere Edge-Events.
EEPROM Wear-Leveling + update()
erledigt Lebensdauer × 8.
Multiplex auf micros()
erledigt Loop läuft ohne delay() durch.
Watchdog (2 s)
erledigt Selbstheilung bei Hängern.
Modus-Hierarchie als enum
erledigt Klare Übergänge.
PROGMEM-Zeichensatz
erledigt RAM-frei.

Hardware

D0/RX-Konflikt
Platinen-Revision Digit3 auf D10 verlegen → Upload + Serial-Debug ohne Aufschrauben.
Hardware-PWM für Helligkeit
Platinen-Revision Common-Cathode-Enable über Timer2-PWM.
TVS / Optokoppler an A3
empfohlen Schützt MCU vor 14 V-Spikes auf der Diagnose-Leitung.
Reverse-Polarity-Schutz
empfohlen P-MOSFET High-Side oder Schottky + PTC.
BOD-Fuses (2.7 V)
empfohlen Schützt EEPROM bei Spannungs­einbrüchen.
Entkopplung 100 nF + 10 µF
empfohlen An VCC-Pins der ICs.

UX

Visuelle Long-Press-Bestätigung
Bei 1 s / 5 s / 10 s je ein anderes Indikator-Muster.
Override-Anzeige
Dezimalpunkt am Einer-Digit als Indikator.
Helligkeit dynamisch
Über LDR oder Klemme 58 (Standlicht).
Schwellwert mit Beschleunigung
Schnelles Drehen → 5 °C / Klick.
Werkseinstellung
15 s halten ohne Zündung → EEPROM-Reset.
Service-Modus / Selbsttest
Beim Power-On „888" + Software-Version.

Vollständigen Plan öffnen →

Emulatoren

Simulation
Motor
Umgebung & Kühlung
Lüfter & PID-Regler
Szenarien & Stöße
Stoß °C
Parameter-Fit aus Echtmessung (Stoppuhr + Display)
Führe die 3 Szenarien nacheinander durch. Je 2 Zeitpunkte mit abgelesener Temperatur genügen. Zeiten immer ab Beginn des jeweiligen Szenarios (Stoppuhr neu starten).
① Kaltstart – Aufwärmen
Motor an, Lüfter aus, Leerlauf. Messen bis kurz VOR dem Thermostat-Öffnen (sichtbar als Verlangsamung des Anstiegs).
Punkt 1 t = s T = °C Punkt 2 t = s T = °C Last (geschätzt) % (Leerlauf ≈ 20–35 %) Thermostat öffnet °C (Temp. wo Anstieg merklich abbricht)
② Lüfterkühlung – Motor an, Lüfter EIN
Lüfter manuell einschalten (Override), Motor läuft weiter im Leerlauf. Stoppuhr ab Lüfter-Einschalten.
Punkt 1 t = s T = °C Punkt 2 t = s T = °C Last (Leerlauf) %
③ Abkühlung – Motor aus, Lüfter aus
Zündung aus, Lüfter aus. Stoppuhr ab Motorabstellung. Beide Punkte sollten > 88 °C sein (Thermostat offen).
Punkt 1 t = s T = °C Punkt 2 t = s T = °C Außentemperatur °C
Live
Temperatur
25 °C
Soll (Schwelle)
70 °C
PID-Output (Duty)
0 %
Lüfter-Relais
⏻ AUS
Modellzeit
0 s
Schaltzyklen
0
0 / h
Wassertemp. (effektiv) · ┄ ┄ Sensorwert (PT1-verzögert) · ┄ ┄ Sollwert · PID-Output (rechte Achse, %) · ▒▒ Hysterese-Band (Output zwischen AUS- und EIN-Schwelle) · Lüfter-Relais an (oben) · Override aktiv (oben)
NORMAL
Schwelle: 70 °C · Helligkeit: 100 % · Override: aus
Halten = Long-Press (Maus gedrückt halten). Mausrad = drehen.
Zündung (I1)
Tür offen (I3)

Fehlercode-Simulation

Im Steuergerät hinterlegte Codes
Klicke Codes an, um sie ins „Mock-Steuergerät" zu legen. Bei der Diagnose werden sie der Reihe nach gesendet.
Aktion
Du kannst entweder den Drehknopf 10 s halten (mit Zündung an) oder direkt hier starten:
Live-Status
Phase
bereit
Empfange gerade
Sitzungs-Puffer
Ausgewählt

Anleitung

  • Knopf kurz klicken → Override toggeln (nur das Relais; Anzeige bleibt)
  • Knopf halten ≥ 1 s (mit Zündung) → Schwellwert-Edit, danach drehen, kurzer Klick speichert
  • Knopf doppelt klicken (mit Zündung) → Helligkeit-Edit
  • Knopf halten ≥ 10 s (mit Zündung) → Diagnose mit den oben eingegebenen Codes
  • Knopf halten ≥ 5 s (ohne Zündung) → History
  • Im History-Modus 6 × drehen = nächste Sitzung
  • Bei „Tür offen" + Zündung AUS bleibt die Anzeige weiterhin sichtbar (Firmware-Spezifikation)

Live-Log

CodeBedeutungBedingung / UrsacheErsatzwert / Datenliste
NTC-Parameter
R bei 25 °C [Ω]
Beta-Wert [K]
Vorwiderstand [Ω]
Topologie
ADC-Auflösung
Anpassen anhand realer Messpunkte
Zwei bekannte (Temperatur, ADC)-Paare → Beta+R25 werden gefittet.
Punkt 1: T [°C]
  ADC
Punkt 2: T [°C]
  ADC
Generierter C-Code
Klicke „C-Code generieren"
Eingangs-Pulse · roter Cursor = aktuelle Decoder-Position
Decoder-Status
Modus
WAIT_FIRST
Kalibrierung
offen (0/3)
Pause-Schwelle
– ms
aktuelle Ziffer 1
aktuelle Ziffer 2
letzter Code
end12-Counter
0
Erkannte Codes (Sitzungspuffer)

Log

Motor-Simulation
Beim laufenden Motor steigt die Wassertemperatur asymptotisch auf 95 °C. Lüfter wirkt dem entgegen (–0,5 °C/s).
Aktuelle Temperatur: 25 °C
Lüfter-Relais: ⏻ AUS
Steuergerät (Motronic) – Mock
Hier kannst du Codes „im Steuergerät" hinterlegen. Wird im Diagnose-Modus gesendet.
NORMAL
Zündung
Tür offen

Log

3D-Modell – Interaktiver STL-Viewer

Alle druckbaren Teile und das PCB-Modell in einer interaktiven 3D-Vorschau. Bedienung: Mausziehen = drehen · Mausrad = zoomen · Rechtsklick + Ziehen = verschieben · Doppelklick = Kamera zentrieren.

Three.js wird geladen…
Erste Sitzung benötigt Internet (CDN)
Geometrie-Info:
STL geladen aus

PCB-Modell (KiCad STEP)

Das Lüftersteuerung mit Diagnose.step enthält das exakte Platinen-Modell aus KiCad inkl. Bauteilen (DC/DC, Pro Mini, Optokoppler, Relais, Anzeige).

Three.js kann STEP nicht nativ rendern (das Format ist eine NURBS-/B-Rep-Beschreibung, nicht polygonal). Drei Wege, sich's anzusehen:

  1. STEP-Viewer im Browser: öffne die Datei direkt in 3dviewer.net oder viewstl.com per Drag & Drop.
  2. Lokale Software: FreeCAD, KiCad selbst (View → 3D Viewer) oder eDrawings.
  3. Konvertieren zu STL: in FreeCAD öffnen → File → Export → STL → in den Ordner 3D Druck/ legen → erscheint dann oben im Dropdown (manuell als Option ergänzen).
STEP-Datei herunterladen

Anmerkungen & Verbesserungen

Diese Seite sammelt Korrekturen zu meinen früheren Aussagen, technische Hintergründe und konkrete Verbesserungsvorschläge mit High-Level-Umsetzung. Schwerpunkt aktuell: Lüfteransteuerung nach dem Umbau auf PID.

📌 Aktuelle Entscheidung: Das verbaute KFZ-Relais bleibt drin. Die PID-Regelung wurde entsprechend auf D-dominante Hysterese umgestellt — der Output wird nicht slow-PWM-gerastert, sondern triggert das Relais nur, wenn er Hysterese-Schwellen überschreitet UND Mindest-EIN/AUS-Zeiten eingehalten sind. Dadurch sind die Schaltzyklen pro Stunde drastisch reduziert (Größenordnung: von ~120/h auf ~10–30/h im Worst Case). Diese Strategie ist seit Firmware v2 default aktiv.

0. Schaltsparender PID-Regler (D-dominant + Hysterese)

Statt eines Slow-PWM-Aktuators auf dem Relais regelt v2 jetzt mit einem Hysterese-Aktuator, der zusätzlich auf Mindest-Verweilzeiten in jedem Zustand achtet. Der Trick liegt im PID-Tuning: Kd ist hoch, Kp und Ki sind klein.

Warum D-dominant?

Bei der Motorkühlung haben wir's mit einem thermisch sehr trägen System zu tun:

  • Eine reine P-Regelung reagiert nur, wenn der Sollwert schon überschritten ist. Bis dann der Lüfter-Effekt greift, ist die Temperatur weiter gestiegen → Überschwingen.
  • Der I-Anteil mittelt zwar Drift heraus, treibt aber bei Sollwert-Sprüngen ins Wind-up. Bei einem Bang-Bang-/Hysterese-Aktuator ist der I-Anteil eher schädlich (Sättigung).
  • Der D-Anteil reagiert auf dT/dt – also wie schnell sich die Temperatur ändert. Wenn der Motor heizt und die Temperatur steigt, schiebt der D-Anteil den Output schon hoch, bevor das Setpoint erreicht ist. Sobald der Lüfter greift und die Temperatur fällt, kippt D ins Negative und drückt den Output unter die AUS-Schwelle – Lüfter aus, lange bevor die Temperatur wieder unter Sollwert ist.

Resultat: lange An-Phasen, lange Aus-Phasen, sehr wenige Schaltvorgänge.

Default-Tuning (Firmware v2)

ParameterVorher (Slow-PWM)Jetzt (Hysterese)Begründung
Kp5.0 %/°C2.0 %/°CKein heftiger Sprung-Beitrag, der zu Flatterschalten führt
Ki0.5 %/(°C·s)0.05 %/(°C·s)Nur leichte Drift-Korrektur, kein Wind-up-Risiko
Kd ★2.0 %·s/°C15.0 %·s/°C★ Antizipiert Temperaturänderung 5–10 s im Voraus
D-Filter (EMA α)0.15Tiefpass auf dT/dt gegen ADC-Rauschen
EIN-Schwelle60 % OutputKlares „jetzt einschalten"-Signal
AUS-Schwelle30 % Output30 % Hysterese-Band
Min-EIN-Zeit30 sVerhindert kurze Pulse
Min-AUS-Zeit60 sErzwingt lange Ruhezyklen
Schaltrate (Worst Case)~120/h~30/hFaktor 4× weniger Verschleiß

Hysterese-Logik (Pseudocode)

output = PID(error, dt)  // mit Kp=2, Ki=0.05, Kd=15, EMA-D-Filter

if (relais ist EIN) {
  // nur ausschalten, wenn Mindestzeit-EIN abgelaufen UND Output unter AUS-Schwelle
  if (now - lastSwitch >= MIN_ON_MS  &&  output < OFF_THRESH) {
    relais = AUS;  lastSwitch = now;
  }
} else {
  // nur einschalten, wenn Mindestzeit-AUS abgelaufen UND Output über EIN-Schwelle
  if (now - lastSwitch >= MIN_OFF_MS  &&  output > ON_THRESH) {
    relais = EIN;  lastSwitch = now;
  }
}

Im Emulator selbst durchspielen

Im UI-Tab unter „PID-Regler-Parameter" auf D-dominant ★ klicken und im Live-Dashboard auf den Schaltzyklen-Counter und die / h-Rate schauen. Vergleichend auf Klassisch (Kp-dominant) stellen → der Counter klettert dramatisch schneller. Auf Sehr schaltsparend für noch weniger Schaltungen (mit etwas mehr Temperatur-Hub).

1. Korrektur: Lebensdauer-Aussage zum Relais

1. Korrektur: Lebensdauer-Aussage zum Relais

Was ich vorher pauschal gesagt habe: „Slow-PWM mit 30 s Periode ⇒ ~830 h Relais-Lebensdauer."
Was korrekter ist: Diese Zahl gilt nur für das aktuell verbaute SRD-05VDC-SL-C — ein 5 V-PCB-Relais aus dem Hobby-Bereich. Ein echtes KFZ-Mini-ISO-Relais (Bosch / Hella, 30–40 A) hat 2–5× höhere Schaltzyklen­zahlen. Die Frage „realistisch für ein KFZ-Relais?" ist also eigentlich zwei Fragen: wäre 30 s PWM für ein PCB-Relais realistisch (eher nicht) und für ein Mini-ISO-Relais (ja, problemlos).

2. KFZ-Relais im Detail – Schaltzeiten und Lebensdauer

Mechanische Schaltzeiten

Relais-TypAnzugzeitAbfallzeitMin. Zykluszeit (mech.)
Songle SRD-05VDC-SL-C (PCB-Hobby)~10 ms~5 ms~30 ms (≈ 30 Hz)
Bosch Mini-ISO 30 A (z. B. 0 332 019 150)10–15 ms5–10 ms~25 ms
Hella 50 A SPDT (4RA-Serie)15–20 ms10 ms~35 ms
Tyco V23234 KFZ-Power~10 ms~3 ms~15 ms

Mechanisch verkraften alle ein paar 10 Hz problemlos. Die elektrische Lebensdauer unter Last (Lichtbogen, Inrush) ist die echte Begrenzung.

Lebensdauer unter Lüfter-Last

Ein typischer KFZ-Kühlerventilator zieht:

  • Dauerstrom 10–20 A (Manta B: vermutlich ~12–15 A)
  • Anlaufstrom 3–6 × Dauer für 50–200 ms (sog. „Inrush")
  • Abschaltspike wird von der Freilaufdiode über die Spule, NICHT über den Kontakt eingefangen — aber das Bordnetz sieht den Spike
RelaisDatenblatt-Zyklen (induktive Last)Bei 30 s Slow-PWM, 100 % Lüfter-ZeitRealistisch (10 % Lüfter)
SRD-05VDC-SL-C @ 10 A~100 000~830 h~14 Jahre*
Bosch Mini-ISO 30 A~200 000~1 660 h~28 Jahre*
Hella 4RA / 50 A~200 000–500 000~4 150 h~70 Jahre*

* Annahme: 200 h Fahrt/Jahr, 10 % davon mit aktivem Lüfter. Real meist weniger; an heißen Tagen / Anhängerbetrieb kann's mehr sein.

Antwort auf deine Frage: 30 s PWM ist für ein echtes KFZ-Relais (Mini-ISO) absolut realistisch und harmlos. Selbst bei Worst-Case-Nutzung übertrifft die Lebensdauer den Rest des Fahrzeugs. Beim aktuell verbauten SRD-Hobby-Relais ist es grenzwertig — das ist eher ein Fall, wo das Relais sowieso nicht in ein 12 V/15 A KFZ-Bordnetz gehört.

3. Wo's trotzdem haken kann (auch beim KFZ-Relais)

  1. Hörbares Klicken — alle 30 s ein Schaltgeräusch. Im Motorraum egal, im Innenraum nervig.
  2. Lüfter-Bürstenverschleiß — viele Anläufe = mehr Bürstenverschleiß als kontinuierlicher Lauf.
  3. Bordnetz-Spikes — alle 30 s ein 30–80 A-Inrush-Spike auf 12 V. Lichtmaschine + Batterie puffern, aber Radio kann „klacken" hören.
  4. Kein Soft-Start — der Lüfter springt von 0 auf volle Drehzahl. Mit MOSFET kann man rampen.
  5. Keine Drehzahlregelung — Slow-PWM-Duty mittelt sich thermisch raus, der Motor läuft aber binär. Ein „45 % leise" gibt's nicht.

4. Die fünf Lösungswege im Vergleich

Variante Hardware-Aufwand Software-Aufwand Komfort Lebensdauer Mein Rating
A) Status Quo: SRD-Hobby + Slow-PWM 30 s keinkein schlecht (Klick)grenzwertig vermeiden
B) Mini-ISO-KFZ-Relais + Slow-PWM 30 s 1 Relais + Sockel kein mittel (Klick) sehr gut solide
C) Zwei-Stufen-Relais (Low / High) ohne PWM 2 KFZ-Relais + 0,3 Ω/100 W Vorwiderstand für Low klein (Output → 0/Low/High) gut (3 Stufen) sehr gut elegant
D) Logik-MOSFET mit echter PWM (100 Hz–25 kHz) 1 MOSFET + Gate-R + TVS klein (analogWrite) sehr gut (lautlos, Soft-Start, stufenlos) quasi unbegrenzt empfohlen
E) Hybrid: KFZ-Relais hält Dauerstrom, MOSFET schaltet 1 Relais + 1 MOSFET mittel (zwei Aktoren) sehr gut quasi unbegrenzt overkill

5. Empfehlungen je nach Strategie

Hinweis: aktuelle Projekt­entscheidung ist Variante B + D-dominante Hysterese (Punkt 0 oben). Die anderen Optionen bleiben hier als Referenz erhalten, falls die Strategie später wechselt.

Aktiv: KFZ-Relais bleibt + D-dominante HystereseVariante B + 0
SRD-PCB-Relais gegen Bosch Mini-ISO 30 A tauschen. Firmware mit CFG_RELAY_MODE = RELAY_HYST_PID (Default in v2) flashen. Schaltrate sinkt von ~120/h auf ~10–30/h, Klicken nur noch alle paar Minuten, Lebensdauer „mehrere Auto-Leben" bei realistischer Nutzung. Kosten: ~5 €.
Optional: Logik-MOSFETVariante D, später
Logik-MOSFET IRLZ44N (TO-220, ~1 €), 25 kHz PWM, lautlos, stufenlos. Voraussetzung: Platinen-Revision oder Adapterboard, 100 Ω Gate-R, 10 kΩ Pulldown, TVS-Diode, Kühlkörper. Firmware mit CFG_RELAY_MODE = RELAY_SLOW_PWM + PWM-Periode auf 40 µs (auf Timer1) → echtes PWM. Erst sinnvoll wenn das Klicken trotz Hysterese stört.

6. High-Level-Umsetzung — Aktuator-Abstraktion

Damit die Firmware nicht jedes Mal umgeschrieben werden muss, wenn die Hardware sich ändert, abstrahiere ich den „Aktuator" (Lüfter-Endstufe). Der PID-Regler liefert weiter eine Stellgröße 0–100 %. Welcher Aktuator-Code daraus „Relais an/aus" macht, ist auswählbar.

// firmware/ProMini_Optimized.ino – konzeptionell:

#define CFG_FAN_ACTUATOR  ACTUATOR_SLOW_PWM_RELAY   // A oder B
//      ACTUATOR_TWO_STAGE_RELAY                    // C
//      ACTUATOR_FAST_PWM_MOSFET                    // D
//      ACTUATOR_HYBRID_RELAY_MOSFET                // E

class FanActuator {
public:
  virtual void apply(float dutyPct) = 0;      // 0..100
  virtual void off() = 0;
};

// A/B: Slow-PWM auf Relais (Default, schon implementiert)
class SlowPwmActuator : public FanActuator {
  uint8_t pin; unsigned long cycleStart, cycleMs;
  void apply(float duty) override {
    unsigned long now = millis(), el = (now - cycleStart) % cycleMs;
    digitalWrite(pin, (el < duty/100.0f * cycleMs) ? HIGH : LOW);
  }
};

// C: Zwei-Stufen-Relais ohne PWM
class TwoStageActuator : public FanActuator {
  uint8_t pinLow, pinHigh;
  void apply(float duty) override {
    if      (duty < 30) { off(); }
    else if (duty < 70) { digitalWrite(pinLow, HIGH); digitalWrite(pinHigh, LOW); }
    else                { digitalWrite(pinLow, LOW);  digitalWrite(pinHigh, HIGH); }
  }
};

// D: Echtes PWM auf MOSFET (Timer1, 25 kHz)
class FastPwmActuator : public FanActuator {
  uint8_t pin;
  void setup() {
    // Timer1 in 8-Bit Fast-PWM bei 25 kHz konfigurieren
    TCCR1A = _BV(COM1A1) | _BV(WGM10);
    TCCR1B = _BV(WGM12) | _BV(CS10);          // 16 MHz / 1 / 256 ≈ 62 kHz
  }
  void apply(float duty) override {
    OCR1A = (uint8_t)(duty * 2.55f);          // 0..255
  }
};

// Verwendung im PID-Loop:
fanActuator->apply(manualOverride ? 100.0f : pidOutputPct);

Die konkrete Klasse wird per #if-Schalter zur Compilezeit ausgewählt. Das Interface ist gleich, der Rest der Firmware (PID, Override, Auto-Ende) bleibt unverändert.

7. Schaltplan-Skizzen

Variante D – Logik-MOSFET (empfohlen)

             +12 V (Bordnetz, abgesichert)
                 │
                ┌┴┐
                │L│ Lüfter (12 V, 10–15 A)
                └┬┘
                 │     ┌───── TVS 18 V (z. B. SMBJ18A)
                 ├─────┤  oder Schottky-Freilaufdiode 1N5408
                 │     └───── parallel zur Lüfterwicklung
                 │
              D ─┴─
                 │
   ATmega A0 ───[100 Ω]─── G ──┤ IRLZ44N (TO-220, Kühlkörper)
                                │
              S ─┬─
                 │
                 └─── GND (12 V- und µC-GND verbunden)

   10 kΩ Gate-Pulldown von G nach S (verhindert Floating bei
   Reset / Power-Up – wichtig, sonst zappelt der MOSFET).

Variante C – Zwei-Stufen-Relais

+12 V ──┬─── K1 (Low) ──[ 0,3 Ω / 100 W ]──┐
        │                                       │
        └─── K2 (High) ────────────────────────┤
                                                ├─── Lüfter ─── GND
                                                │
                                          1N5408 parallel zur
                                          Lüfterwicklung

   ATmega A0 → Treiber → K2 (High)
   ATmega Aux → Treiber → K1 (Low)
   PID-Output 0..30 %  → beide AUS
   PID-Output 30..70 % → K1 AN, K2 AUS  (langsame Drehzahl)
   PID-Output 70..100% → K1 AUS, K2 AN  (volle Drehzahl)

Die Reihenschaltung über K1 + Vorwiderstand ist die klassische Werks-Lösung in den meisten KFZ. Im Manta B sollte vermutlich sogar bereits ein zweiter Schaltpunkt im Originalkabelbaum existieren.

8. Migrations-Roadmap

SchrittWasWerAufwand
1Aktuelle Firmware mit PID-Slow-PWM 30 s flashen, im Auto messen: Schaltgeräusch hörbar? Bordnetz-Klacken im Radio?du1 h
2aWenn Relais-Klacken stört oder Lebensdauer-Sorge → SRD-PCB-Relais gegen Bosch Mini-ISO 30 A tauschen (Adapterboard mit Sockel)du2–3 h Lötzeit
2bEmpfehlung: gleich auf MOSFET-Variante wechseln. Adapterplatine mit IRLZ44N, Gate-R, Pulldown, TVSdu / KiCad1 Wochenende
3Firmware-Aktuator-Abstraktion einführen, FastPwmActuator implementieren (Timer1 25 kHz)ich, auf Bestellung~1 h Code
4Im Emulator auch FastPWM darstellen (PWM-Periode 1 s im Sim, dafür sichtbar)ich30 min
5PID-Tuning auf der echten Hardware: Sprung-Antwort messen, Kp/Ki/Kd nachjustierendu, mit Datenlogiterativ

9. Was ich davon jetzt sofort tun kann

  • Sag „Aktuator-Abstraktion bauen" → ich lege die Klassen wie oben in der Firmware an, baue alle drei Strategien (Slow-PWM, Two-Stage, Fast-PWM) ein und mache sie über CFG_FAN_ACTUATOR wählbar.
  • Sag „Schaltplan-Erweiterung in KiCad" → ich kann zwar KiCad nicht direkt aufrufen (nicht installiert), aber ich kann eine ergänzende SVG-Skizze als zweite Schaltplan-Datei erstellen.
  • Sag „BOM für Variante D" → ich erstelle eine fertige Bestellliste mit Reichelt-/Mouser-Bestellnummern.

Downloads & Dateien