Řízení motoru je obvyklá záležitost pro levňoučké Pico, je však důležité porozumnět různým typům motorů, které můžeme používat, a je velmi nutné je přesně vědět, jak je budeme řídit pomocí pulsně šířkové modulace (PWM). Jako přídavek se podíváme na řízení krokových motorů, kde ale PWM používat nebudeme.

Nejjednodušší rozdělení motorů je stejnosměrné a střídavé. Střídavé motory jsou velké (o výkonu 1 kW a výše), napájejí se obvykle jednofázově nebo třífázově, z 230V nebo 380V. Řízením střídavých motorů se zabývat nebudeme, protože to je celý studijní obor na vysoké škole (třeba na ČVUT obor Pohony a výkonová eletrotechnika). Stejnosměrné motory pracují na nižším napětí, jsou menší a vhodnější pro IoT. Zde se podíváme jenom na stejnosměrné motorky a jak je řídit pomocí pulsně šířkové modulace.

Stejnosměrný motor

Princip kartáčového motoru. Šipkami jsou znázorněny odpudivé síly mezi vnějším polem statoru a polem rotoru. Rotor je tvořený cívkou a magnetické pole, které cívka vytváří je na ní barevně znázorněno.

Electric motor

Existují dvě velké skupiny stejnosměrných motorů, kartáčové nebo bezkartáčové. Motory pracují tak, že používají nepohyblivé magnety, nazývané stator a množství rotujících magnetů, nazývaných rotor.

Stejnosměrný motor se skládá z rotoru (upevněn na hřídeli) a statoru (pevná část elektromotoru). Rotor je vždy elektromagnet, stator může být buď elektromagnet nebo permanentní magnet. Kotvou je označován elektromagnet, na kterém dochází k přepólování napájení jeho vinutí (buď pomocí komutátoru nebo řídicím elektronickým obvodem). Kotva může být na statoru i na rotoru (podle konstrukce motoru).

Spřažený magnetický tok budicího vinutí a kotvy na sebe silově působí. Stejné póly se odpuzují a opačné přitahují. Tím vzniká točivý moment. Pokud by při pootočení nedošlo k přepnutí vinutí kotvy (komutaci), došlo by k zastavení. Vektory spřaženého magnetického toku by nevyvozovaly vzájemné silové účinky (magnetická pole by byla orientována ve stejném směru). Tento jev je využíván u elektromagnetického měřicího ústrojí. Pro zachování dosavadního směru otáčení je kotva přepólována tak, aby se rotor snažil pootočit směrem do další neutrální polohy, ale mezi tím dojde opět k další komutaci části vinutí kotvy. Pro plynulejší pohyb má kotva tři a více vinutí. Změnu směru otáčení motoru nebo polarity výstupního napětí dynama je možno uskutečnit reverzací (přepólováním) jen kotvy, nebo jen buzení. Pro rychlou reverzaci motoru je obvykle reverzována kotva, která má mnohem menší časovou konstantu než budicí obvod.

Kartáčové motory

Kartáčový motor (ang. brushed motor) má na hřídeli rotor = kotvu, v jejichž drážkách je vloženo vinutí rotoru připojené na komutátor. Komutátor je soustava vzájemně elektricky oddělených vodivých kovových lamel upevněných na hřídeli rotoru. Na komutátor přiléhají uhlíky (kartáče), kterými je přiveden do rotoru elektrický proud. Komutátor s uhlíky zajišťují komutaci vinutí - přepínání částí vinutí rotoru. Během provozu dochází k opotřebovávání uhlíků otěrem o lamely a jiskřením při přepínání napájení pro jednotlivé části vinutí. Komutátor je nejporuchovější součástí stejnosměrného kartáčového motoru a vyžaduje pravidelnou údržbu. Napětí a proud procházející vinutím rotoru je vždy stejnosměrný, pokud je střídavý jedná se o univerzální motor.

Stator kartáčového motoru obsahuje budicí obvod, který je tvořen permanentními magnety nebo cívkami budicího vinutí.

Vektor magnetického toku buzení (statoru) je pootočen o 90°elektrických vůči vektoru magnetického toku kotvy. Oba magnetické toky jsou spřaženy ve společném magnetickém obvodu. Tím dochází k silovému působení mezi magnetickými toky cívek a vzájemným silovým působením vzniká kroutící moment.

Uhlíky jsou umístěny v ose magnetické neutrály, kdy ve vinutí nevzniká pohybové napětí. V tom případě dochází jen ke komutaci pracovního proudu. Komutace se opakuje tak, aby si vektor magnetického toku kotvy zachovával stálou polohu.

