Řízení Brushless DC motoru 57BLF03 s driverem BLDC-8015A pomocí Arduina
autor: Johny, arduino, dne 1.1.2020
Rozhodl jsem se vyzkoušet BLDC motoru od Longs motor vybavený hallovou sondou. Konkrétně jde o motor 57BLF03 a řídící desku BLDC-8015A – na odkazu je jiný driver (DCBL-0115A), ale zdá se, že jde jen o jiné označení pro stejné zařízení. Vše ostatní sedí.
Motor i driver jsem koupil na eBay za v přepočtu cca 3000 Kč. Příjemě mě potěšila rychlost dopravy – z Číny do ČR to zvládli za 2 dny! Bohužel další 3 dny to vyselo na celnici a bylo mi dopočteno DPH asi 550Kč + 490Kč za zprostředkování proclení firmou DHL. Mizerové!!!
Ukázka zapojení
Funkční zapojení na mém stole.
Brushless DC motor 57BLF03
Jedná se o kombinaci krokového a Brushless DC motoru. V podstatě jde o obyčejný brushless DC motor (inrunner), který navíc obsahuje 3× hallovu sonda. Díky tomu má řídící jednotka informaci o tom, jak se motor „otáčí“ a může počítat „kroky“, případně motor krátkodobě přetížit bez rizika poškození – ví, že se pootočil.
Motor tak spojuje výhody krokového a DC motoru. Rozsah otáček je od nuly do cca 3000 ot/m a co je největší výhoda – v celém rozsahu otáček má téměř konstantní kroutící moment 0.6Nm−1. V peaku pak dokáže až 1.8Nm−1. Efektivita motoru je kolem 0.066 N-m−1/A. Udávaný výkon motoru je 188W, maximální otáčky jsou 3000RPM.
Řídící jednotka dokáže motor ovládat na základě analogového vstupu nebo PWM signálu. Je třeba ovládat i směr (samostatně) a navíc je možné využít elektronickou brzdu. (Tu zatím nepoužívám). Příjemné je, že řídící jednotka očekává 5V signál a deklaruje max. spotřebu 5mA – což nám dá možnost přímého připojení Arduina.
Videoukázka zapojení a funkce
Finální podoba testovacího zapojení včetně ukázky debug výpisu v serial monitoru.
Zapojení motoru a napájení
Napájení je libovolné stejnosměrné napětí 24V a cca 200W. Já bohužel na testování 24V zdroj nemám, napájím tedy motor i driver 18V a vše funguje.
| Označení na driveru | Color | Barva kabelu |
|---|---|---|
| DC+ | VCC +24V | + napájení 24V |
| DC- | GND | – neboli zem 24V |
| U | YELLOW | Žlutý kabel |
| V | GREEN | Zelený kabel |
| W | BLUE | Modrý kabel |
Zapojení motoru – hallovy sondy
Hallovy sondy potřebují napájení. To nám poskytuje přímo driver. Dle výrobce by napájení hallových sond mělo být mezi 5V a 20V. Z driveru jde asi 14V. Dále motor obsahuje tři vodiče, žlutý, zelený a modrý. Každá barva analogicky odpovídá cívce z napájení, tedy je zde analogie HW=W(modrá), HU=U(žlutá), HV=V(zelená).
| Označení na driveru | Kabel | Popis |
|---|---|---|
| REF- | BLACK – GND | Černý kablík (zem) |
| HW | BLUE | Modrý |
| HV | GREEN | Zelený |
| HU | YELLOW | Žlutý |
| REF- | RED – VCC | Červený |
Driver dále obsahuje dva přepínače – dipswitche. Pro nás je důležitý hlavně switch 2 – je třeba ho přepnout do polohy OFF – tím dáme najevo, že chceme driver řídit PWM signálem. Samozřejmě nesmíme zapomenout propojit GND s ENBL – tím aktivujeme otáčení.
Zapojení arduina a vysílačky
Používám Arduino pro mini, tedy verze adruida bez USB portu. Programuje se pomocí samostatného převodníku USB na seriovou linku (5V logika). Pokud máte arduino s USB portem, tak se TX a RX portem zabývat nemusíte a prostě arduino připojíte do USB a fungujete.
Výhoda arduina bez USB je zejména ve velikosti a ceně – dá se sehnat už kolem 30Kč.
USB je stejně třeba jen na programování, dále už potřeba není a jen překáží ;-)
| ARDUINO | Použití | Poznámka |
|---|---|---|
| VCC | Napájení | 5V napájení, zatím beru z USB |
| GND | GND – zem | Propojím všechny země, GND driveru, GND vysílačky a GND z USB |
| RX | RX / FTDI | pro programování z PC |
| TX | TX / FTDI | pro programování z PC |
| PIN2 | Radio | Připojeno do přijímače vysílačky, kanál 1 (PWM režim) |
| PIN3 | Driver AVI | Pro řízení rychlosti přes PWM |
| PIN4 | Driver R/F | Pro řízení směru otáčení CW/CCW |
Programování Arduina
Tak, pokud je vše zapojeno dle popisu, tak teď stačí arduino naprogramovat aby vykonávalo požadovanou funkci – řídilo motor.
Celé řízení se v podstatě omezuje na dekódování modelářského PWM signálu a jeho přepočet na řídící signál pro motor. Do budoucna bude možné snadno implementovat dorazové snímače pro automatické zastavení motoru při dojetí na konec dráhy.
PWM signál z vysílačky čtu pomocí interuptu – při každé změně napětí přijímače se zavolá funkce, která spočítá čas od poslední změny. Tím získávám číslo (v mikrosekundách) které po přepočtu používám na řízení motoru.
V případě modelářského PWM signálu je pro minimální hodnotu cca 1000us, maximální hodnota pak je cca 2000us. Středová pozice páčky odpovídá cca 1500us. Protože každá vysílačka má tyto hodnoty trochu jiné a navíc střední poloha páčky může mírně kolístat, rozhodl jsem se do programu implementovat pole 4 hodnot reciever_ranges. První a poslední hodnota určuje rozsah vysílačky, prostřední hodnoty vymezují tzv. deadband – tedy mrtvé pásmo kdy se nic neděje – rozuměj kdy se motor netočí.
Ukázka „minimální“ (po přejetí myší maximální) hodnoty na osciloskopu (dílek má 500us, tedy dva dílky odpovídají 1000us).
Inicializace proměnných
První část programu deklaruje proměnné. Jsou zde popsané piny pro řízení rychlosti a směru. Pozor při změnách – pin pro řízení rychlosti musí podporovat PWM! Pin pro vysílačku zase musí podporovat interupt.
int pinMotorSpeed = 3; int pinMotorDir = 4; int actMotorSpeed= 0; int actMotorDir = 1; int actMotorDirLast = 1; int rx_pulse_width=0; int rx_last_pwm_error=0; unsigned long reviever_pwm_pulse_width = 0; unsigned long reviever_pwm_pulse_width_last = 0; //Radio constant: 0-1 CCW speedm, 1-2 deadband, 2-3 CW speed int reciever_ranges[4] = {983,1488,1500,2010};
Nastavení arduina po zapnutí
Tento blok kódu je zde kvůli nastaveni po zapnutí. Nastaví se nějaké výchozí hodnoty, nastaví se režimy fungování portů (vstupy, výstupy) a hlavně se zaregistruje funkce pro interupt na pinu 3 pro změnu stavu. Dále se nastaví rychlost seriového portu pro pozdější testovací a ladící výpisy.
void setup() { pinMode(pinMotorSpeed, OUTPUT); //setup motor speed pinMode(pinMotorDir, OUTPUT); //setup direction, LOW=CCW, HIGH=CW pinMode(2, INPUT); //connect PWM from reciever attachInterrupt(0, RECIEVER_Interrupt, CHANGE); //default direction CW digitalWrite(pinMotorDir, HIGH); //for debug only Serial.begin(115200); }
hlavní smyčka – Loop()
Hlavní smyčka – každých 50ms aktualizuje chování motoru. V podstatě jen zapíše proměnou actMotorSpeed a actMotorDir. Pokud se ale v podmínce zistí, že došlo k změně směru, tak je motor zastaven a čeká se 150ms. Důvodem je, aby neměnil motor rychlost ve vyšších otáčkách – zabrání se tak ohromnému přetížení driveru a zbytečnému mechanickému namáhání motoru. Podle druhu motoru lze s hodnotama různě hýbat a otestovat, co nejlépe sedí.
void loop() { //if direction change then stop motor and wait 150ms if(actMotorDir!=actMotorDirLast){ Serial.println("#### DIRECTION CHANGE ####"); actMotorDirLast=actMotorDir; analogWrite(pinMotorSpeed, 0); delay(150); } /* Serial.print("Reciever PWM: "); Serial.print (reviever_pwm_pulse_width); Serial.print(", Direction: "); Serial.print(actMotorDir); Serial.print(", Speed: "); Serial.print(actMotorSpeed); Serial.print(", last PWM Error: "); Serial.println (rx_last_pwm_error); */ analogWrite(pinMotorSpeed, actMotorSpeed); digitalWrite(pinMotorDir, actMotorDir); delay(50); }
RECIEVER_Interupt()
Funkce interuptu pro zpracování signálu vysílačky. Zde je implementován deadband, přemapování hodnoty z načtených hodnot do rozsahu 0–255 a detekce směru otáčení. Mimo jiné se ukládá i do rx_last_pwm_error hodnoty, pokud jsou mimo definovaný rozsah. Vodné pro ladění.
//call every time when change PWM signal from reciever void RECIEVER_Interrupt() { rx_pulse_width=micros()-reviever_pwm_pulse_width_last; if(rx_pulse_width>reciever_ranges[0] and rx_pulse_width<reciever_ranges[3]){ reviever_pwm_pulse_width = rx_pulse_width; if(reviever_pwm_pulse_width>reciever_ranges[0] and reviever_pwm_pulse_width<reciever_ranges[1]){ actMotorDir=LOW; actMotorSpeed = map(reviever_pwm_pulse_width,reciever_ranges[0],reciever_ranges[1],255,0); } if(reviever_pwm_pulse_width>reciever_ranges[2] and reviever_pwm_pulse_width<reciever_ranges[3]){ actMotorDir = HIGH; actMotorSpeed = map(reviever_pwm_pulse_width,reciever_ranges[2],reciever_ranges[3],0,255); } if(reviever_pwm_pulse_width>reciever_ranges[1] and reviever_pwm_pulse_width<reciever_ranges[2]){ actMotorSpeed = 0; } } else{ rx_last_pwm_error = rx_pulse_width; } reviever_pwm_pulse_width_last = micros(); }
A to je všechno! Ať to funguje ;-)
Připojená fotogalerie: 2015/ilustrace/Podobné články:
- Arduino a RC vysílačka 9.12.2014
- Arduino a krokový motor potřetí 20.11.2014
- Arduino a motor 28BYJ-48 podruhé 17.11.2014
- Arduino - řízení krokového motoru 11.11.2014
Štítky tohoto článku:
Diskuze: Řízení Brushless DC motoru 57BLF03 s driverem BLDC-8015A pomocí Arduina
- Pierre MATHYS (26.2.2017 19:19)
Hello
I use the same hardware to drive my wife's potter wheel.
Works fine excepted that I can't reach more than 2/3 of max speed (i.e. 2000rpm) with 99% duty-cycle @1kHz on AVI input.
Full speed can only be obtained with internal RV pot.
Did you experiment the same?
Thanks for your reply.
Best regards
PM - larry lievre (15.9.2018 06:56)
Arduino: 1.8.5 (Windows 10), Board: "Arduino/Genuino Uno"
BLDC_RC_ARDUINO:1: error: stray '\342' in program
int pinMotorSpeed ​​= 3 ;
^
BLDC_RC_ARDUINO:1: error: stray '\200' in program
BLDC_RC_ARDUINO:1: error: stray '\213' in program
BLDC_RC_ARDUINO:1: error: stray '\342' in program
BLDC_RC_ARDUINO:1: error: stray '\200' in program
BLDC_RC_ARDUINO:1: error: stray '\213' in program
BLDC_RC_ARDUINO:3: error: stray '\342' in program
int actMotorSpeed ​​= 0 ;
^
BLDC_RC_ARDUINO:3: error: stray '\200' in program
BLDC_RC_ARDUINO:3: error: stray '\213' in program
BLDC_RC_ARDUINO:3: error: stray '\342' in program
BLDC_RC_ARDUINO:3: error: stray '\200' in program
BLDC_RC_ARDUINO:3: error: stray '\213' in program
BLDC_RC_ARDUINO:58: error: stray '\342' in program
actMotorSpeed ​​= map (reviever_pwm_pulse_width, reciever_ranges [ 0 ], reciever_ranges [ 1 ], 255 , 0 );
^
BLDC_RC_ARDUINO:58: error: stray '\200' in program
BLDC_RC_ARDUINO:58: error: stray '\213' in program
BLDC_RC_ARDUINO:58: error: stray '\342' in program
BLDC_RC_ARDUINO:58: error: stray '\200' in program
BLDC_RC_ARDUINO:58: error: stray '\213' in program
BLDC_RC_ARDUINO:62: error: stray '\342' in program
actMotorSpeed ​​= map (reviever_pwm_pulse_width, reciever_ranges [ 2 ], reciever_ranges [ 3 ], 0 , 255 );
^
BLDC_RC_ARDUINO:62: error: stray '\200' in program
BLDC_RC_ARDUINO:62: error: stray '\213' in program
BLDC_RC_ARDUINO:62: error: stray '\342' in program
BLDC_RC_ARDUINO:62: error: stray '\200' in program
BLDC_RC_ARDUINO:62: error: stray '\213' in program
BLDC_RC_ARDUINO:65: error: stray '\342' in program
actMotorSpeed ​​= 0 ;
^
BLDC_RC_ARDUINO:65: error: stray '\200' in program
BLDC_RC_ARDUINO:65: error: stray '\213' in program
BLDC_RC_ARDUINO:65: error: stray '\342' in program
BLDC_RC_ARDUINO:65: error: stray '\200' in program
BLDC_RC_ARDUINO:65: error: stray '\213' in program
BLDC_RC_ARDUINO:11: error: 'intreciever_ranges' does not name a type
intreciever_ranges [ 4 ] = { 983 , 1488 , 1500 , 2010 };
^
C:\Users\Larry\Documents\Arduino\BLDC_RC_ARDUINO\BLDC_RC_ARDUINO.ino: In function 'void loop()':
BLDC_RC_ARDUINO:28: error: expected ')' before '!' token
if (actMotorDir! = actMotorDirLast) {
^
BLDC_RC_ARDUINO:35: error: expected primary-expression before '/' token
/ *
^
BLDC_RC_ARDUINO:36: error: invalid type argument of unary '*' (have 'size_t {aka unsigned int}')
Serial.print ("Reciever PWM:");
^
BLDC_RC_ARDUINO:38: error: expected ';' before 'Serial'
Serial.print (", Direction:");
^
BLDC_RC_ARDUINO:42: error: expected ';' before 'Serial'
Serial.print ("Last PWM Error:");
^
BLDC_RC_ARDUINO:45: error: expected primary-expression before '/' token
* /
^
C:\Users\Larry\Documents\Arduino\BLDC_RC_ARDUINO\BLDC_RC_ARDUINO.ino: In function 'void RECIEVER_Interrupt()':
BLDC_RC_ARDUINO:54: error: 'reciever_ranges' was not declared in this scope
if (rx_pulse_width> reciever_ranges [ 0 ] and rx_pulse_width <reciever_ranges [ 3 ]) {
^
exit status 1
stray '\342' in program
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
I GOT THIS MESSAGE WHEN I COPIED YOUR CODES INTO ARDUINO SKETCH. PEASE HELP - Adrian (3.10.2018 14:57)
Probably, because this motor driver is 10V driven and Atmega is only 5V - so 100% PWM @ 5V is only 50% for 10V. Since 0 PWM is 10% speed (I've read it somewhere) 50% PWM could be 60% speed - this is somewhere around 2/3 of max :)
- Phillip Koon (9.2.2019 18:49)
Hi, I am writing seeking help. I bought a couple of the Wantai BLDC-8015A drivers. I first wired one of the drivers up completely to my Arduino and BLDC motor with hall sensor. When I applied power, 24VDC Battery, across the DC+ to DC- terminals the red alarm LED came on. I then just wired the battery to the other drivers DC+ and DC- terminals. This driver also came on with the red alarm light. I measured the voltage and found it was 25.2 VDC. At what voltage are you running your driver? Any ideas of why my drivers are showing an alarm light?
I really appreciate your page and video on the Arduino and this driver.
Thanks,
Phillip - Merziuz (14.11.2020 17:20)
6VEnil http://pills2sale.com/ viagra online
- fldrcai (19.1.2021 21:35)
6HS5Wr <a href="http://tnodftoudtlt.com/">tnodftoudtlt</a>, [url=http://mavllthkbavu.com/]mavllthkbavu[/url], [link=http://yogdmyirxysu.com/]yogdmyirxysu[/link], http://canstwyyzoxh.com/
Původní diskuze je zachována jako archiv.