Table of Contents
Motivation / Tal der Tränen
In meinem Line Follower Roboter Projekt habe ich mit dem Motortreiber L298N gearbeitet. Da Module mit diesem Treiber auf eine Leistung von maximal 25 Watt limitiert sind, musste für unser Azubi-Projekt ein anderer Treiber her.
Die Anforderungen waren mit 50 Watt pro Motor und einer Vollbrücke nicht besonders hoch, aber der Teufel steckt ja bekanntlich im Detail. Der erste Treiber, der Cytron SmartDriveDuo MDDS30 war mit 40A / 300W stark überdimensioniert. Er ist uns trotzdem nach ein paar Wochen abgeraucht.
Der nächste Versuch mit dem Soldered DRV8424P war auch nicht von Erfolg gekrönt. Wir haben erst nach ein paar Tagen herausgefunden, dass der falsche Chip bestückt wurde. Auch bei der Nachlieferung war das der Fall, anscheinend war die ganze Charge des Lieferanten falsch.
Also schnell aus der Not eine Tugend machen und selber einen Treiber entwerfen.
Anforderungen
Der Motortreiber soll sich zur Ansteuerung mit Arduino GPIOs via TTL-Pegel eignen. Er soll zwei 2 Kanäle mit jeweils 50 Watt Leistung haben und via PWM in der Geschwindigkeit regelbar sein. Die Betriebsspannung soll zwischen 18 und 24 Volt liegen.
Recherche
Nach dem Schauen von dutzenden Videos und Lesen von einigen Blog-Artikeln habe ich den Beitrag von Alexander Egger gefunden:
https://www.aeq-web.com/arduino-mosfet-h-bruecke-dc-motor-steuern-mit-drehrichtung-und-geschwindigkeit-vierquadrantensteller/
Dieser Artikel erschien mir sehr gut als Absprungbasis geeignet.
Schaltungsentwurf – Revision 1
Im ersten Versuch habe ich die Schaltung von Alex mit Fritzing nachgebaut. Als Transistoren habe ich für die High Side die im Artikel erwähnten IRF9540 benutzt. Für die Low Side habe ich IRLZ44N verwendet, da die L-Versionen für Logikpegel geeignet sind, weil sie bei 5V VGS schon durchschalten. Zusätzlich habe ich vier 1N4007 als Freilaufdioden eingebaut:
Daraus habe ich dann eine erste Platine gelayoutet:
Aus Fritzing heraus, konnte ich direkt eine Platine bei Aisler fertigen lassen. Mindestabnahmemenge sind 3 Stück. Bei einem Gesamtpreis von knapp 20€ ein sehr interessanter Anbieter. Da die Produktion und Lieferung 2,5 Wochen dauern sollte, habe ich parallel dazu die Schaltung auf einem Breadbaord aufgebaut und getestet.
Hierbei ist mir dann aufgefallen, dass ich die p-kanal MOSFETs falsch herum eingezeichnet hatte.
Das konnte ich beim Bestücken der Platine -die doch bereits nach 10 Tagen eingetroffen war- noch halbwegs elegant beheben.
Lasttest
Ich habe mich langsam herangetastet, einfacher 5V Motor mit wenigen 100mA Last.
Dann den richtigen Motor bei 24V betrieben. Leider konnte ich keinen echten Lasttest durchführen.
Die Schaltung lief aber stabil bei 12-15Watt Leistungsaufnahme.
Die Transistoren haben sich dabei auf ca 40° Celsius erwärmt.
Lasttest Nummer 2
Um mal die Platine richtig zu stressen, habe ich eine elektronische Last drangehängt.
Hierbei hat sich dann der Steckverbinder des Jumnperkabels verabschiedet, da die Zuleitung für mehr als 1 Ampere überfordert war. Das bedeutet die Spannungsversorgung über die Pin Header ist nicht optimal.
Schaltungsentwurf – Revision 2
Nicht lang snacken, Kopp inn Nacken! Im zweiten Wurf wollte ich dann die Spannungsversorgung auch über eine WAGO-Klemme realisieren.
Zudem sind noch ein paar Optimierungen möglich. Die Freilaufdioden sollten näher an den MOSFETs platziert werden. (Danke Hubert für den Tip!)
Es fehlten noch die Montage-Löcher, um die Platine sinnvoll zu befestigen. Für die WAGO-Klemme hatte ich den falschen Footprint benutzt, sodass ich zum verlöten von der Klemme zwei Beinchen abzwicken musste. Duh!
Schematic
Da mir die Möglichkeiten mit fritzing etwas eingeschränkt vorkommen, habe ich mich in KiCAD eingearbeitet. Die Lernkurve ist etwas steiler, aber machbar.
Die Schaltung habe ich fast eins zu eins von den Schematics aus fritzing ins KiCAD übertragen. (Und die p-Kanal-Mosfets richtig herum angeschlossen LOL)
Der Standard-Header hat jetzt einen Pin mehr, da er die Betriebsspannung ans Logik-Board übertragen muss. Dazu später mehr.
PCB-Layout
Beim PCB Layout habe ich mich an der ersten Version orientiert, habe aber die Freilaufdioden näher an die MOSFETs platziert. Für die Leistung die Leiterbahnbreite auf 2 mm erhöht.
Im 3D-Viewer kann man schön sehen, ob die Teile gut positioniert sind.
Auch diese Platine habe ich wieder bei Aisler bestellt. Perfekter Service.
Bestückung
Beim Bestücken ist mir aufgefallen, dass ich für die Bipolar-Transistoren den schmalen Footprint genommen habe. Das macht das Löten etwas anstrengender, aber noch ok.
Lasttest
Beim Lasttest konnte ich eine Leistung von knapp 50 Watt abrufen, ohne dass sich die MOSFETS überhitzt haben.
Die p-Kanal MOSFETs werden mit 65°C jedoch deutlich wärmer als die n-Kanal (45°C)
Steuerungssoftware
Für die PWM-Ansteuerung habe ich mich am Programm von Alex orientiert, allerdings etwas optimiert und für eine Anbindung an ein Python-Programm mit GUI erweitert.
const byte P_FET_Q1 = 2;
const byte N_FET_Q4 = 3; // PWM controlled
const byte P_FET_Q3 = 8;
const byte N_FET_Q2 = 9; // PWM controlled
byte current_PWM_port = N_FET_Q4;
void setup()
{
//This sets frequency to 7812.5 hz.
TCCR0B = TCCR0B & 0b11111000 | 0x01;
pinMode(P_FET_Q1, OUTPUT);
pinMode(N_FET_Q2, OUTPUT);
pinMode(P_FET_Q3, OUTPUT);
pinMode(N_FET_Q4, OUTPUT);
Serial.begin(9600);
}
Am Anfang werden alle Pins deklariert und als Output gesetzt.
Wie auch bei meinem Line Follower setze ich die PWM-Frequenz auf 7kHz.
void forward()
{
digitalWrite(N_FET_Q2, LOW);
digitalWrite(P_FET_Q3, LOW);
digitalWrite(P_FET_Q1, HIGH);
current_PWM_port = N_FET_Q4;
}
digitalWrite ist hier sehr nützlich, weil es relativ langsam ausgeführt wird.
Die 4–5 µs Verzögerung, die durch den Funktionsaufruf entstehen, wirken hier wie eine kurze Dead Time.
Fazit & Ausblick Rev3
Da ich beim Testen von beiden Platinen die Spannungsquelle ein paar Mal falsch herum angeschlossen hatte, sollte in Revision 3 ein Verpolungsschutz hinzukommen. Eine Beschriftung der WAGO-Klemme ist natürlich auch sinnvoll.
Zudem hätte ich auch gerne eine Indikator-LED, die mir anzeigt, dass die Schaltung mit Spannung versorgt wird. Zwei LEDs, die die Drehrichtung anzeigen, werde ich auch einbauen. Bei Rev1 und Rev2 fehlen auch die Bezeichnungen an den Digital-Eingängen, sodass ich beim Testen immer rätseln musste, welcher Pin welchen Transistor ansteuert.
Da die Schaltung außerdem nicht gegen shoot-through gesichert ist, muss das derzeit Software-seitig passieren. Für Revision 3 werde ich noch eine Logikschaltung entwerfen, die sicherstellt, dass nur die korrespondierenden Hi- und Lo-Side gleichzeitg aktiv werden können.
Last but not least werde ich versuchen, die Platine in SMD-Technik zu layouten.
Arduino-Code
Hier der komplette Arduino Code:
const byte P_FET_Q1 = 2;
const byte N_FET_Q4 = 3; // PWM controlled
const byte P_FET_Q3 = 8;
const byte N_FET_Q2 = 9; // PWM controlled
byte current_PWM_port = N_FET_Q4;
void setup()
{
//This sets frequency to 7812.5 hz.
TCCR0B = TCCR0B & 0b11111000 | 0x01;
pinMode(P_FET_Q1, OUTPUT);
pinMode(N_FET_Q2, OUTPUT);
pinMode(P_FET_Q3, OUTPUT);
pinMode(N_FET_Q4, OUTPUT);
Serial.begin(9600);
}
void stop()
{
analogWrite(current_PWM_port, 0);
}
void forward()
{
digitalWrite(N_FET_Q2, LOW);
digitalWrite(P_FET_Q3, LOW);
digitalWrite(P_FET_Q1, HIGH);
current_PWM_port = N_FET_Q4;
}
void backwards()
{
digitalWrite(P_FET_Q1, LOW);
digitalWrite(N_FET_Q4, LOW);
digitalWrite(P_FET_Q3, HIGH);
current_PWM_port = N_FET_Q2;
}
void drive(byte speed)
{
analogWrite(current_PWM_port, speed);
}
void loop()
{
if (Serial.available()) {
String cmd = Serial.readStringUntil('\n');
if (cmd.startsWith("PWM:")) {
int value = cmd.substring(4).toInt();
if (value < 0) {
backwards();
value = -value;
} else {
forward();
}
value = constrain(value, 0, 255);
drive(value);
} else if (cmd == "STOP") {
stop();
}
}
}