Nach langem mal wieder was von mir. Da bei der CNC die ich gerade baue der Großteil selber gestrickt ist muss auch der Motortreiber selbst gebaut sein. Gemacht hab ich das noch nie, deswegen hab hab ich mich im Wesentlichen an folgendem Desing Orientiert http://www.dr-iguana.com/prj_StepperDriver/index.html , welches ich nahezu 1:1 übernommen hab. Es sitzen drei von diesen Treibern auf einer Platine, gemeinsam mit ein bisschen Hühnerfutter, um sinnvoll mit anderen Geräten Kommunizieren zu können. Vorweg: Das hier ist kein Nachbau Projekt, das Design hat ein paar Bugs, andererseits lohnt es nicht Wirklich einen Motortreiber mit dieser Funktionalität selbst zu bauen (China liefert billiger). Mit den Erfahrungen die ich hier mitnehme hab ich aber vor einen State of the Art Motortreiber zu entwerfe bei dem sich das Nachbauen lohnt. Ich weis nicht mehr ganz was meine Intension war als ich angefangen hab meinen Motortreiber selbst zu bauen, aber gelernt hab ich auf jeden Fall was dabei und das möchte ich hier Teilen. Wer die KiCAD Dateien oder sonstiges zu dem Projekt haben möchte schreibt mir bitte, ich will das git repo nicht veröffentlichen weil da Massenhaft Datenblätter und ein paar Application notes drinnen sind die nicht von mir sind, privat geb ich das ganze aber gerne weiter.
Das gesamte Projekt besteht aus 3 Modulen Netzteil, Motortreiberplatine mit 3 Treibern und einem Raspberry PI der das ganze über einen CAN Bus an das Netzwerk frickelt.
1. Netzteil
Netzteil ist ziemlich staight forward aus einem LM5116 gebaut. Ich hatte noch 2*28V Trafo rumfliegen der macht schöne 80V DC für das Netzteil dann gehts mit einem Buck runter auf 20-36V bei 8A was dann etwa 200W hergibt. Der LM5116 ist gleichzeitig PWM controler, MOSFET Treiber und Linearversorgung für sich selbst. Da die uC und der Raspberry 5V sehen wollen sitzt auf dem Netzteil noch ein LM2676 Buck der aus der Brückenspannung für die Motortreiber 5V @ 3A macht. Der LM5116 vom Großen Buck kann sich nur mit thermischen Problemen auf Dauer aus den 80V selbst versorgen. Deswegen übernimmt nach dem Anlaufen die 5V Versorgung diese Aufgabe. Gelaufen ist das ganze out of the Box der LM5116 erleichtert vieles kann ich jedem nur empfehlen vor allem weil es ihn bei reichelt gibt.
Schaltplan
Und ja wem es auffällt das sind 120 1206er Abblockkondensatoren die in 4 Layers gestapelt sind .
Und für die wo es mir nicht glauben hier noch die tollen Kondensator Türmchen.
2. Motortreiber
Der Motortreiber war leider nicht plug and play. Wie schon beschrieben sitzen auf der Motortreiberplatine 3 Treiber, ein uC um mit dem Raspberry Pi auf der einen Seite zu kommunizieren und den einzelnen Motortreibern auf der anderen zusätzlich ist ein bisschen Kleinkram für die Referenzspannungen und die 3,3V für die uC's vorhanden. Das schöne daran die Treiber über einen uC anzusteuern und nicht direkt vom PI ist dass das die Echtzeitanforderungen vom PI nimmt. Die 7 Seiten Schaltplan gibt es hier https://flo-e.de/CNC/Mainboard.pdf. Elektrisch ist das alles schon zusammen gelötet und getestet fehlen tut nur noch die Software für die Kommunikation. Ich werd euch auf dem Laufenden halten. Die Software um den Motor zu regeln steht bereits. Wer genauer an der Funktionsweise von Stepper Drivern interessiert ist hier https://www.microchip.com/wwwAppNotes/A ... e=en546027 ist das ganz gut beschrieben.
Elektrischer Aufbau
Die einzelnen Motortreiber bestehen aus je einer L298 Bipolaren Doppelvollbrücke(dafür dass ich die Dinger verwendet hab ohne nachzudenken beiß ich mir jetzt noch in den Arsch ) und einem dsPIC33FJ12MC202 uC von microchip. Der L298 besteht aus 2 Vollbrücken(für jede Motorphase eine) somit lässt sich jede Phase in beide Richtungen bestromen. Die einzelnen Motorphase verhalten sich wie ein RL Element. Bekanntermaßen gilt damit für $I=0$ $U = L\frac{\mathrm{d}I}{\mathrm{d}t}$, insbesondere begrenzt die Brückenspannung somit den maximalen Stromgradienten und die Drehzahl. Motortreiber verwenden deswegen in der Regel eine hohe Brückenspannung und Stellen den Strom im Motor mittels PWM. Um den Strom regeln zu können ist je Treiber und je Phase einen Shunt mit feedback Verstärker verbaut. Das Feedback wird dann vom ADC des uC gelesen. Zusätzlich sind noch Comperatoren für die Überstromabschaltung und Anschlüsse für die Endschalter der Achse verbaut.
Probleme sind leider nicht ausgeblieben ich musste nach langem Suchen feststellen dass zwei der uC etwas Temperatur empfindlich sind. Unter einer gewissen Temperatur werden die ADC Interrupts nur sehr sporadisch bis gar nicht geworfen. Woher das kommt hab ich keinen Plan es könnte ein Silicon Bug sein oder ich hab die uC irgendwie geschrotted . Fürs erste hab ich mal eine 1206 Heizung draufgeklebt . Bei der nächsten reichelt Bestellung werden beide defekte uCs getauscht. Fürs erste läuft das so mit dem Hack.
Schaltplan
Bilder
Initialisierung
Leider musste ich nach dem ich das Ding zusammen gelötet hab feststellen dass die L298 Brücken ziemlich langsam sind die on Time ist um etwa $3,\!5\,\mu\mathrm{s}$ kürzer als die wo der uC vorgibt und variiert von Halbbrücke zu Halbbrücke um etwa $0,\!5\,\mu\mathrm{s}$ . Ähnliches gilt für die turn off delay. Das ist deswegen problematisch weil der uC dem ADC vorgibt wann genau der Strom aufgezeichnet wird. Da die Strommessung nur möglich ist wenn die Halbbrücke an ist, muss, um das Maximum des Stroms zu erfassen, die Verzögerung zwischen abschalten des uC Signals und Abschalten der Halbbrücke bekannt sein. Weiter ist im Feedback Verstärker noch ein RC Tiefpass um glitches beim Schalten zu Filtern, dieser verzögert das Strommaximum zusätzlich.
Um diese Probleme zu kompensieren(nimmt man normalerweise gute MOSFET Brücken ) muss der uC einige Messungen beim hochfahren machen.
- Zuerst wird der Offset der Feedbackverstärker ermittelt welcher sich durch die Widerstandstoleranzen ergibt. Das geschieht bei ausgeschalteter Brücke.
- Um die Ausschaltverzögerung zu bestimmen legt der uC eine PWM mit fester On time an die Brücke an. Durch sweepen der ADC Umwandlungszeitpunkte über einen gewissen Zeitbereich findet der uC das die Position des Maximums des gemessenen Stroms.
- Mit der nun bekannten Turn-Off Delay wird nun die Verringerung der On-Time bestimmt. Hierzu erhöht der uC die On-Time solange bis ein sehr kleiner Strom messbar ist.
Der uC hat nur einen ADC da auf beiden Phasen der Strom zu einem jeweils anderen Zeitpunkt gemessen werden muss, wird der ADC abwechselnd auf die eine oder andere Phase aufgeschalten. Folglich kann die Stromregelung für jede Phase auch nur dann stattfinden wenn ein neuer ADC Wert vorhanden ist, also nur jeden zweiten PWM Zyklus. Die Stromregelung funktioniert über einen selbst implementierten PID Regler. Grundlagen sind hier https://rn-wissen.de/wiki/index.php/Reg ... 1-Glied.29 ganz gut beschrieben. Implementiert ist das gleich nur will der Regler seine Regelungsparameter eingestellt haben sonst läuft da nichts. In letzterem Link sind einige Vorgehensweisen aufgelistet die bei mir alle nicht wirklich funktioniert haben, Ich hab mir das deswegen selber überlegt. Die Ziegler/Nichols und die Chien/Hrones/Reswick Methode können bei einem Stepper eigentlich nicht funktionieren weil die Sprungantwort vom Regler hierzu Abschnittsweise Konvex und Konkav sein muss, was bei einem RL Element nicht der Fall ist. Die dort angegebene Methode 1 funktioniert nicht weil ab der Verstärkung wo der Regler zu schwingen beginnt das Quantisierungsrauschen des ADC als Störgröße die Messung zu stark verfälscht.
Zunächst ist werden die Stell und Messwerte(in Bit) innerhalb des uC mit den Realen Größen in Beziehung gesetzt. Für die Effektiv am Motor anliegende Spannung $U$ gilt in Abhängigkeit des PWM Stellwertes $q_{PWM}$, der PWM Periode $q_{Period}$ und der Brückenspannung $U_{Bridge}$ gilt: $$U(t) = \frac{q_{PWM}(t)}{q_{Period}}\cdot U_{Bridge}$$
Auf den ersten Blick scheint dieser Zusammenhang offensichtlich. Problematisch ist jedoch wieder dass ich Bipolare Halbbrücken verbaut hab. Im Eingeschalteten Zustand der Brücke ( eine Seite HIGH die ander LOW) reduziert sich die Brückenspannung lediglich um die Flussspannung der Transistoren. Problematisch ist jedoch der Ausgeschaltete Zustand(beide Seiten LOW) hier liegt über der Brücke immer noch eine Flussspannung an was obige Beziehung nichtlinear macht. Ich vernachlässige das einfach mal weil die Mathematik dann schön einfach wird und der Einfluss nicht alzu groß sein solte ist.
Analog gilt für das Strom Feedback mit dem Strom $I$, dem Stromverstärkungsfaktor $G\left[\frac{1}{A}\right]$, dem ADC wert $q_{ADC}$ und der maximalen ADC Auslenkung auf die $G$ normiert ist $q_{limit}$:
$$I(t) G= \frac{q_{ADC}(t)}{q_{limit}}$$
Ein Zeit kontinuierlicher PID Regler wird, wobei $s$ den Sollwert markiert, durch folgende Gleichung beschrieben:
$$q_{PWM} = K_P \cdot (q_{ADC} - q_S) + K_D \frac{d(q_{ADC} - q_S)}{dt} + K_I \int_0^t dt (q_{ADC} - q_S)$$
Das RL Element(Regelstrecke) verhält sich folgendermaßen:
$$U = RI + L\frac{dI}{dt}$$
Durch Einsetzten dieser 4 Gleichungen ineinander folgt die folgende gewöhnliche lineare inhomogen DGL zweiter Ordnung mit Konstanten Koeffizienten:
$$K_I I + \left(K_P - \frac{R q_{Period}}{U_B G q_{limit}}\right) I' + \left(K_D - \frac{L q_{Period}}{U_B G q_{limit}}\right)I'' = K_I I_S + K_P I_S' + K_D I_S''$$
Ich freue mich immer wieder wenn eine so schön einfache DGL das Problem repräsentiert. Diese ist nämlich analytisch lösbar und die Lösungen sind gedämpfte Schwingungen. Von einem Guten Regler wird erwarted, dass er bei einer Sollwertänderung schnell reagiert, dabei aber nicht zu schwingen beginnt. Für diese DGL existiert eine solche Lösung nämlich der Aperiodische Grenzfall https://de.wikipedia.org/wiki/Aperiodischer_Grenzfall. Das ist der Grenzfall zwischen gerade so nicht schwingen und möglichst schneller Änderung. Um dies zu erreichen gilt für die Koeffizienten:
$$4 K_I = \frac{\left(K_P - \frac{R q_{Period}}{U_B G q_{limit}}\right)^2}{K_D - \frac{L q_{Period}}{U_B G q_{limit}}}$$
Der Freiheitsgrad der Koeffizienten ist nun um 1 geringer. Fehlt noch $K_P$ und $K_D$ zu bestimmen. Für einen Apperiodischen Regler ohne Totzeit der ungestört ist können beide theoretisch beliebig hoch gewählt werden (Meine ich zu mindestens wenn es nicht stimmt bitte berichtigen). Das Problem ist dass das Quantsierungsrauschen(Störgrößen) da wir einen diskreten Regler haben einen Strich durch die Rechnung macht. Da das schwerer zu modellieren ist folgendermaßen vorgehen um eine sinnvolle Einstellung zu finden. Zu Beginn wird ein kleines $K_D$ gewählt, $K_P$ wird solange erhöht bis der Regler durch das Rauschen instabil wird $K_I$ muss natürlich paralell mit obiger Gleichung nachgeführt werden. Anschliesend reduziert $K_P$ ein Stückchen zurück und erhöht $K_D$ wieder bis der Regler Instabil wird. Dann nochmal ein kleines Stück zurück und Fertig ist es.
Da der Regler jedoch kein kontinuierlicher ist sonder diskret mit Schrittweite $\Delta t$ muss die DGL noch Substituiert werden. Mit $S \Delta t = t$ gilt:
$$\frac{d}{dt} = \frac{d}{dS}\cdot \frac{dS}{dt} = \frac{1}{\Delta t} \frac{d}{dS}$$ bzw
$$\frac{d^2}{dt^2} = \frac{1}{\Delta t^2} \frac{d^2}{dS^2}$$
Für die Diskreten PID Parameter ergibt sich analog als Aperiodenbedingung mit $K_{D,dis} = \frac{D_{I,cont}}{\Delta t}$, $K_{I,dis} = K_{I,cont} \Delta t$
$$4 K_I = \frac{\left(K_P - \frac{R q_{Period}}{U_B G q_{limit}}\right)^2}{K_D - \frac{L q_{Period}}{\Delta t U_B G q_{limit}}}$$
So wie ich den Regler hier entworfen hab muss bedacht werden dass $\Delta t$ gleich der zweifachen Periodenlänge der PWM Periode ist.
Diese analytische vorgehensweise verhilft auch zu einem sauberen ergebniss, ich kann jedem nur davon abraten zu versuchen einen PID mit der Hand oder mit old school Einstellregeln einzustellen. Mit 15min nachdenken und eine Hand voll einfacher Rechnungen, ist das Ergebniss richtig nice. Bei den kleinen NEMA17 200Step/rot Dingern wo ich vor hab zu verbauen erreiche ich etwa 110rpm ohne dass der Strom gemindert ist. Die Drehzahlgrenze liegt bei etwa 150rpm @ 33V Brückenspannung. Wobei das sicher nicht das ende der Fahnenstange ist ich musste die PWM wegen der Rechenzeit für den PID regler auf 75% begrenzen da lässt sich einerseits noch etwas raus hohlen wenn ich mich dazu aufraffen könnte das in Assembler zu implementieren. Andererseits kann die Brückenspannung noch solange erhöt werden wie die Motorisolierung das mit macht. Wenn man die Drehzahl von einem Schrittmotor auf die Spitze treiben will, auch wenn das bei einer CNC nicht immer das ziel ist, gibt es noch einen kleinen Trick. Ein PID Regler kann im schwingenden Bereich größere Gradienten fahren. Wenn die doppelte Schrittfrequenz jedoch größer ist als die Eigenfrequenz des PID und die Dämpfung größer 0 kann fängt der PID obwohl er nicht mehr aperiodisch ist nicht an zu schwingen. Der PID wird schwingend indem $K_I$ größer wird als das der aperiodische Grenzfall erlaubt aber nicht so Groß dass die Grenzfrequenz zu hoch wird.
Dass man mir das auch glaubt hier einmal Bilder vom Current Feedback in Oma Geschwindigkeit und bei 150rpm.
Oma:
150rpm:
Bei der hohen Geschwindigkeit sind 2 Dinge gut erkennbar. Einerseits sieht man dass der PID Regler ziemlich an dem Maximalen Gradienten ist der möglich ist. Zum zweiten sieht man dass der maximale negative Gradient größer ist als der Positive Gradient. Das liegt wie ich vorher schon beschrieben hab dass das eine Bipolarhalbbrücke ist wo die Sättigungsspannung über den Bipolartransistoren anliegt.
Ansteuerung
Zuletzt fehlt noch wie der Motortreiber mit der CAN Bus Controler kommuniziert. Wie gesagt der Teil ist noch nicht fertig und ich werde euch auf dem laufende halten. Vom Prinzip her gibt es 2 Kommunikationskanäle einmal das was man klassisch als Step/Dir Signale kennt zusätzlich gibt es dann noch einen I2C Bus damit man so etwas wie Endschaltersignale Rückmelden kann. Bei den Step/Dir Signalen werde ich warscheinlich von dem was Üblich st abweichen und QEI Signale nehmen weil die der uC automatisch de modulieren kann.
Bald gehts weiter
lg ferrum