Změna rychlosti otáčení a kroutícího momentu je prováděna změnou velikosti přivedeného elektrického napětí na kotvu a změnou budicího proudu.

Řízení kartáčového motoru jedním směrem

Kartáčový motor může být řízen jednoduše tak, že ho připojíma na zdroj stejnosměrného napětí. Pokud změníme polaritu tohoto napájecího napětí, změní se i směr otáčení motoru. Rychlost otáčení je jednoduše přímo úměrná velikosti napájecího napětí. Jestliže chceme řídit otáčky motoru jenom jedním směrem, všechno co potřebujeme je PWM řadič, který je schopen dodat odpovídající napájecí napětí a proud.

Jednoduché řešení s jedním tranzistorem funguje, nesmíme zapomenout na zhášecí diodu, která umožňuje, aby energie nahromaděná v cívce byla pohašena, když se motor točí, ale není pod proudem. (Jinak hrozí zničení tranzistoru).

Řízení motoru jedním tranzistorem

UBM TIP120

Toto zapojení je jednoduché a funguje s motorky až do napájecího napětí 40V a proudů 5A trvale, ve špičce 8A. Drobná poznámka: TIP120 jsou dva tranzistory v jednom pouzdře v Darlingtonově zapojení. Je to kvůli vysokému zesílení, které potřebujeme. Pokles napětí při otevřeném tranzistoru je však 1.2V (jsou tam 2 tranzistory) a mělo by se s tím počítat, hlavně při určení omezujícího odporu \(R_1\).

Občas někdo říká, že TIP120 a podobné Darlingtony jsou neefektivní, protože jsou složeny ze dvou tranzistorů, mají dvojnásobné napětí mezi emitorem a kolektrorem, což je více než můžete očekávat a také to znamená, že produkují dvakrát více tepla, než je nezbytné.

Jestliže poháníte motorek z bateria, můžete použít MOSFET, ale jak již bylo řečeno v kapitole o elektronice, je 3.3 V málo pro zapínání MOSFETu. Existuje však řešení použít bipolární tranzistor a zesílit napětí na hradle MOSFETu:

Řízení motoru bipolárním tranzistorem a MOSFETem

motor MOSFET1

Bipolární tranzistor \(T_1\) připojuje hradlo MOSFETU \(T_2\) na 12V. MOSFET IRFZ44NPBF má zapínací napětí mezi 2 až 4 V, obvod bude fungovat i na 5 V, někdy i na 3.3V bez pomoci bipolárního tranzistoru. 12 V zajišťuje že MOSFET bude plně zapnut. Problém je v tom, že bipolární tranzistor \(T_1\) invertuje signál. Když je GPIO na vysoké úrovni, tranzistor \(T_1\) je zapnutý a tudíž MOSFET \(T_2\) je vypnutý a obráceně. Jinými slovy když GPIO zapne, tak se motor vypne. MOSFET IRFZ44NPBF může pracovat s napětím až do 50 V a proudem do 40 A. Tranzistor 2N2222 pracuje s napětím do 30V, nebo do 40V ve variantě 2N2222A.

Třetí způsob řízení stejnosměrného motoru jedním směrem je použít poloviční H-můstek (half H-bridge). Proč se H-můstek tak nazývá pochopíte v další části, kde se budeme zabývat řízením motoru oběma směry. H-můstek používá buď dva komplementární bipolární tranzistory NPN a PNP anebo dva MOSFETy, jeden typu N a druhý typu P.

Řízení motoru polovičním H-můstkem

motor half H bridge

Je-li GPIO linka na vysoké úrovni, potom je tranzistor \(T_1\) zapnutý a tranzistor T2 vypnutý a motor se točí. Je-li GPIO linka na nízké úrovni, potom je tranzistor \(T_1\) vypnutý a tranzistor \(T_2\) zapnutý a motor je brzděn. Motor má setrvačnost a při brzdění funguje jako generátor, díky zpětné elektromotorické síle (EMF). Možná bude potřeba použít bipolární tranzistory, abychom zajistili plné vybuzení MOSFETů.

Software pro jednosměrné PWM řízení

Program pro řízení otáček jedním směrem je velmi jednoduchý. Rychlost otáčení nastavujeme pomocí koeficientu naplnění (duty cycle), to je jediný parametr, který musíme zvolit, kromě frekvence samozřejmě. Chceme-li optimální řízení, potom je určení frekvence poměrně obtížný úkol. Při vyšších frekvencích motor běží rychleji a tišeji, ale pokud to přeženeme a zvolíme frekvenci příliš vysokou, bude motor ztrácet výkon a řídící tranzistory se budou hřát. Určující parametr pro volbu frekvence je indukčnost cívky motoru a další komponenty obvodu jako jsou kondenzátory. V praxi se používají frekvence od 100 Hz do 20 kHz, ve většině případů je dobrá volba frekvence mezi 1 kHz a 2 KHz.

