Varování: Příspěvek není návodem
ale inspirací pro možný návrh podobného zařízení kvalifikovanou osobou
případně pod dozorem jako školní projekt. Obsahuje části pod napětím
životu nebezpečným. Autor nenese odpovědnost za újmy na zdraví nebo
majetku vzniklé v souvislosti s následujícím příspěvkem. Autor si
vyhrazuje právo příspěvek kdykoli změnit.
DTC – Direct Torque Control, přímé řízení momentu. Jedná se o hysterezní metodu řízení toku a momentu určenou především pro asynchronní motory s kotvou nakrátko. Verze popsaná zde vychází z U1 – I modelu.
DTC – Direct Torque Control, přímé řízení momentu. Jedná se o hysterezní metodu řízení toku a momentu určenou především pro asynchronní motory s kotvou nakrátko. Verze popsaná zde vychází z U1 – I modelu.
Schema
Obr. 1: Blokové schema
1) Měření proudu
Prostorový vektor:
Platí:
Složky proudu získáme měřením ve
dvou fázích pomocí transformace Clarkové:
, kde K
volíme 2/3, dále pro vinutí bez vyvedeného středu platí
Výsledné výpočty
obsažené v bloku transformace potom:
2) Měření napětí
Složky napětí získáme
podle aktuální kombinace sepnutí obdobným způsobem jako složky
proudu z napětí meziobvodu UM:
3) Výpočet toků:
Bloky realizují integraci napětí v čase.
Velikost toku je potom:
4) Výpočet momentu:
Bloky
násobiček a sčítačka dají výsledný moment, který je třeba
korigovat konstantou inverzní k té, co byla zanesena v bloku
výpočtu složek proudů.
, kde pp je počet
pólpárů.
5) Přepínací tabulka
Její
výstupy přímo řídí konfiguraci sepnutí tranzistorů v
třífázovém můstku. Na vstupech má hysterezní regulátory toku
a momentu.
Obr.
2: Přepínací tabulka
Hysterezní
regulátor toku rozhoduje o tom, kdy se má přepnout na následující
prostorový vektor.
Pro menší žádaný tok se přepíná dříve a prostorový vektor se tedy pohybuje po
menším šeštiúhelníku. Pro větší naopak. Cyklickým
přepínáním pracovních oblastí je dosaženo točivého
magnetického pole. Tokové vektory působí kolmo k cívkám
statoru.
Hysterezní regulátor
momentu potom rozhoduje o tom, jestli budou tranzistory sepnuté do
aktivního stavu 1 až 6 nebo do konfigurace nulového fázového
napětí, tedy stavu 0 nebo 7 podle toho, který je dosažen jediným
přepnutím. Tímto řízením je v rámci hystereze dosažen
konstantní, kruhový průběh momentu.
Výstupem přepínací
tabulky jsou potom tři logické signály každý pro jednu fázi
rozhodující o tom, jestli je sepnutý horní nebo dolní tranzistor
v dané fázi.
6) Třífázový můstek
Tranzistory,
nejčastěji IGBT, zajišťují rozstřídání stejnosměrného
napětí meziobvodu podle signálů z přepínací tabulky na
jednotlivé fáze asynchronního motoru. Uvedené schema je velmi
zjednodušené, pouze pro definování polarity řídících signálů,
chybí např. generování deadtimu.
Obr. 3: zjednodušené
schema třífázového můstku
Závěr:
Z principu je patrné, že
tranzistory nejsou řízeny PWM s fixní spínací frekvencí. Jak
často dochází k přepínání je dáno především nastavením
hystereze regulátoru momentu, který opakovaně spíná a vypíná
aktivní a pasivní stav v oblasti, kde se dle přepínací tabulky
zrovna nachází prostorový vektor a tím se snaží udržet žádaný
moment motoru.
Šestiúhelník je možno
zvětšovat až do maximálního omezeného napětím meziobvodu.
Dále pak motor při vyšších otáčkách samovolně přechází do
režimu odbuzování, tedy klesá moment.
Realizace v MCU
Chtěl jsem ze zvědavosti zkusit realizovat výpočet uvedený výše, který je vlastně přepisem odevzdávaného protokolu, v MCU na prototypové desce s 3f můstkem, který jsem do té doby používal se skalární regulací. Zde je schema, pár fotek a videa, jak to zatím vypadá. V příloze pak kousek upraveného kódu.
S namontovaným chladičem
Příloha:
Z průbehu vypočteného toku je vidět, že algoritmus nefungoval úplně koretně ještě a vnášel tam jistý offset. (vykresleno přímo z dat přenesených z MCU)
Příloha:
Z průbehu vypočteného toku je vidět, že algoritmus nefungoval úplně koretně ještě a vnášel tam jistý offset. (vykresleno přímo z dat přenesených z MCU)
Příloha:
/* Transformace */
I_alpha = I_a;
I_beta = (I_a + 2*I_b);
I_beta = I_beta*57735/100000;
I_alpha = I_a;
I_beta = (I_a + 2*I_b);
I_beta = I_beta*57735/100000;
/* Stanoveni fazovych napeti */
switch(vektor)
{
case 0:
{
U_alpha = 0;
U_beta = 0;
}
break;
case 1:
{
U_alpha = U_m;
U_beta = 0;
}
break;
case 2:
{
U_alpha = U_m/2;
U_beta = U_m*86603/100000;
}
break;
case 3:
{
U_alpha = -U_m/2;
U_beta = U_m*86603/100000;
}
break;
case 4:
{
U_alpha = -U_m;
U_beta = 0;
}
break;
case 5:
{
U_alpha = -U_m/2;
U_beta = -U_m*86603/100000;
}
break;
case 6:
{
U_alpha = U_m/2;
U_beta = -U_m*86603/100000;
}
break;
case 7:
{
U_alpha = 0;
U_beta = 0;
}
break;
}
/* Vypocet slozek toku */
psi_alpha = psi_alpha + U_alpha - I_alpha/Gs;
psi_beta = psi_beta + U_beta - I_beta/Gs;
/* Vypocet toku */
psi_druha = psi_alpha*psi_alpha + psi_beta*psi_beta; //druha mocnina psi
/* Vypocet druhe odmocniny */
psi_b = 1 << (32-2);
psi = 0;
while (psi_b != 0)
{
if (psi_druha >= psi + psi_b)
{
psi_druha -= psi + psi_b;
psi += psi_b << 1;
}
psi >>= 1;
psi_b >>= 2;
}
/* Vypocet momentu */
moment = (psi_alpha*I_beta/154 - psi_beta*I_alpha/154)*3/2; //130*154=20kHz => mNm
/* Vyber sektoru */
switch(sektor)
{
case 0:
{
if(psi_beta*1732 > psi_alpha*1000)
{
sektor = 1;
otacky++;
}
if(-psi_beta*1732 > psi_alpha*1000)
{
sektor = 5;
otacky--;
}
}
break;
case 1:
{
if(psi_alpha < 0)
{
sektor = 2;
otacky++;
}
if(psi_beta*1732 < psi_alpha*1000)
{
sektor = 0;
otacky--;
}
}
break;
case 2:
{
if(psi_beta*1732 < -psi_alpha*1000)
{
sektor = 3;
otacky++;
}
if(psi_alpha > 0)
{
sektor = 1;
otacky--;
}
}
break;
case 3:
{
if(psi_beta*1732 < psi_alpha*1000)
{
sektor = 4;
otacky++;
}
if(psi_beta*1732 > -psi_alpha*1000)
{
sektor = 2;
otacky--;
}
}
break;
case 4:
{
if(psi_alpha > 0)
{
sektor = 5;
otacky++;
}
if(psi_beta*1732 > psi_alpha*1000)
{
sektor = 3;
otacky--;
}
}
break;
case 5:
{
if(-psi_beta*1732 < psi_alpha*1000)
{
sektor = 0;
otacky++;
}
if(psi_alpha < 0)
{
sektor = 4;
otacky--;
}
}
break;
}
/* Regulator toku */
psi_delta = psi_zadane - psi;
if(psi_delta > psi_epsilon)
{
psi_hystereze = 1; //tok nahoru
}
if(psi_delta < -psi_epsilon)
{
psi_hystereze = 0; //tok dolu
}
/* Regulator momentu */
moment_delta = moment_zadany - moment;
switch(psi_stav)
{
case 0:
{
if(moment_delta > moment_epsilon)
{
psi_stav = 1;
}
if(moment_delta < -moment_epsilon)
{
psi_stav = 2;
}
moment_hystereze = 0;
}
break;
case 1:
{
if(moment_delta <= 0)
{
psi_stav = 0;
}
moment_hystereze = 1; //moment nahoru
}
break;
case 2:
{
if(moment_delta >= 0)
{
psi_stav = 0;
}
moment_hystereze = -1; //moment dolu, nemame kam rekuperovat
}
break;
}
/* Prepinaci tabulka */
if(psi_hystereze) //tok nahoru
{
if(moment_hystereze == 0)
{
vektor = 0; //lichy do nul, sudy do jednicek
}
if(moment_hystereze == 1)
{
vektor = 1 + (6 + sektor + 1)%6; //dopredu ven
}
if(moment_hystereze == -1)
{
vektor = 1 + (6 + sektor - 1)%6; //zpet ven
}
}
else
{
if(moment_hystereze == 0)
{
vektor = 0;
}
if(moment_hystereze == 1)
{
vektor = 1 + (6 + sektor + 2)%6; //dopredu dovnitr
}
if(moment_hystereze == -1)
{
vektor = 1 + (6 + sektor - 2)%6; //zpet dovnitr
}
}
/* Zapis do komparacnich jednotek 3f mustku */
switch(vektor)
{
case 0:
{
TIM1->CCR1 = 0;
TIM1->CCR2 = 0;
TIM1->CCR3 = 0;
}
break;
case 1:
{
TIM1->CCR1 = 4200;
TIM1->CCR2 = 0;
TIM1->CCR3 = 0;
}
break;
case 2:
{
TIM1->CCR1 = 4200;
TIM1->CCR2 = 4200;
TIM1->CCR3 = 0;
}
break;
case 3:
{
TIM1->CCR1 = 0;
TIM1->CCR2 = 4200;
TIM1->CCR3 = 0;
}
break;
case 4:
{
TIM1->CCR1 = 0;
TIM1->CCR2 = 4200;
TIM1->CCR3 = 4200;
}
break;
case 5:
{
TIM1->CCR1 = 0;
TIM1->CCR2 = 0;
TIM1->CCR3 = 4200;
}
break;
case 6:
{
TIM1->CCR1 = 4200;
TIM1->CCR2 = 0;
TIM1->CCR3 = 4200;
}
break;
case 7:
{
TIM1->CCR1 = 4200;
TIM1->CCR2 = 4200;
TIM1->CCR3 = 4200;
}
break;
}
}
switch(vektor)
{
case 0:
{
U_alpha = 0;
U_beta = 0;
}
break;
case 1:
{
U_alpha = U_m;
U_beta = 0;
}
break;
case 2:
{
U_alpha = U_m/2;
U_beta = U_m*86603/100000;
}
break;
case 3:
{
U_alpha = -U_m/2;
U_beta = U_m*86603/100000;
}
break;
case 4:
{
U_alpha = -U_m;
U_beta = 0;
}
break;
case 5:
{
U_alpha = -U_m/2;
U_beta = -U_m*86603/100000;
}
break;
case 6:
{
U_alpha = U_m/2;
U_beta = -U_m*86603/100000;
}
break;
case 7:
{
U_alpha = 0;
U_beta = 0;
}
break;
}
/* Vypocet slozek toku */
psi_alpha = psi_alpha + U_alpha - I_alpha/Gs;
psi_beta = psi_beta + U_beta - I_beta/Gs;
/* Vypocet toku */
psi_druha = psi_alpha*psi_alpha + psi_beta*psi_beta; //druha mocnina psi
/* Vypocet druhe odmocniny */
psi_b = 1 << (32-2);
psi = 0;
while (psi_b != 0)
{
if (psi_druha >= psi + psi_b)
{
psi_druha -= psi + psi_b;
psi += psi_b << 1;
}
psi >>= 1;
psi_b >>= 2;
}
/* Vypocet momentu */
moment = (psi_alpha*I_beta/154 - psi_beta*I_alpha/154)*3/2; //130*154=20kHz => mNm
/* Vyber sektoru */
switch(sektor)
{
case 0:
{
if(psi_beta*1732 > psi_alpha*1000)
{
sektor = 1;
otacky++;
}
if(-psi_beta*1732 > psi_alpha*1000)
{
sektor = 5;
otacky--;
}
}
break;
case 1:
{
if(psi_alpha < 0)
{
sektor = 2;
otacky++;
}
if(psi_beta*1732 < psi_alpha*1000)
{
sektor = 0;
otacky--;
}
}
break;
case 2:
{
if(psi_beta*1732 < -psi_alpha*1000)
{
sektor = 3;
otacky++;
}
if(psi_alpha > 0)
{
sektor = 1;
otacky--;
}
}
break;
case 3:
{
if(psi_beta*1732 < psi_alpha*1000)
{
sektor = 4;
otacky++;
}
if(psi_beta*1732 > -psi_alpha*1000)
{
sektor = 2;
otacky--;
}
}
break;
case 4:
{
if(psi_alpha > 0)
{
sektor = 5;
otacky++;
}
if(psi_beta*1732 > psi_alpha*1000)
{
sektor = 3;
otacky--;
}
}
break;
case 5:
{
if(-psi_beta*1732 < psi_alpha*1000)
{
sektor = 0;
otacky++;
}
if(psi_alpha < 0)
{
sektor = 4;
otacky--;
}
}
break;
}
/* Regulator toku */
psi_delta = psi_zadane - psi;
if(psi_delta > psi_epsilon)
{
psi_hystereze = 1; //tok nahoru
}
if(psi_delta < -psi_epsilon)
{
psi_hystereze = 0; //tok dolu
}
/* Regulator momentu */
moment_delta = moment_zadany - moment;
switch(psi_stav)
{
case 0:
{
if(moment_delta > moment_epsilon)
{
psi_stav = 1;
}
if(moment_delta < -moment_epsilon)
{
psi_stav = 2;
}
moment_hystereze = 0;
}
break;
case 1:
{
if(moment_delta <= 0)
{
psi_stav = 0;
}
moment_hystereze = 1; //moment nahoru
}
break;
case 2:
{
if(moment_delta >= 0)
{
psi_stav = 0;
}
moment_hystereze = -1; //moment dolu, nemame kam rekuperovat
}
break;
}
/* Prepinaci tabulka */
if(psi_hystereze) //tok nahoru
{
if(moment_hystereze == 0)
{
vektor = 0; //lichy do nul, sudy do jednicek
}
if(moment_hystereze == 1)
{
vektor = 1 + (6 + sektor + 1)%6; //dopredu ven
}
if(moment_hystereze == -1)
{
vektor = 1 + (6 + sektor - 1)%6; //zpet ven
}
}
else
{
if(moment_hystereze == 0)
{
vektor = 0;
}
if(moment_hystereze == 1)
{
vektor = 1 + (6 + sektor + 2)%6; //dopredu dovnitr
}
if(moment_hystereze == -1)
{
vektor = 1 + (6 + sektor - 2)%6; //zpet dovnitr
}
}
/* Zapis do komparacnich jednotek 3f mustku */
switch(vektor)
{
case 0:
{
TIM1->CCR1 = 0;
TIM1->CCR2 = 0;
TIM1->CCR3 = 0;
}
break;
case 1:
{
TIM1->CCR1 = 4200;
TIM1->CCR2 = 0;
TIM1->CCR3 = 0;
}
break;
case 2:
{
TIM1->CCR1 = 4200;
TIM1->CCR2 = 4200;
TIM1->CCR3 = 0;
}
break;
case 3:
{
TIM1->CCR1 = 0;
TIM1->CCR2 = 4200;
TIM1->CCR3 = 0;
}
break;
case 4:
{
TIM1->CCR1 = 0;
TIM1->CCR2 = 4200;
TIM1->CCR3 = 4200;
}
break;
case 5:
{
TIM1->CCR1 = 0;
TIM1->CCR2 = 0;
TIM1->CCR3 = 4200;
}
break;
case 6:
{
TIM1->CCR1 = 4200;
TIM1->CCR2 = 0;
TIM1->CCR3 = 4200;
}
break;
case 7:
{
TIM1->CCR1 = 4200;
TIM1->CCR2 = 4200;
TIM1->CCR3 = 4200;
}
break;
}
}
Žádné komentáře:
Okomentovat