Hallo,
Zur Zeit arbeite ich an einer BLDC Positionier Steuerung mitsamt
Encoder.
Soweit läuft alles. Der BLDC läuft zur Zeit Zwangskommutiert durch die
Sinustabelle sehr ruhig und ruckelfrei. Der Encoder gibt die Lage des
Motors in 12 Bit aus, soweit so gut.
Mein einziges Verständnisproblem ergibt sich aus dem Zusammenspiel von
beidem.
Konkret denke ich daran, die Sinustabelle bzw das Vielfache davon mit
dem Encoder zu synchronisieren. Dadurch würde korrekt kommutiert werden,
jedoch bin ich mir unsicher, wie ich nun dem Motor sagen kann, er soll
in die eine oder andere Richtung fahren.
Könnte ich das Ganze durch einen variablen Offset in der Tabelle lösen,
welcher die Sinustabelle dann voreilen lassen würde? Oder habe ich da
eventuell Probleme durch eine geringe nicht-Linearität des Encoders,
sprich: der Motor rollt einfach langsam los, weil Encoder und Tabelle an
einigen Stellen nicht genau genug synchron laufen?
Oder gibt es da ganz andere Ansätze?
Erstmal Vielen Dank!
Lookuptables (Rotorwinkel, naechster Ausgabewinkel) fuer beide
Drehrichtungen.
Dann einfach schauen, welche Richtung du haben willst, was der aktuelle
Winkel ist und dann einfach die passende Ausgabe auswaehlen.
Das ganze kannst du fuer hohe Drehzahlen relativ grob machen (1-3Grad)
und natuerlich auch drehzahlabhaengig Werte ueberspringen.
Fuer sehr geringe Drehzahlen kannst du zwischen den einzelnen Eintraegen
interpolieren und so neue Werte erzeugen.
Wenn der Encoder absolute Daten über eine serielle Schnittstelle liefert
sind diese direkt mit der Tabelle verküpfbar, wenn beide die gleiche
Einteilung haben(z.B. je Grad einen Tabellenwert). Falls es nur eine
ABZ-Schnittstelle ist, muss die Position und Richtungsänderung gezählt
werden. Es gibt hier ( http://www.gb97816.homepage.t-online.de/index.htm
) ein gutes Beispiel wie ein Motor mit dem 1-Chip Encoder iC-MH8
arbeitet und welche Ergebnisse erzielt werden. Der iC-MH8 (
http://ichaus.de/product/iC-MH8 ) kann auch die Kommutierungssignale UVW
abgeben und entweder ABZ, Sinus/Cosinus oder die absolute Position mit
12 Bit ausgeben.
Moin,
hast du mal Feldorientierte Regelung in Betracht gezogen? Wenn du schon
die genaue Position hast, dann kannst du mit präzise, Drehmoment,
Drehzahl und Position regeln. Dazu siehst du dir die SVPWM an, findest
auch einige Beiträge im Forum dazu. Dann siehst du dir mal die
d/q-Transformation auf Wikipedia an. Damit kannst du dann die Innere
Stromregel Schleife aufbauen. Dann darüber die Drehzahl regeln und ganz
außen machst du die Positionsregelung.
Alles andere ist gebastelt, was bei geringer Rechenleistung durch aus
legitim ist.
Wenn du's unbedingt mit der Sinustabelle machen willst/musst, nimm die
Rotorlage (viel mehr die Flusslage also der Winkel in dem die N-S
Strecke deiner Permanentmagneten liegt) und lasse deine Sinustabelle 90°
voreilen.
Jenach dem ob du im Stillstand 90° nach rechts vom Fluss gehst oder nach
Links gibst du die Drehrichtung vor. Aber bitte implementiere wenigstens
eine U/f Kennlinie damit deine Maschine keine Heizung wird.
Gruß
Tec
Vielen Dank für die Tipps!
@Horst: Ich setze derzeit auf Absolutencoder von AMS, welche zur Zeit
nicht dein genanntes Feature besitzen. Daher werde ich wohl vorerst
anders arbeiten müssen.
@Tec: Danke erstmal. Ich hatte zuerst auch über eine FOC nachgedacht,
zumal es eine recht gute AppNote von Microsemi gibt:
http://www.actel.com/documents/SF_FOC_PMSM_HALL_UG.pdf
Leider habe ich mir auf der Hardware den Zugang zu den Motorphasen
versperrt und kann daher dort weder Strom noch Spannung messen.
Zudem bin ich rechentechnisch zur Zeit etwas knapp an Leistung.
Somit sind vorerst meine Möglichkeiten begrenzt. Ich werde allerdings
nach den ersten Gehversuchen die FOC in einer neuen Hardware
realisieren.
Bis jetzt habe ich nur: 12 Bit (Absolut)encoder
und meine Sinustabelle mit 3rd Harmonic.
Mein Verständnisproblem ist folgendes:
Nehmen wir theoretisch an: Ich habe einen 12 Bit Encoder, eine 12 Bit
Sinustabelle, die aufgrund des Motors, welcher 7 Magnetpaare hat,
dementsprechend 7 mal durchlaufen wird für 360°.
Nun möchte ich meine 7x12Bit Sinustabelle durchlaufen lassen.
Dementsprechend will ich nicht unbedingt den Encoder an die Tabelle 1 zu
1 koppeln, sondern die kompletten 28672 Schritte pro Umdrehung
durchlaufen lassen.
Wäre es falsch gedacht, den Code so aufzubauen, dass folgendes gilt:
Solange Sinustabelle und Encoder einen gewissen maximalen Abstand
einhalten, so lange eilt die Sinustabelle 90 elektrische Grad dem
Encoder voraus.
Sollte der Motor eine wechselnde Last erfahren und damit nicht folgen
können, so gilt: Sinustabelle = Encoder + 90° Voreilung?
Und könnte ich ferner (ja ich weiß, Bastelei), den Abstand zwischen
Encoder und Sinustabelle durch einen Regler schieben und bei
Vergrößerung des Abstands die Stromstärke im Motor erhöhen?
Der Motor wuerde aufgrund seines Innenwiderstands kein Heizofen werden.
Ich habe bei dem Encoder derzeit knapp 1 KHz Sample Rate bei max.
100rpm, die der Motor drehen soll. Somit hätte ich theoretische genug
Messwerte, um das zu versuchen.
Oder liege ich da völlig falsch? Es ist für mich die erste BLDC
Steuerung, welche Positionieren und nicht nur sich drehen soll.
Zum oben genannten:
Die LUT würde dann über einen variablen Wert hochgezählt werden, welcher
sich aus der Soll/Ist-Position des Motors zum Zielwinkel berechnet.
Der Encoder würde somit nur dazu dienen, dass die LUT dem Motor nicht
davonrast durch oben genannte Maßnahmen.
Moin,
dieses ganze If then else gedöns mit der Sinustabelle vergiss ganz
schnell.
1. Kannst du wenigstens die gesamt Stromaufnahme messen?
2. Zur Drehfeldregelung. Du nimmst IMMER einen Werte 90° links oder
rechts von deiner Rotorlage, alles andere macht aus deinem Motor eine
Heizung( und der Innenwiderstand der Wicklung ist der Heizkörper.
3. Du hast eine Sollposition, die vergleichst du mit der Istposition ->
PI Regler und dessen Ausgang vergleichst du als Drehzahl gesehen mit der
Aktuellen Drehzahl. Das gibste auf nen weiteren PI Regeler der Ausgang
des PI Reglers ist die Amplitude deines Sinus und das Vorzeichen des
Regler aus gangs sagt links oder rechts 90° der Rotorlage ist dein
Sinus.
Wenn du das machst regelst du im inneren Kreis zwar nur die Spannung da
die aber aufgrund der geringen Drehzahl und der wahrscheinlich kleinen
Induktivität des Motors erst mal relativ gut dem Strom entspricht ist
das OK. ggf. musst du bei höheren Drehzahlen, Drehzahl abhängig sogar
mehr als 90° voreilen um die Wiklungsinduktivität zu kompensieren was
sonst der Stromregler tun würde das kann man mit Kenntnis der
Wicklingsinduktivität und des Wicklingswiderstandes vorsteuern.
Gruß
Tec
Soweit so gut.
Leider bin ich auf meiner Hardware nicht in der Lage, den Strom zu
messen, da noch andere Motoren Strom ziehen werden.
Ich habe erstmal einige Tests gemacht und der Motor läuft eigentlich
ganz sauber. Trotzdem habe ich Verständnisfragen:
Ohne eine ordentliche FOC muss ich eine Sinustabelle einbauen.
Woran orientiert sich, wieviel Auflösung diese bekommen soll?
Bei 12 Bit Encoder wäre es sinnlos mehr als 4096 "Schritte" pro
Motorumdrehung zu haben,oder?
Aber wie dimensionier ich das am Besten? Soviel wie ich an Speicherplatz
opfern kann und der Encoder Auflösung hat?
Und wenn der Motor im Stillstand trotzdem ein Haltemoment aufweisen
soll, wie würde man sowas dann umsetzen?
Sprich: Zum Beispiel bei Direct-Drive Positionierung?
Die Fragen stell ich nur, um das Thema danach besser verstanden zu
haben.
Vielen Dank!
Moin,
Das du den Strom nicht messen kannst ist erst mal nicht die Hürde.
Was die Sinustabelle angeht würde ich aus Resourcen und Geschwindigkeits
Gründen den Folgenden Artikel mit der Implementierung aus dem unteren
Thread empfehlen.
http://www.mikrocontroller.net/articles/Frequenzumrichter_mit_RaumzeigermodulationBeitrag "SVPWM mit LPC1769"
Damit nutzt du für deine 3-Phasen Sinus Spannung deine komplette
Versorgungsspannug aus.
Dann würde ich mir aus dem Encoder den Winkel bestimmen gern als 0-4095
= 0 - 2*PI und damit gehste in die SVPWM. Was die Genauigkeit der
Tabelle angeht, glaube ich das der Algo aus dem Thread das mit CORDIC
gemacht hat, dann hätteste volle Genauigkeit. bin mir aber nicht sicher.
Was das HalteMoment angeht. Folgendes Beispiel:
Du bingst Drehmoment X auf die Welle auf dann muss der Motor folglich -X
leisten, dafür benötigt er einen Stromvektor senkrecht zur Rotorlage
(was du ja nach der beschriebenen Methode immer hast) in dir Richtung -,
wenn wir sagen + ist CW und - ist CCW dann bedeutet das, Das Drehmoment
X wirkt nach links also muss dein Strom Rechtsrum um 90° voreilen. Du
hast jetz halt nur Gleichstrom durch die Wicklungen.
Aber wie kompensieren die Regler das Drehmoment:
Gehen wir vom stationären Zustand aus. Du bist auf Sollposition -> dein
Positionsfehler(Schleppfehler in den Büchern) ist quasi 0, damit gibt
der Positionsregler eine Drehzahl von 0 vor denn erwill ja an der
Position Bleiben. Damit dein Drehzahlregler seinen Sollwert von 0
Umdrehungen einhalten kann muss er eine Spannung nach rechts um 90°
voreilend stellen mit einer Amplitude die genug drehmoment erzeugt damit
das moment X ausgeglichen wird. Das übernimmt der I Anteil des PI
Drehzahl Reglers der hat nähmlich auf Grund eines vorherigen Fehlers,
der sich zwangsläufig einstellt, wenn er nicht dagegen geht. den
Stellwert für die Spannungsamplitude bereits erhöht.
Dynamisch bedeutet dis fälls Drehmoment X weg, Dreht dein Motor in CCW
Richtung los, die Position und Drehzahl weichen in CCW Richtung ab und
der Positionsregler gibt aufgrund des Schleppfehlers eine Drehzahl im
Uhrzeigersinn vor, da sich der Antrieb Gegen den Uhrzeigersinn dreht,
ist der Fehler für den Drehzahl regler noch größer weil er ja vom
Positionsregler w in CW gesagt bekommt. -> ergibt ein eie Spannung links
90° in CW richtung mit ordentlich Amplitude vor. Bis wider die
Sollwpostition erreicht ist und und sich wider der stationäre Zustand
einstellt.
Bildlich, wenn du einen Helbel ander Welle hast. Und drückst den nach CW
dann kannst du das etwas aber der Antrieb baut Drehmoment auf und hält
gegen wenn wer mehr Drehmoment hat als du aufbringst dann erreicht er
wieder seine Sollposition. Lässt du schnell loss wird der Hebel leicht
überschwingen und dann wieder auf Postion sein.
Vorraus gesetzt die Regler sind alle gut eingestellt. hält er sauber die
Position. Und wird sich an einem Virtuellen Master(laufender
Postitionswert) wie ein Schrittmotor verhalten.
Das ist dann bis auf die kompensation des Stromwinkels eine saubere
ServoRegeleung wie sie ein moderner Antriebsumrichter macht.
PS: Fange doch erst mal so an das du die SVPWM übernimmst und ein
Drehmoment stellen kannst. Also bei Positivem Eingang stellst du eine
proportionale Spannungsamplitude die nach rechts 90° dem Rotor voreilt.
und bei Negativ eben links mit ebenso einer Amplitude.
Dann kannste anfangen die Drehzahl aus der Positionsänderung zu
bestimmen und den Drehzahl regelkreis Aufbauen und einstellen. Und dann
erst den Postions kreis.
Gruß
Tec
Hallo nochmal,
Ich hatte bis vor einigen Tagen noch keine Zeit zur Umsetzung, jedoch
ergibt sich für mich nun das nächste Problem bei der Drehzahlberechnung:
Ich arbeite wie oben genannt mit einem Absolutencoder. Dieser springt
bei einem Messwert immer zwischen zwei Werten hin und her. Zudem liefert
er die Messwerte mit "nur" 1KHz. Hierdurch kann ich nicht wie bei einem
inkrementalgeber einfach die Zeitabstände zwischen den Impulsen
messen und daraus die Drehgeschwindigkeit errechnen.
Der Motor soll zudem einen sehr langsamen Drehbereich haben
(zwischen 5-90rpm). Der Encoder misst die Umdrehung in 12Bit.
Mir fällt nur ein, jeden zehnten Messwert mit dem Ersten zu vergleichen
und dann diese Differenz zur Drehzahlberechnung zu verwenden.
Ich bin mir jedoch nicht sicher, ob man das so machen kann.
Denn die Positionregelung findet mit 100Hz statt und wird von äußeren
Sensoren geregelt. Das Verwenden von 10 Messwerten zur Drehzahlregelung
würde dann nur noch mit 100Hz stattfinden.
Ich bin mir eigentlich sicher, dass die innere Regelungen wesentlich
schneller stattfinden sollte als die Äußere Regelung, oder liege ich da
falsch?
Wäre gut, wenn es dafür noch einen eleganteren Weg geben würde.
Gruß,
Der MotorMann
Hi,
warum willste jeden 10. Postionswert nur auswerten. Für die Drehzahl
nimmst du die Differenz der letzten Position zur neuen Position und das
immer fertig, da ist doch nix bei. Das das vllt. zappelt ist bei den
Geschwndigkeiten erstmal nicht dein Problem sondern Problem des Reglers
wenn der Robust genug eingestellt ist , also nicht so empfindlich, dann
wird das gehen.
Gruß
Tec
Hi,
Genau darin sehe ich das Problem (oder ist es garkeins?) :
Nehmen wir an, dass der Motor mit 60 rpm dreht.
Dies entspricht einer Umdrehung in 1 Sekunde, hierbei durchfährt er die
4096 Positionen. Somit würde bei 1 KHz zwischen jedem Wert nur eine
Differenz von etwa 4 bleiben.
Würde der Motor 30 rpm haben, so wäre die Differenz ungefähr 2.
Bei 10 rpm würde ich allerdings nur noch eine Differenz von ~2/3 haben.
Wie kann ich damit dann noch regeln oder habe ich das Konzept falsch
verstanden?
Gruß,
MotorMann
Das ist bei den langsamen Drehzahlen schon ein Problem. Wenn dann würde
ich die Werte durch ein IIR Filter 1. Ordnung jagen. Und das probeweise
auf 5 Schritte Dimensionieren.
Also: Drehzahl(k) = (Positionsdifferenz(k)/4096*1000Hz + 4*
Drehzahl(k-1))/5
K ist der Schrittindex.