Jak implementovat jednoduše kód? Dobrý vzor, který má mnoho výhod, si můžeme vypůjčit z objektově orientovaného programování: vytvoříme strukturu, jejíž položky budou vyjadřovat stav jednotlivých veličin. Například pro jednosměrný motor můžeme vytvořit strukturu Motor:

typedef struct
{
    uint gpio;
    uint slice;
    uint chan;
    uint speed;
    uint freq
    uint resolution;
    bool on;
} Motor;

Jak je vidět, máme všechny informace potřebné k definování stavu motoru. Potřebujeme implementovat funkce, které budou tento stav měnit. První je inicializační funkce:

void motorInit( Motor *m, uint gpio, uint freq)
{
    gpio_set_function( gpio, GPIO_FUNC_PWM);
    m->gpio       = gpio;
    m->slice      = pwm_gpio_to_slice_num( gpio );
    m->chan       = pwm_gpio_to_channel( gpio );
    m->freq       = freq;
    m->speed      = 0;
    m->resolution = pwm_set_freq_duty(m->slice, m->chan, m->freq, m->speed);
    m->on         = false;
}

Dále potřebujeme funkci pro změnu rychlosti:

void motorspeed( Motor *m, int s)
{
    pwm_set_duty( m->slice, m->chan, s );
    m->speed = s;
}

A nakonec funkce, které zapnou a vypnou motor:

void motorOn( Motor *m )
{
    pwm_set_enabled( m->slice, true );
    m->on = true;
}

void motorOff( Motor *m )
{
    pwm_set_enabled( m->slice, false );
    m->on = false;
}

S touto strukturou a funkcemi plus dalšími funkcemi z předchozí kapitoly, můžeme řídit motor velmi snadno. Nezapomeňte do CMakeLists.txt přidat hardware_pwm.

target_link_libraries(myprogram
            pico_stdlib
            hardware_gpio
            hardware_pwm)
#include "pico/stdlib.h"
#include "hardware/pwm.h"

uint32_t pwm_set_freq_duty(uint slice_num, uint chan, uint32_t f, int d)
{
    uint32_t clock = 125000000;
    uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
    if (divider16 / 16 == 0)
        divider16 = 16;
    uint32_t wrap = clock * 16 / divider16 / f - 1;
    pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
    pwm_set_wrap(slice_num, wrap);
    pwm_set_chan_level(slice_num, chan, wrap * d / 100);
    return wrap;
}

uint32_t pwm_get_wrap(uint slice_num)
{
    valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
    return pwm_hw->slice[slice_num].top;
}

void pwm_set_duty(uint slice_num, uint chan, int d)
{
    pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}

typedef struct
{
    uint gpio;
    uint slice;
    uint chan;
    uint speed;
    uint freq;
    uint resolution;
    bool on;
} Motor;

void motorInit(Motor *m, uint gpio, uint freq)
{
    gpio_set_function(gpio, GPIO_FUNC_PWM);
    m->gpio = gpio;
    m->slice = pwm_gpio_to_slice_num(gpio);
    m->chan = pwm_gpio_to_channel(gpio);
    m->freq = freq;
    m->speed = 0;
    m->resolution = pwm_set_freq_duty(m->slice, m->chan, m->freq, m->speed);
    m->on = false;
}

void motorspeed(Motor *m, int s)
{
    pwm_set_duty(m->slice, m->chan, s);
    m->speed = s;
}
void motorOn(Motor *m)
{
    pwm_set_enabled(m->slice, true);
    m->on = true;
}

void motorOff(Motor *m)
{
    pwm_set_enabled(m->slice, false);
    m->on = false;
}

int main()
{
    Motor mot1;
    motorInit(&mot1, 21, 2000);
    motorspeed(&mot1, 50);
    motorOn(&mot1);
    return 0;
}

Řízení kartáčového motoru oběma směry

Software pro obousměrné PWM řízení

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pwm.h"

uint32_t pwm_set_freq_duty(uint slice_num, uint chan, uint32_t f, int d)
{
    uint32_t clock = 125000000;
    uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
    if (divider16 / 16 == 0)
        divider16 = 16;
    uint32_t wrap = clock * 16 / divider16 / f - 1;
    pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
    pwm_set_wrap(slice_num, wrap);
    pwm_set_chan_level(slice_num, chan, wrap * d / 100);
    return wrap;
}

