Hallo,
Ich habe das Forum bereits durchstöbert, jedoch noch keine konkrete
Antwort gefunden.
Ich wollte eine SVPWM oder SPWM basierte Motorsteuerung bauen, jedoch
einen AS5048A als Absolutencoder verwenden.
Die Steuerung ist als Positionierantrieb gedacht,
Geschwindigkeitsbereich 1rpm - 120rpm.
Ich habe noch so meine Verständnisprobleme darin, ob es nicht möglich
wäre, diese "popokurven" die am Ende entstehen sollen mit Hilfe einer
LookupTabelle zu erzeugen und eine Regelung auf Basis des Encoders zu
nutzen. Dies wird ja ansonsten auf anderem Wege ohne einen richtigen
Encoder berechnet.
Hierbei würde ich mit einem Regler, vorzugsweise PI, die Amplitude nur
noch verändern müssen(?). Da ich zu jedem Zeitpunkt die genaue Position
des Rotors kenne, glaube ich, dass dies funktionieren sollte, falls
nein, warum nicht?
Zu Beginn wäre es allerdings ausreichend, erst einmal den Motor mit
einer Sinuskommutierung laufen zu lassen.
Hier allerdings das nächste Problem: der 3 - Phasen Sinus soll laut
einigen Quellen nicht das Optimum sein, besser soll dieser hier sein(?):
http://exor-evs.com/cache/exor/59-modulator-e19391e3cf1b2d74.png
"Sinus"funktion Mitte
Falls das stimmt, wie erzeuge ich so einen? Ich würde die Funktion
in einer LookUpTable speichern und über den jeweiligen Rotorwinkel
abrufen.
Ich würde mich über Ideen und Aufklärung freuen.
Insbesondere, ob es nicht bessere Wege gibt, einen BLDC basierten
Positionierantrieb zu bauen.
Ich hatte bisher mit Motoren wenig am Hut und versuche mich da nun
erstmal einzulesen.
MotorMann schrieb:> Ich habe noch so meine Verständnisprobleme darin, ob es nicht möglich> wäre, diese "popokurven" die am Ende entstehen sollen mit Hilfe einer> LookupTabelle zu erzeugen und eine Regelung auf Basis des Encoders zu> nutzen.
Doch, natürlich kannst du eine Lookup Table benutzen. Die Application
Note AVR447 erzeugt genau auf diese Art und Weise ressourcensparend die
3 Phasen. Mein Wettbewerbsbeitrag '3-Phasen Frequenzumrichter' hier im
Forum basiert auch auf dieser AppNote.
AVR447 ist allerdings gedacht für Motore mit 3 Hallsensoren. Da du nun
einen absoluten Drehencoder benutzt, ist die Aufgabe, die
Sektorerkennung so umzustricken, das das Phasenschema wieder stimmt.
AVR447 benutzt einfach nur den Pinchange bei einem Sensorwechsel, um den
Start des nächsten Sektors in der Tabelle festzulegen.
Die Regelung der Leistung erfolgt einfach die Multiplikation der
Phasenwerte mit dem Amplitudenfaktor.
MotorMann schrieb:> Insbesondere, ob es nicht bessere Wege gibt, einen BLDC basierten> Positionierantrieb zu bauen.
Der Ansatz mit dem PI(D) Regler ist ja schon richtig. Du musst jetzt nur
deinen Drehgeber so normieren, das er Werte liefert, mit denen der
Regler was anfangen kann, und die Ansteuerung so modifizieren, das eine
Drehrichtungsumkehr auch programmgesteurt erfolgen kann und nicht nur
(wie bei AVR447) über einen User Pin.
Der Regler bekommt als Sollwert dann den gewünschten Drehgeberwert, und
als Istwert den gemessenen vom Sensor. Am Ausgang steht ein
vorzeichenbehafteter Amplitudenwert für die Phasenausgabe.
Brauchbare PID Regler werden in AVR221 beschrieben und sind auch bei der
Software für AVR447 mit integriert.
Danke erstmal einmal für die Hilfe
Ich verstehe allerdings nicht ganz die gezeigte SPWM aus AVR447.
Wohin fliesst der Strom ab? Wenn ich es richtig verstanden habe, so
geben die Sinuskurven die PWM für die HighSide-Driver vor, richtig?
Bedeutet dies, dass jeder Nullwert der Phasen automatisch bedeutet, dass
die LowSide Driver geschaltet sind, damit der Strom abfliesst? Falls das
so sein sollte, hatte ich bei meinen Versuchen das Problem, dass der
Motor erst sehr fein lief aber dann ruppig schaltete, weil die Lowside
natürlich in einem Schlag gewechselt wird.
Zweite Frage: In diesem Video wird Zwangskommutiert:
http://www.youtube.com/watch?v=94f0yHa61ec
Wie ist es möglich, dass die Motoren derart flüssig laufen während ich
das ruckeln nicht entfernt bekomme? Hatte einen ähnlichen Algorithmus (
BrushlessGimbal) an meinem Motor getestet, dieser soll jedoch nur simple
Sinusbestromung haben (zwangskommutiert) oder muss ich für solche
Ergebnisse bei langsamen Geschwindigkeiten die Amplitude dynamisch klein
halten?
MotorMann schrieb:> Wenn ich es richtig verstanden habe, so> geben die Sinuskurven die PWM für die HighSide-Driver vor, richtig?
Das ist die Spannung an der Wicklung des Motors, nicht nur die Highside.
Bei AVR447 werden die Timer im 'Gegentakt' Modus betrieben. Wenn du z.B.
einen Wert von 255 in einen Timer schreibst, würde die Highside der
betroffenen Halbbrücke voll durchgesteuert und die Lowside fast nie. Bei
128 wäre es halbe-halbe, immer natürlich minus der Totzeit, die ja von
beiden Timern etwas abzieht, damit die H-Brücke nie oben und unten
gleichzeitig leitet.
MotorMann schrieb:> weil die Lowside> natürlich in einem Schlag gewechselt wird.
Auch die Lowside wird mit dem Sinus angesteuert, nur ist er hier
invertiert.
Das Problem bei allen hallsensorbasierten Sinusdrives ist, das sie die
absolute Motorposition nur auf 60° genau 'wissen' (pro 3 Pole, die
Auflösung für einen Motor mit mehr als 3 Polen ist dann natürlich
höher), da die Sensoren nur 6 Zustände erfassen. Bei deinem
Absolutencoder kannst du mit geschickter Umrechnung theoretisch beliebig
genau erfassen, praktisch ist die Grenze die Auflösung der Tabelle.
AVR447 nimmt hier 192 Werte, aber es ist möglich (und habe ich auch
schon gemacht), die Tabelle z.B. 384 Werte lang zu machen. Wenn dir 192
erstmal reicht, ist deine derzeitige Aufgabe, den Sektorstart so zu
umzurechnen, das dir der Drehgeber einen Zeiger liefert, der an die
richtige Stelle der Tabelle zeigt.
447 nimmt dazu diese Konstrukte:
1
PROGMEMuint16_tCSOffsetsForward[8]=
2
{
3
0,
4
4*(SINE_TABLE_LENGTH/6),
5
2*(SINE_TABLE_LENGTH/6),
6
3*(SINE_TABLE_LENGTH/6),
7
0*(SINE_TABLE_LENGTH/6),
8
5*(SINE_TABLE_LENGTH/6),
9
1*(SINE_TABLE_LENGTH/6),
10
0
11
};
Das musst du umbauen. Bei dir ist es vermutlich sinnvoll, statt
Tabellenwerten ein Unterprogramm damit zu behelligen. Also Sensorwert
umrechnen in Tabellenposition. Wie oben erwähnt, hängt das von der
Motorgeometrie ab. Ein 9 poliger Motor würde ja pro Umdrehung dreimal
die Tabelle durchlaufen, ein 12poliger 4 mal usw.
MotorMann schrieb:> Mit dem genannten Sinus Algorithmus lief der Motor sehr> ruhig, hatte jedoch keinen hohen Drehmoment
Das ist später Aufgabe des PID Reglers. Dieser vergleicht deine Vorgabe
mit dem Ist-Wert und dreht bei Bedarf die Amplitude hoch, so dass am
Motor das Drehmoment höher wird. Verschiebe das auf später, wenn dir die
Umsetzung Drehgeber -> Sinustabelle gelungen ist.
Das Stichwort was dir beim Googlen helfen könnte ist
"Kommutierungswinkel" bzw. "Kommutierungswinkelfindung". Dein
Absolutencoder läuft ja einmal pro Umdrehung über und startet wieder bei
Null. Diese Nullposition ist aber nicht zwingend auch der Punkt, an dem
deine Kommutierungssequenz starten muss, weil der Geber mechanisch nicht
auf den Rotor ausgerichtet ist. Du musst also den Kommutierungsoffset
bestimmen und bei allen weiteren Berechnungen den gemessenen Winkel um
diesen Offset korrieren.
Man kann z.B. eine Motorwicklung mit konstantem Strom beaufschlagen
(nicht zu wenig, >>5% des Nennstroms). Der Rotor muss frei drehen
können, er wird sich dann entsprechend des angelegten Feldes ausrichten.
Dann den Winkel vom Encoder auslesen und den Offset ausrechnen. Es gibt
auch verfahren, die ohne Motorbewegung auskommen, aber das ist etwas
komplexer.
Mit freundlichen Grüßen
Thorsten Ostermann
Vielen Dank!
Ich komme der Sache näher.
Leider muss ich den Code anders schreiben, da er auf einem PSoC5LP
laufen wird. Ich hatte schon erste Tests, bin mir allerdings nicht
sicher, ob das Ergebnis stimmt. Deshalb nochmal zum Verständnis:
Ich habe nochmal das Sinusmuster von AVR447 mit 6 Zahlen angehängt.
Wenn ich es richtig verstanden habe, so wäre bei einem 8Bit PWM der
Wert 1 im Sektor 1: ~10/255 für PWM UH bzw ~240/255 für PWM UL.
Wert 2 in Sektor 1: ~250/255 für PWM UH bzw ~5/255 für PWM UL
Wert 3 in Sektor 2: ~5/255 für PWM UH bzw ~250/255 für PWM UL. (?)
Wert 4 in Sektor 2: ~240/255 für PWM UH bzw ~240/255 für PWM UL. (?)
Wert 5 in Sektor 1: ~5/255 für PWM WH bzw ~250/255 für PWM WL. (?)
Wert 6 in Sektor 1: ~240/255 für PWM WH bzw ~10/255 für PWM WL. (?)
(Falls die Step Tabelle bedeuten soll, dass bei einem Minus sich die
Comparewerte tauschen)
Was soll denn die schwarze Kurve darstellen? Bzw. warum hat die an den
Zonenübergängen (z.B. von 2 nach 3), wo eigentlich die Amplitude maximal
sein sollte lokale Minima?
Mit freundlichen Grüßen
Thorsten Ostermann
Thorsten Ostermann schrieb:> wo eigentlich die Amplitude maximal> sein sollte lokale Minima?
Das sind die sogen. 'Popo' Kurven, die für die Geometrie der meisten
BLDC/PMSM Motore am besten geeignet sind, beim Durchgang eines
Magnetfeldes der Wicklung an einem Permamentmagneten das günstigste
Drehmoment zu erzeugen. Die Spule U durchläuft in diesem Moment das
Maximum des permanenten Magnetfeldes am Rotor und die nächste Wicklung
übernimmt die Weiterbewegung des Motors.
Wenn wir beim Übergang von Sektor 2 zu 3 bleiben: W wird in dem Moment
abgeschaltet, indem U das Maximum durchläuft und V übernimmt.
> Dein> Absolutencoder läuft ja einmal pro Umdrehung über und startet wieder bei> Null.
Nicht unbedingt, aber das kann uns der TE ja nochmal mitteilen. Ich habe
hier Absolutenkoder von Sick Stegmann und Haidenhein, die eine Umdrehung
in 4096 Schritte auflösen und zusätzlich bis zu 4096 komplette
Umdrehungen erfassen.
Das Problem bei solchen Enkodern ist allerdings weniger die genaue
Winkelerfassung, als die Geschwindigkeit, mit der das geschieht. Bei
meinen Enkodern mit SSI Interface wäre es aufgrund der Datenrate nicht
möglich, den Motor mit mehr als ca. 300-500 U/min zu drehen, da ein
Datenpaket schon etwa 20ms benötigt.
Es sollte also ein Enkoder mit parallelen Ausgang sein.
MotorMann schrieb:> Wert 3 in Sektor 2: ~5/255 für PWM UH bzw ~250/255 für PWM UL. (?)
Verwirr mich nicht :-) Du hast den Wert 3 aber in Sektor 3 gezeichnet.
Du kannst den Absolutwert für z.B. Timer 0 eigentlich direkt an der
Kurve ablesen, wenn wir die Totzeit mal weglassen. Ist die Kurve also im
Maximum, ist in UH fast 255 drin und in UL nahezu 0. Das gleiche gilt
analog auch für Timer 1 (VH/VL) und Timer 2 (WH/WL).
Im Prinzip sind das also 3 D/A Wandler in PWM Ausführung.
Selbst bei Multiturn-Encodern muss man zumindest einmalig den
Kommutierungswinkel bestimmen. Wenn man Motor und Regler aus einer Hand
kauft (Siemens, Bosch, Beckhoff,...), dann entfällt das, weil die
Hersteller den Geber mechanisch immer gleich ausrichten und die
Umrichter wissen, wie dann der Winkel eingestellt werden muss.
Das ist aber beim OP nicht der Fall, weil der mit einem Magnet und einem
Hallsensor-IC selbst einen Singleturn Geber aufgebaut hat.
Mit freundlichen Grüßen
Thorsten Ostermann
Thorsten Ostermann schrieb:> Selbst bei Multiturn-Encodern muss man zumindest einmalig den> Kommutierungswinkel bestimmen.
Hab mir gerade mal die Daten des Drehgebers angeschaut, der AS5048A ist
ein Singleturn Enkoder mit 14 bit und kann per Software genullt werden.
Das ist hier evtl. sogar kontraproduktiv, weil dadurch natürlich der
Zusammenhang zwischen Motorposition und Drehgeber nicht absolut ist.
M.E. muss die Position des BLDC also zusätzlich mit normalen Halls
erfasst werden.
@Motormann: Ich habe den Algorithmus von AVR447 auch schon mal auf dem
STM32F1XX implementiert (mit einem 'Advanced Timer') und auf dem XMega
mittels AWEX. Sollte also möglich sein, auch auf PSoC5LP (was auch immer
das ist :-) zum Erfolg zu kommen.
Moin Zusammen,
Was willst du genau machen? Einen Servo Bauen oder n BrushlessGimbal?
Wenn du wirklich richtig die Position regeln willst, brauchst du
zwingend einen unterlagerten Stromregler der dir das Drehmoment regelt
und den Strom auf Bauteilverträgliche Werte begrenzt.
Ob du die SVPWM mit LookUp oder sonst wie rechnest ist egal. Hauptsache
du stellst den richtigen Spannungsvektor wenn der Regler das will.
Und eigendlich sollte dir ein Encoder das Spiel einfacher machen und
nicht komplizierter.
Mach ne richtige FOC. Regel den Strom und der Sollwert davon kommt von
der Positionsregelung.
MfG
Tec
Hallo Matthias!
> Hab mir gerade mal die Daten des Drehgebers angeschaut, der AS5048A ist> ein Singleturn Enkoder mit 14 bit und kann per Software genullt werden.> Das ist hier evtl. sogar kontraproduktiv, weil dadurch natürlich der> Zusammenhang zwischen Motorposition und Drehgeber nicht absolut ist.> M.E. muss die Position des BLDC also zusätzlich mit normalen Halls> erfasst werden.
Unsinn. Man speichert den Offset zwischen Geber-Nullposition und
Startpunkt der Kommutierungssequenz und verschiebt entsprechend den
Winkel den man vom Geber bekommt. Fertig.
Mit freundlichen Grüßen
Thorsten Ostermann
Hallo, falls die Berechnung zu zeitaufwendig und umständlich wird - es
gibt auch 1-Chip Absolutencoder für Motorsteuerungen die gleich UVW mit
generieren und zusatzlich über SSI/BiSS auch absolut ausgelesen werden
können, wie z.B. der iC-MH8. Hier sind verschiedene 1-Chip Motorencoder
Optionen beschrieben:
http://ichaus.biz/Encoder_Motorkommutierungssignale und ein Motorencoder
mit Platinenentwurf ist hier:
http://www.gb97816.homepage.t-online.de/mh8_3.htm beschrieben.
Matthias Sch. schrieb:> Hab mir gerade mal die Daten des Drehgebers angeschaut, der AS5048A ist> ein Singleturn Enkoder mit 14 bit und kann per Software genullt werden.
Lt. Datenblatt geht das übrigens genau einmal, da das OTP Zellen sind.