Der folgende Artikel beschreibt, wie man die Drehzahl eines bürstenlosen Gleichstrommotors mittels Modellbauregler und Arduino-Mikrocontroller steuern kann. Der Mikrocontroller erhält die Stellgrösse über USB- Shield per PC mitgeteilt. Natürlich sind auch andere Alternativen zur Werteübermittlung denkbar.
Ein bürstenloser Motor verfügt über keinen Kommutator zur Stromwendung. Stattdessen wird im Stator (das ist der feststehende Teil eines Motors) ein Drehfeld erzeugt, dass einen mit Permanentmagneten bestückten Rotor mit nimmt. Dieses Drehfeld wird mittels einer Steuerelektronik erzeugt. Wer keine Lust hat sich eine Steuerelektonik selbst zu basteln (wie z.B. hier siehe 4.12.2009), der kann einfach einen Brushless Regler aus dem Modelbau benutzen. Der Regler sollte etwas mehr als den Nennstrom des Motors liefern können. Ich habe folgende Komponenten verwendet:
- Arduino Mini V04 Mikrocontroller
- USB Shield für Arduino
- LiPo Akku XCell eco XCell-3/2200 mAh / 11,1V (Achung: für LiPo Akkus braucht man spezielle Ladegeräte, ansonsten herrscht BRANDGEFAHR!)
- DEAN Stecker zum Anschluss des Reglers an den Akku
- Graupner 7224 Compact Controll 45 (bis 45 Ampere)
- Graupner Inline 370 Brushless Motor 11,1V, U/min pro Volt 3900 (oder ein alter Festplattenmotor)
- Graupner Sensorkabel
- Leitungen
Funktionsweise des Brushlessreglers
Der Brushlessregler verfügt über mindestens folgende Anschlüsse:
- Versorgungsspannung
- BEC (Battery Eliminator Circuit) Ansschluss und Impulseingang, normalerweise ist dies die Versorgungsspannung für den Empfänger des Models
- Motoranschluss für den Bruhlessmotor
Die Versorgungsspannung erfolgt normalerweise durch einen Akku. Hier ist auf die Polung zu achten! Nachdem der Regler werksseitig mit einem G3.5 Hochstromsteckersystem ausgestattet ist, könnte ich diesen nicht an meinen Akku anschliessen. Dieser hat eine DEAN Buchse. Deshalb habe ich anstatt dem G3.5 einen DEAN-Stecker drangelötet.
Der BEC Stecker hat zwei Funktionen. Zum einen liefert er die Versorgungsspannung für einen Funkempfänger, zum anderen nimmt er die Impulse zur Steuerung der Drehzahl des Motors entgegen. In dieser Schaltung wird die BEC Versorgung als Versorgungsspannung für den Mikrocontroller verwendet. Der Mikrocontroller hingegen muss den Steuerimpuls erzeugen. Die Leitungen an dem Stecker sind farblich wie folgt codiert:
- Rot: +
- Braun: -
- Orange: Impuls
Die Spannung hängt vom Regler ab. Im Normalfall (und auch in diesem Fall) liegen zwischen Rot und Braun 5V an.
An den Anschlüssen zum Motor erzeugt der Regler ein Drehfeld, der den Rotor des Motors antreibt. Ideal wäre ein Drehfeld das aus drei Sinusförmigen und um 120° versetzten Spannungen erzeugt wird. Der Regler erzeugt drei (gemessene) phasenverschobene Rechteckspannungen. Das funktioniert natürlich auch.
Schaltungsaufbau
Die Schaltung ist experimentell auf einem Breadboard aufgebaut. Am Arduino mini ist PIN 10 (Arduino mini Layout) für das Erzeugen des Steuerimpulses als PWM Signal vorgesehen. Der Widerstand zwischen PIN 10 und dem Controller dient zur Sicherheit. Der ResetPIN wird auf 5V gelegt da der Mikrocontroller sonst unkontrolliert reseten würde. Das USB Shield wird wie gewohnt an die Serielle Schnittstelle RX/TX angeschlossen, und der MinusPIN wird auf eine gemeinsame Masse mit dem BL-Controller gelegt. Die LED ist an PIN 13 angeschlossen und benötigt keinen Vorwiderstand, da Pin 13 bereits einen 1KOhm Widerstand eingebaut hat.
Festplattenmotor als Alternative
Da die Hochleistungs-Elektromotoren aus dem Modellbau teuer sind, kann man zum herumprobieren auch einen alten Festplattenmotor verwenden. Die Motorwindungen in Festplattenmotoren sind meist im Stern geschaltet, um den Anlaufstrom niedrig zu halten. Das erkennt man daran, dass vier, anstatt drei, Anschlüsse vorhanden sind. Ein Anschluss ist der Sternpunkt, an dem die Wicklungen zusammen geschaltet sind, die anderen drei sind jeweils die Wicklungsenden.
ACHTUNG: Das Bild stammt aus der Wikipedia und gehört zum Thema “Sternschaltung von Drehstrohmasynchron-Motoren”. Daher stehen da 400V in der Zeichnung. Das gilt natürlich nicht für Modelbaumotoren . 400V sind LEBENSGEFÄHRLICH!
Durch Messung kann man herausfinden, wo sich der Sternpunkt befindet. Zwischen Sternpunkt und den Außenleitern u1, v1 und w1 sollte der Widerstand immer gleich groß sein. Ich habe dann einfach drei 2,5mm² dicke Litzen an die Kontakte gelötet. Festplattenmotoren haben keine große Leistung, ziehen deshalb keinen großen Strom, und bleiben dementsprechend kühl.
Die Kommunikation zwischen Arduino und Brushless-Regler
Die Impulse sind die gleichen wie sie zur Steuerung von Schrittmotoren Anwendung finden. Der Brushlessregler erwartet ein Rechteckimpuls mit einer Periodendauer von 20 ms. Die Impulsdauer (engl. Duty) beträgt zwischen 1ms (Motor aus/stop) und 1,5 ms (Volle Drehzahl). Die Impulsspannung beträgt 5V. Diesen Impuls muss der Mikrocontroller erzeugen. Der Einfachheit halber bediene ich mich der Bibliothek TimerOne die man hier herunterladen kann. TimerOne stellt einfache Funktionen zum erzeugen eines PWM (Puls-Weiten-Modulation) Signals bereit. Das ist genau der Rechteckimpuls, den man zum Steuern des Brushless-Reglers braucht.
Mit Timer1.initialize(20000); wird ein Timer initialisiert mit Periodendauer 20ms (20000 ns). Timer1.pwm(10,52);erzeugt ein einen Rechteckimpuls auf PIN 10 der eine Impulsdauer (engl. Duty) von etwa 5% der Periodendauer hat. Die Impulsdauer der Funktion pwm(int PIN, int Duty) kann von 0-1024 gehen, wobei 0 einer Impulsdauer von 0% entspricht und 1024 einer Impulsdauer von 100% der Periodendauer. Der Impuls für den Regler muss zwischen 1ms und 1,5ms betragen, also zwischen 5% und 7,5%. Als Integerwert ergibt das ca. 52 für 0% und 77 für 100%. Die Werte sind gerundet. Das ergibt ein Delta von 25, also 25 Stufen, in denen man den Motor stellen kann. Oder ganz einfach 4% – Schritte. Ich habe das ganze mit einem Oszilloskop überprüft, bevor ich den Arduino an den Regler angeschlossen habe.
Die Arduino Software
Die Software (siehe unten “Der Quelltext”) erwartet einen, mit Newline abgeschlossenen, Wert zwischen 0 und 25, wobei 0 “Motor aus” und 25 “Volle Drehzahl” bedeutet. Liest man in den Beispielcodes zu Arduino Serialeingabe wird man feststellen, dass oft eine Verzögerung von 10ms ( delay(100); ) eingebaut ist, damit alle Zeichen übertragen werden können, bevor man mit Serial.read(); diese ausliest. Diesen Weg habe ich absichtlich nicht beschritten. In dem Beispiel wird ein Puffer mit den Zeichen gefüllt, die über die Serielle Schnitstelle gesendet werden. Sind es gültige Zeichen (Ziffer zwischen 0 und 9) und ist der Puffer voll ist oder ein Newline (‘\n’ oder in ASCII 10) Symbol kommt. Eine Verzögerung ist da nicht nötig. Der Puffer ist drei Zeichen lang, um eine Zahl mit zwei Ziffern und das ‘Newline’-Zeichen aufnehmen zu können.
Der Quelltext
Ich denke dieser ist selbsterklärend.
- #include <TimerOne.h>
-
- const byte pwmsender = 10;
- const int fanspeedoffset = 52;
- char buffer[3];
- int fanspeed = 0;
- int i=0;
- boolean isfanspeedcomplete=false;
-
- void setup()
- {
- Serial.begin(9600);
- pinMode(pwmsender, OUTPUT);
- Timer1.initialize(20000);
- Timer1.pwm(pwmsender,52);
- }
-
- /**
- * setzt den PWM Impuls, um Modelbausteller (regler) für Bürstenlose Motoren (brushless)
- * zu regeln. PWM - Frequenz 50Hz (Periodendauer 20ms) , Impulslänge für Motor aus: 1 ms, für Motor vollgas: 1,5 ms
- * Entspricht einer Duty von 5% bis 7,5% bei 20ms Periodendauer. Bei einer Auflösung von 1024 (10bit) sind das etwa 52 - 77.
- */
- void setPWMRate()
- {
- Serial.println(fanspeed);
- int duty = fanspeedoffset + fanspeed;
- if(duty>77){
- duty=52;
- }
- Timer1.pwm(pwmsender, duty);
- Serial.print("Duty: " );
- Serial.println(duty);
- }
-
- /**
- * liest die Zeichen von Serial solange bis ein '\n' (ASCII-Wert 10) gesendet wird oder der Zeichenpuffer buffer voll ist.
- * Danach wird fanspeed gesetzt und isfanspeedcomplete auf true gesetzt.
- * buffer max. Zwei Ziffern speichern.
- * Zeichen >9 und <0 sind ungültig, und werden ignoriert.
- **/
- void processFanSpeedMessage()
- {
- int newfanspeed = 0;
- char digit=Serial.read();
- if( digit != 10 && i<2){
- if(digit>='0' && digit<='9')
- buffer[i++]=digit;
- }
- else{
- buffer[i]=0;
- newfanspeed = atoi(buffer);
- fanspeed = newfanspeed;
- isfanspeedcomplete=true;
- i=0;
- Serial.print("Fanspeed: ");
- Serial.println(fanspeed);
- }
- }
-
- /**
- * prüft, ob etwas über Serial angekommen ist, und lässt dies verabeiten.
- * wenn ein kompletter Wert über Serial gelesen wurde, wird der PWM Impuls gesetzt.
- **/
- void loop()
- {
- if(Serial.available()>0 )
- {
- processFanSpeedMessage();
- }
- if(isfanspeedcomplete)
- setPWMRate();
- isfanspeedcomplete=false;
- }
Und was macht man nun damit?
Man kann zum Beispiel den Motor in einen Impeller einbauen, und diesen Impeller in Verpackungsmaterial einbauen, und man erhält den Prototypen eines Luftkissenfahrzeugs. Zugegeben: nicht schön, aber dennoch Lustig.