uint32_t pwm_get_wrap(uint slice_num)
{
    valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
    return pwm_hw->slice[slice_num].top;
}

void pwm_set_duty(uint slice_num, uint chan, int d)
{
    pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}

typedef struct
{
    uint gpioForward;
    uint gpioBackward;
    uint slice;
    uint Fchan;
    uint Bchan;
    bool forward;
    uint speed;
    uint freq;
    uint resolution;
    bool on;
} BiMotor;

void BiMotorInit(BiMotor *m, uint gpioForward, uint gpioBackward, uint freq)
{
    gpio_set_function(gpioForward, GPIO_FUNC_PWM);
    m->gpioForward = gpioForward;
    m->slice = pwm_gpio_to_slice_num(gpioForward);
    m->Fchan = pwm_gpio_to_channel(gpioForward);

    gpio_set_function(gpioBackward, GPIO_FUNC_PWM);
    m->gpioBackward = gpioBackward;
    m->Bchan = pwm_gpio_to_channel(gpioBackward);

    m->freq = freq;
    m->speed = 0;
    m->forward = true;
    m->resolution = pwm_set_freq_duty(m->slice, m->Fchan, m->freq, 0);
    pwm_set_duty(m->slice, m->Bchan, 0);
    m->on = false;
}

void BiMotorspeed(BiMotor *m, int s, bool forward)
{
    if (forward)
    {
        pwm_set_duty(m->slice, m->Bchan, 0);
        pwm_set_duty(m->slice, m->Fchan, s);
        m->forward = true;
    }
    else
    {
        pwm_set_duty(m->slice, m->Fchan, 0);
        pwm_set_duty(m->slice, m->Bchan, s);
        m->forward = true;
    }
    m->speed = s;
}

void BiMotorOn(BiMotor *m)
{
    pwm_set_enabled(m->slice, true);
    m->on = true;
}

void BiMotorOff(BiMotor *m)
{
    pwm_set_enabled(m->slice, false);
    m->on = false;
}

int main()
{
    BiMotor mot1;
    BiMotorInit(&mot1, 20, 21, 2000);

    BiMotorOn(&mot1);
    while (true)
    {
        BiMotorspeed(&mot1, 50, true);
        sleep_ms(2000);
        BiMotorspeed(&mot1, 25, false);
        sleep_ms(2000);
    }

    return 0;
}

Použití jednoho plného můstku jako dva poloviční můstky

Ovládání serva

Bezkartáčové stejnosměrné motory

Rotor motoru je tvořen permanentním magnetem, stator vinutými cívkami, do nichž je pomocí řídící jednotky (střídač) přiveden střídavý proud, vytváří točivé magnetické pole. Řídící jednotka sleduje pohyb rotoru, aby správně zapínala jednotlivé cívky na statoru a na hřídeli motoru byl vytvářen točivý moment. Rotor se snaží uchovat si svoji konstantní polohu vůči otáčivému magnetickému poli vytvářenému průchodem střídavého proudu ve statoru, drží se v synchronismu až do kritického točivého momentu. Vůči poli statoru si udržuje posuv o úhel podle zátěže (zátěžový úhel beta): Změnou zátěže se úhel změní přechodovým jevem (kývání rotoru), kdy se i cyklicky po určitou dobu (řádově sekundy) pravidelně mění otáčky rotoru. Výkonová zátěžová charakteristika se nazývá V-křivka. Bezkartáčový stejnosměrný motor je někdy označován jako synchronní motor, i když zde není vnější frekvence napájecího proudu, na kterou by se motor synchronizoval.

Podrobněji na Wikipedii

Příkladem použití bezkartáčového motoru je ventilátor (čtyřdrátový) používaný ke chlazení počítačů.

Stator počítačového ventilátoru (bezkartáčový motor)

stator ventilatoru

Rotor počítačového ventilátoru

rotor ventilatoru

Krokové motory

Existuje jeden druh bezkartáčových motorů, který se snadno používá a nestojí moc peněz — krokové motory. Od normálních motorů se liší tím, že většinou nejsou určeny k trvalému otáčení vysokými otáčkami, ale spíše k přesnému natočení v daném úhlu, či vystavení do určité polohy. Najdeme je v různých vystavovacích mechanismech, třeba v tiskárnách, plottrech, 3D tiskárnách, řezacích plottrech, DVD a disketových mechanikách, při ovládání ventilů atd. atp.

Krokové motory jsou unipolární a bipolární.

Řízení krokového motoru pomocí PIO a DMA

Řízení krokového motoru pomocí PIO a DMA kanálu, které je neblokující je popsáno zde.

Řizení otáčení krokového motoru pomocí časovačů

Zdroje a odkazy