Steuerung von zwei unabhängigen Gleichstrommotoren ("Teller Mitte" / "Teller Rot", keine echten Schrittmotoren, siehe Diagnose-Notizen unten) mit Mattke-MTR-24...60/5- Servoverstärkern über ESP32-S3. Ersetzt die defekte SPS einer PVD-Sputterbeschichtungsanlage (PINK GmbH Vakuumtechnik, Vakuumlabor Fachbereich Physikalische Technik).
Durch Nachmessen an der DIN41612-Steckerplatine von "Teller Mitte" bestätigt:
- Pos-/Neg-Stop (A14/A12) fest auf GND gebrückt → Motor in beiden Richtungen frei
- Sollwert 2 (A10/E10) auf GND → ungenutzt
- Sollwert 1 (E8/C10) und Disable (E12) waren früher über Relais von der SPS geschaltet – diese Verbindungen fehlen jetzt und müssen neu aufgebaut werden
- Erfolgreicher manueller Test: Motor lief über C6 (+12V) → Poti "Schnell"/"Langsam" → 8e (Sollwert 1), Disable (12e) auf GND
- Die hier dokumentierte MCP4725/LM358-DAC-Lösung (kontinuierlicher Sollwert, nötig für spätere Positionierung mit Encoder)
- Ein in derselben Session gebauter Relais/Optokoppler-Ansatz mit Web-Oberfläche (schneller Weg zum ersten Erfolgstest, nutzt die vorhandenen Frontplatten-Potis "Schnell"/"Langsam" statt eines DAC)
Vollständige Mattke-Steckerbelegung, Diagnoseverlauf und Projektstatus: siehe
Obsidian-Notizen 02 Projekte/Sputteranlage SPS-Ersatz.md und
04 Ressourcen/Elektronik/Mattke MTR 24-60-5 Steckerbelegung.md im HSRM-Vault.
| Komponente | Modell | Funktion |
|---|---|---|
| Mikrocontroller | ESP32-S3-N16R8 | Steuerzentrale |
| DAC (2×) | MCP4725 (I2C) | 12-Bit Digital-Analog-Wandler (Motor 1 & 2) |
| Operationsverstärker | LM358 | Spannungsverstärkung (0...3.3V → 0...10V) |
| Optokoppler | PC817 | Galvanische Isolation |
| Motor-Steuerung (2×) | Mattke MT24 60 | 24...60V, 5A Schrittmotor-Steuerung |
ESP32-S3 MCP4725 (Motor 1) MCP4725 (Motor 2)
GPIO8 (SDA) ─────────────────────────────────────── SDA
GPIO9 (SCL) ─────────────────────────────────────── SCL
GND ─────────────────────────────────────── GND (gemeinsam)
+3.3V ─────────────────────────────────────── VDD (gemeinsam)
I2C-Adressen:
- Motor 1 DAC:
0x60(A0=GND, A1=GND, A2=GND) - Motor 2 DAC:
0x61(A0=+3.3V, A1=GND, A2=GND)
LM358 Nicht-invertierender Verstärker (Kanal 1: Motor 1)
MCP4725 Motor 1 Output ──────→ [R_in = 100kΩ] ─→ LM358 Pin 3 (IN+)
│
┌───[R_f = 203kΩ]───┐
│ │
[R_g = 100kΩ] │
│ │
└────→ LM358 Pin 2 (IN-) ← Pin 1 OUT (Feedback)
│
GND ───┴─ (optional)
Gain = 1 + (R_f / R_in) = 1 + (203/100) = 3.03×
→ 0...3.3V DAC × 3.03 = 0...10V Motor-Eingangsspannung
Output LM358 Pin 1 → MT24 Sollwert-Eingang (0...±10V)
- Mit PC817 Optokoppler isoliert (optional für EMV)
Kanal 2 (Motor 2) identisch auf LM358 Pins 5-7
LM358 OUT1 ──┬─→ [R_limiting = 1kΩ] ─→ PC817 LED (Pin 1)
│ PC817 Collector (Pin 4) ─→ MT24 #1
└─→ 0V PC817 GND (Pin 2) ─→ 0V
PC817 Emitter (Pin 3) ─→ 0V
src/
├── main.cpp # Test-Firmware mit Testphasen
└── (none – Header-only)
include/
├── mcp4725_driver.h # MCP4725 DAC-Treiber (I2C)
├── lm358_converter.h # OpAmp-Kalibrierung (3.03× Gain)
└── motor_controller.h # High-level Motor Control API
- Initialisiert beide MCP4725 DACs auf I2C-Adressen 0x60 & 0x61
- Methoden:
setMotor1Speed(),setMotor2Speed(),emergencyStop() - Eingabe: 0...3.3V, Output: 12-Bit DAC-Wert (0...4095)
- Berechnet OpAmp-Ausgangsspannung:
calculateMotorVoltage(dac_voltage) - Umkehrberechnung:
reverseCalculate(desired_motor_voltage) - Gain-Kalibrierung: 3.03× (100kΩ + 203kΩ Resistor-Divider)
- Spannungsbereich: 0...3.3V DAC → 0...10V MT24
- Public API für Anwendungscode:
init()– System initialisierensetMotorSpeed(motor, voltage)– Spannungsvorgabe in Volt (0...10V)setMotorSpeedPercent(motor, percent)– Prozentsatz (0...100%)stopMotor(motor)– Motor stellenstopAllMotors()– Notfall-StoprampMotorSpeed(motor, target_voltage, ramp_time_ms)– Sanfte BeschleunigunggetMotorVoltage(motor)– Aktuelle Spannung auslesen
void setup() {
MotorController::init();
}
void loop() {
// Motor 1 auf 50% Geschwindigkeit (5V)
MotorController::setMotorSpeedPercent(MotorController::MOTOR_1, 50.0f);
delay(2000);
// Motor 2 sanft auf 8V beschleunigen (über 3 Sekunden)
MotorController::rampMotorSpeed(MotorController::MOTOR_2, 8.0f, 3000);
delay(3000);
// Notfall-Stop
MotorController::stopAllMotors();
}Die main.cpp enthält eine automatische Testsequenz:
| Phase | Aktion |
|---|---|
| 1 | Motor 1 @ 30% (3V) |
| 2 | Motor 1 @ 50% (5V) |
| 3 | Motor 1 @ 80% (8V) |
| 4 | Motor 2 @ 20% (2V) |
| 5 | Motor 2 @ 60% (6V) |
| 6 | Motor 2 @ 90% (9V) |
| 7 | Beide @ 50% (5V) |
| 8 | Beide @ 100% (10V) |
| 9 | Ramp-Test (sanfte Zu-/Abfahrt) |
| 10 | Notfall-Stop |
Jede Phase dauert 5 Sekunden (konfigurierbar via TEST_INTERVAL_MS).
# Build
pio run -e esp32
# Upload
pio run -e esp32 -t upload
# Monitor serielle Ausgabe
pio device monitor -b 115200=== PINK DUAL MOTOR CONTROL SYSTEM ===
ESP32-S3 with MCP4725 DAC & LM358 OpAmp
Target: Mattke MT24 60 Steuerungen (2×)
=== Initializing Dual Motor Control System ===
✓ MCP4725 DACs initialized
=== LM358 Converter Calibration ===
Gain Factor: 3.03
DAC Input Range: 0.0...3.3V
Motor Output Range: 0.0...10.0V
Calibration Test Points:
DAC 0.00V → Motor 0.00V
DAC 0.83V → Motor 2.51V
DAC 1.65V → Motor 5.00V
DAC 2.48V → Motor 7.50V
DAC 3.30V → Motor 10.00V
✓ Motor controller ready
| GPIO | Funktion | Bezeichnung | Schaltschrank |
|---|---|---|---|
| 04 | DI 01 | Drehschalter Stellung 1 | |
| 05 | DI 02 | Drehschalter Stellung 2 | |
| 06 | DI 03 | Drehschalter Stellung 3 | |
| 07 | DI 04 | Drehschalter Stellung 4 | |
| 15 | DO 01 | 24 V Relais Eckventil Bypass | 12Y4, 20S5 |
| 16 | DO 02 | 24 V Relais Eckventil Rezipient | 12Y2, 18S1 |
| 17 | DO 03 | 24 V Relais Vorpumpe | |
| 18 | DO 04 | 24 V Relais Turbopumpe |
- Bypassleitung auf
Leitung von Turbo zum Rezipienten zu
Drehschieberpumpe ein - Wenn Vordruck erreicht ist, Bypassleitung schließen
Leitung zur Turbo öffnen - Wenn Turbo evakuiert ist, Turbo einschalten, Eckventil zum Rezipienten öffnen
VP: Vorpumpe, Drehschieberpumpe
TP: Turbopumpe
EV_BP: Eckventil Bypass: 12Y4, 20S5
EV_RE: Eckventil Rezipient: 12Y2, 18S1
Gesteuert durch einen mehrpoligen Schalter
| Schalterstellung | Digital IN | Digital OUT | Bezeichnung | Schaltzustand |
|---|---|---|---|---|
| 1 | DI 01 | DO 01 | EV_BP | 0 |
| DO 02 | EV_RE | 0 | ||
| DO 03 | VP | 0 | ||
| DO 04 | TP | 0 | ||
| 2 | DI 02 | DO 01 | EV_BP | 1 |
| DO 02 | EV_RE | 0 | ||
| DO 03 | VP | 1 | ||
| 3 | DI 03 | DO 01 | EV_BP | 0 |
| DO 02 | EV_RE | 1 | ||
| DO 03 | VP | 1 | ||
| 4 | DI 04 | DO 01 | EV_BP | 0 |
| DO 02 | EV_RE | 1 | ||
| DO 03 | VP | 1 | ||
| DO 04 | TP | 1 |