Hi,
vielen Dank für diesen sehr guten Artikel. Ich habe aufgrund deines Posts mir auch einen Brushless Motor mit einer Nosrom Controller zugelegt.
http://www.nosram.com/en/products/electronic-speed-controls/car/mirco/produkt/shock-40-sensorless-brushless-speed-control/details/
Alles funktioniert sehr gut. Was ich nicht hinbekomme ist den Motor in der anderen Richtung zu drehen. Genau das sollte der o.g. Controller können. Ich dachte das evtl. ab einer Impulsehöhe er in die andere Richtung drehen könnte, tut er aber nicht.
Hast Du evtl. eine Idee wie man einen ESC Controller den Brushless Motor Reversen per Arduino könnte?
Ich kann natürlich die Pole vertauschen, ist natürlich nicht ganz das was der Controller können sollte.
Danke.
Gary
Hi Gary,
es freut mich, dass dir der Artikel geholfen hat.
Leider habe ich nicht so richtig Erfahrung mit ESCs die in der Lage sind zu reversen. So weit ich weiß, kocht da jeder Hersteller sein eigenes Süppchen. Die einen “reservieren” 1/3 der Knüppelstellung für den Bremsvorgang/Rückwärtsvorgang und 2/3 um Gas zu geben. Andere machen es eben anders.
Aber es scheint bei allen Controllerherstellern so zu sein, dass Drehrichtung und Geschwindigkeit über die Impulsdauer geregelt wird. Nie über die Impulshöhe.
Das findest du eventuell herraus, wenn du dir die Specs entsprechender Funkempfänger (den ersetzt du ja im Prinizip durch den Arduino) anschaust.
Aus den PDFs zu deinen Nosrom Controller geht das aber leider nicht hervor. Vielleicht verrät ja der Support von Nosram was der Controller. Gute Hilfe könntest du auch in Modellbauforen bekommen.
Las mich wissen, wenn und vor allem wie du es geschafft hast.
Hi Gary, vielen Dank für deine Seite! ich will einen HDD-Spindelmotor antreiben. ich habe einen ESC von Skywalker-20A. Aktuell versuche ich es zu testen. Ich habe zwei Fragen:
- kann ich den ESC mit einem Netzteil (5V,2A – statt Akku) betreiben?
- BEC-Stecker (bei mir schwarz-rot-weiss) macht mir Probleme: wenn ich das richtig verstehe muss auf sw 5V und weiss Signale geben (oder umgekehrt) – rot(mitte) bleibt unbenutzt. Ich wollte mit 5V (vom netzteil) anfangen – dabei ist mein dünnes Kabel sofort recht heiss geworden hmm. Da du die 5V vom arduino benutzt, darf eigentlich nicht viel Strom fliessen… Die Signale habe ich der Einfachheit halber mit PWM zum Testen erzeugt.
Wo liegt mein Fehler – Hast du eine Idee?
Grüße
Hi Georg,
den ESC kannst du auch mit einem Netzteil betreiben. Der benötigt ja genau die 5V.
Die Farbcodierung sollte aber wie folgt sein:
Rot: +
Schwarz: -
Weiß: Impuls
Wenn du dass so anschließt, sollte dass ganze flutschen.
Womit erzeugst du denn das PWM genau?
Grüße
Ivan Kersevan
dank! PWM einfach direkt per arduino. Ich probiers nochmal mit deiner Software.
Zum Anschluß: vom netzteil + und GND an + und – vom ESC. und beim BEC rot (also mittleres Kabel) an +5V vom Netzteil und Impulse an Weiss. GND vom Arduino verbinden mit GND vom Netzteil. so ok?
Hi,
ja, so habe ich es auch gemacht. Da ist mir doch glatt noch ein Fehler im Schaltbild aufgefallen. Da fehlt nämlich die Versorgungsspannung fürs BEC. Das werde ich die Tage mal ändern.
Grüße aus Fürth