Sensorlose BLDC Ansteuerung

Aus der Mikrocontroller.net Artikelsammlung, mit Beiträgen verschiedener Autoren (siehe Versionsgeschichte)
Wechseln zu: Navigation, Suche

Grundlegendes zum Artikel

Dieser Artikel ist im Wesentlichen als Ergänzung zu:

zu verstehen. Es wird jedoch nicht mit einem analog Komparator, sondern mit einem ADC gearbeitet, wie hier beschrieben:

Einleitung

Bei der sensorlosen Ansteuerung wird üblicherweise die BEMF der in der Luft hängenden Phase des BLDCs ausgewertet, um den nächsten Kommutierungsschritt einzuleiten. Hierbei treten diverse Probleme auf:

  • Die BEMF ist bei niedrigen Drehzahlen nur sehr gering und von daher schwer zu erfassen
  • Der BLDC muss häufig lange Zwangskommutiert werden, bevor er startet
  • Die Inbetriebnahme ist umständlich und müßig
  • Einkoppelnde Störungen auf den analog Komparator durch die PWM

Abhilfe

Man integriert die BEMF Spannung. Dabei achtet man darauf, dass die BEMF-Spannung größer bzw. kleiner als Endstufenspannung/2 ist, bevor man anfängt zu integrieren. Synchronisiert man seine Messung nun noch mit der PWM, so sind auch eingekoppelte Störungen kein nennenswertes Problem mehr.

Mikrocontroller

Bei der Wahl des µC entschied ich mich für meinen lieblings 8-Bit AVR, den Atmegaxx8. Dieser, so dachte ich, hat genügend Ressourcen. Jedoch trat ein Problem auf, das mich im Nachhinein aber nur bedingt stört, da es ja funktioniert:

Der ADC ist zu langsam: Der ADC eines normalen AVRs kann mit maximal 200kHz samplen. Bei 20MHz CPU Clock ergibt sich ein Prescaler von 128, somit läuft der ADC auf 156,25kHz. Eine Wandlung dauert somit 83,2µs. Demnach wählte ich eine PWM Frequenz von 10kHz (100µs Periodendauer, pfeift furchtbar) um noch etwas Reserven zu haben. Idealerweise müsste ich die BEMF auch mit 10kHz samplen, was ja grundsätzlich möglich wäre, wenn nicht noch andere Werte mit gesamplet werden müssten wie:

  • Spannung an der Endstufe
  • Strom
  • Flussintegralgrenzwert

Somit entschied ich mich, die BEMF mit 5kHz bzw. jede zweite Messung zu machen, und die anderen drei Werte nur jede 5KHz/3. Bei einer nächsten Version würde ich wohl auf einen STM32F4 zurück greifen. Dessen ADC(s) sind viel schneller und auch komfortabler zu bediehnen. Der ADC des AVR wird von einem Timer automatisch gestartet (10KHz), welcher aber kurz vor Beginn des nächsten PWM-Zyklus den ADC startet.

Schaltung

Zur Schaltung gibt es im Wesentlichen nicht viel zu sagen. Die Endstufe besteht aus 6 MOSFETs und wird vom µC gesteuert. Ein 100mR Widerstand ermöglich eine Überwachung des Motorstroms; falls dieser zu hoch wird setzt die Strombegrenzung ein und die Endstufe wird kurz abgeschaltet. Es ist taktisch sinnvoll, sowohl BEMF-Spannungsteiler als auch Versoungsspannungsteiler im selben Verhältnis zu skalieren, so lassen sich die Werte direkt zueinander in Bezug setzen, ohne das herumskalieren zu müssen. Alle Bauteile mit "n.i.p." sind nicht bestückt.

Software

Die Software ist in C geschrieben und wurde mit Atmel Studio entwickelt. Das Programm ist sehr überschaubar. In der while(1)-Schleife werden Werte über die serielle Schnittstelle ausgegeben, das wars schon. Der Rest spielt sich in der PWM-ISR ab, welche mit 10kHz aufgerufen wird:

Als erstes wird das ADC-Register in Abhängigkeit vom letzten ADMUX ausgelsen. Anschliessend wird der MUX für die nächste Messung vorbereitet. Die eigentliche Messung wird jeweils kurz vorm Timerüberlauf gestartet, damit der ADC mit seiner Messung beginnt, kurz nachdem die PWM wieder von vorn beginnt (Der ADC benötigt durchaus etwa 12µs bis er misst, nachdem er sein Startsignal bekommen hat :-) ).

Danach wird eigentlich nur noch geguckt, was mit den Werten los ist. Ist der Strom in Ordnung bzw. hat die BEMF schon U/2 über bzw. unterschritten und kann mit der Integration begonnen werden? Wird die Integrationsgrenze überschritten wird weiter kommutiert.

Für den Fall, dass der BLDC ungünstig steht und nicht sofort anläuft wird einmal "per Hand" bzw. alle 100ms eine Zwangskommutierung durchgeführt. In der Praxis muss eigentlich bei meinem 2 polpaarigen Modellbau BLDC nur 1x Zwangskommutiert werden bzw. manchmal auch garnicht.

Da der Motor immer im Interrupt kommutiert, lässt sich auch recht bequem die Drehzahl errechnen indem man die Interrupts zwischen 6 Kommutierungen zählt. Daraus lässt sich dann die Drehzahl einfach berechnen:

[math]\displaystyle{ n = \frac{f_{pwm} \cdot 60}{Counts \cdot Polpaarzahl} }[/math]

wobei man natürlich gleich 60 und Polpaarzahl miteinander verrechnen könnte.

Datei:Programm.zip

Oszillogramme

Aufbau

Known Issues

Der AVR-ADC ist für hohe Drehzahlen zu langsam bzw. ist die PWM -und Samplefrequenz mit 10/5KHz zu langsam um ausreichen Auflösung für das Flussintegral zu bekommen. Die Problematik ist dann, dass nur 1-2 Samples pro Kommutierungsschritt zur Verfügung stehen, was vorn und hinten nicht ausreichend ist.

Lösungen:

  • Man verwendet einen schnelleren externen ADC
  • Man schaltet bei hohen Drehzahlen in den Komparatormodus
  • Anderer µC mit schnellerem ADC verweden z.B. STM32F4 - Derivat

Lösung mit einem schnelleren Controller

Der Controller wurde durch einen STM32F050K6 ersetzt. Dieser sampelt nun im Center-Aligned PWM Mode in der Pulsmittte alle Werte und schaufelt diese per DMA in einen Buffer. Die PWM Frequenz beträgt 20kHz. Klappt alles prima.

Ich habe den BLDC nun in ein Plexiglaswürfel "gesperrt" und weiter geforscht. Es funktioniert nun sehr gut. Es wird vor dem Anlauf die Rotorposition bestimmt und der Rotor in eine bestimmte Stellung gebracht. Das Ergebnis ist, dass der Rotor sauber anläuft.

Hier das Programm: Datei:Programm STM32.zip