Řízení Brushless DC motoru 57BLF03 s driverem BLDC-8015A pomocí Arduina

Stáhnout jako PDF 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í

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:

Štítky tohoto článku:

 


Diskuze: Řízení Brushless DC motoru 57BLF03 s driverem BLDC-8015A pomocí Arduina

  1. 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

    • 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 :)

    Reagovat na tento příspěvek
  2. larry lievre (15.9.2018, 06:56)

    Arduino: 1.8.5 (Windows 10), Board: „Arduino/Genu­ino 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_pul­se_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_pul­se_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_ran­ges‘ does not name a type

    intreciever_ranges [ 4 ] = { 983 , 1488 , 1500 , 2010 };

    ^

    C:\Users\Larry\Do­cuments\Ardui­no\BLDC_RC_AR­DUINO\BLDC_RC_AR­DUINO.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\Do­cuments\Ardui­no\BLDC_RC_AR­DUINO\BLDC_RC_AR­DUINO.ino: In function ‚void RECIEVER_Inte­rrupt()‘:

    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

    Reagovat na tento příspěvek
  3. 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

    Reagovat na tento příspěvek

  4.  
    Diskuze: Řízení Brushless DC motoru 57BLF03 s driverem BLDC-8015A pomocí Arduina
    Vaše jméno (povinné)
    Váš email (nebude zveřejněn, povinný)
    WEB (bude zveřejněn, pište s http://)
    Text vzkazu:
    Kolik je 3×2? (ochrana proti spamu)
 
[CNW:Counter]