Forum: Mikrocontroller und Digitale Elektronik Verständnisfrage: BLDC mit S(V)PWM und Winkelencoder


von MotorMann (Gast)


Lesenswert?

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.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

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.

von MotorMann (Gast)


Angehängte Dateien:

Lesenswert?

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?

von MotorMann (Gast)


Lesenswert?

Ergänzung: Mit dem genannten Sinus Algorithmus lief der Motor sehr 
ruhig, hatte jedoch keinen hohen Drehmoment

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

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
PROGMEM uint16_t CSOffsetsForward[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.

von Thorsten O. (Firma: mechapro GmbH) (ostermann) Benutzerseite


Lesenswert?

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

von MotorMann (Gast)


Angehängte Dateien:

Lesenswert?

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)

von Thorsten O. (Firma: mechapro GmbH) (ostermann) Benutzerseite


Lesenswert?

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

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

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.

von Thorsten O. (Firma: mechapro GmbH) (ostermann) Benutzerseite


Lesenswert?

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

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

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.

von Alex E. (tecnologic) Benutzerseite


Lesenswert?

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

von Thorsten O. (Firma: mechapro GmbH) (ostermann) Benutzerseite


Lesenswert?

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

von Horst H. (horst_h44)


Lesenswert?

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.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.