Сообщество Engee

Трапецеидальное (шестишаговое) управление БДПТ (BLDC)

Автор
avatar-poldipoldi
Соавторы
avatar-andrewraysandrewrays
Notebook

Трапецеидальное (шестишаговое) управление БДПТ (BLCD)

В данном проекте показана модель трапецеидального (шестишагового) управления БДПТ (BLDC).

Введение

Трапецеидальное управление БДПТ представляет собой систему без обратной связи по скорости или току. Датчики Холла, определяющие положение вала двигателя, используются только для коммутации обмоток двигателя. На рисунке ниже показана структурная схема модели такого управления.

model_png_2.png

Модель состоит из следующих элементов:

  • Система управления (СУ);
  • Импульсный усилитель мощности (ИУМ);
  • Источник питания (ИП);
  • БДПТ с датчиками Холла.

Ключевые элементы (КЭ) ИУМ выбраны на основе полевых транзисторов (MOSFET).

В модели реализована возможность выбора метода коммутации и способа управления КЭ ИУМ, а также схемы соединения фаз БДПТ.

Подробнее системой управления электродвигателем, на которой базируется разработанная здесь модель, можно ознакомиться в работе [1].

Система управления

Разработанная для данного примера СУ основывается на таблицах истинности (каждая для своего способа управления), а они в свою очередь определяют функцию управления КЭ ИУМ. Ниже изображено устройство СУ БДПТ.

su_png_2.png

Функция управления КЭ ИУМ формируется с помощью логической комбинации 4 переменных:

  1. DR - направление вращения двигателя (0 - прямое вращение, 1 - обратное);
  2. H - сигналы положения с датчиков Холла;
  3. PR - определяет метод коммутации КУ ИУМ (коэффициент заполнения ШИМ);
  4. SP - задаёт скорость (коэффициент заполнения ШИМ).

Методы коммутации КЭ ИУМ

Метод коммутации КЭ ИУМ влияет на распределение нагрузки между КЭ и определяется с помощью постоянной CM. Применяются три метода коммутации:

  • Несиметричный (нижний) CD = 0;
  • Несимметричный (верхний) CD = 100;
  • Поочёредный CD = 50.

Когда CM = 0, а значит и PR = 0, нижние КЭ нагружены больше, чем верхние. В случае когда CM = 100, PR = 1, то, наоборот, нижние КЭ нагружены больше. Если CM = 50 и, соответственно, PR = 0,5, верхние и нижние КЭ за период ШИМ нагружены в равной степени.

Способ управления КЭ ИУМ

Существует 3 способа управления КЭ ИУМ: 120-градусный, 150-градусный и 180-градусный. Способ управления определяется количеством установленных датчиков Холла и их взаимным расположением.

В 120- и 180-градусных способах управления необходимо разделить положение вала двигателя на 6 секторов, для чего нужно поставить 3 датчика Холла. 150-градусная коммутация прелполагает использование 6 датчиков Холла, что означает разделение на 12 секторов.

Для примера, ниже показано расположение датчиков, используемое в модели двигателя, в которой фазы соединены по схеме "звезда" (wye) при различных способах управления КЭ ИУМ.

bldc_comm_png_2.svg

Для схемы подключения "треугольник" (Delta) все датчики Холла поворачиваются на $\pi/6$ радиан по часовой стрелке.

Алгоритм определения положения с помощью датчиков Холла основан на их смещении относительно друг друга. Ниже показано смещение bias датчиков Холла H при соединении фаз двигателя по схеме "звезда" и различных способах управления КЭ ИУМ.

H bias (120) bias (180) bias (150)
H1 $0$ $-\pi/6$ $\pi/3$
H2 $2\pi/3$ $\pi/2$ $\pi/6$
H3 $-2\pi/3$ $-5\pi/6$ $0$
H4 $-\pi/6$
H5 $-\pi/3$
H6 $-\pi/2$

Моделирование

Подключим необходимые пакеты расширения:

In [ ]:
# Добавление отсутствующих пакетов
Pkg.add(["CSV", "DataFrames"]);
In [ ]:
# Подключение необходимых пакетов
using CSV
using DataFrames

С помощью макроса @__DIR__ определим дескриптор пути к файлам проекта:

In [ ]:
demoroot = @__DIR__;

Данные и параметры

Загрузим данные таблиц истинности:

In [ ]:
# Загрузка таблиц истинности из CSV-файла 
truthTable120d = CSV.read("$demoroot/data/truthTable120d.csv",
                         DataFrame; delim = ",", header = false);
truthTable150d = CSV.read("$demoroot/data/truthTable150d.csv",
                         DataFrame; delim = ",", header = false);
truthTable180d = CSV.read("$demoroot/data/truthTable180d.csv",
                         DataFrame; delim = ",", header = false);

# Способы управления КЭ ИУМ
## 120-градусный
tt120deg = truthTable120d.Column1; 
tt120deg = [tt120deg truthTable120d.Column2];
tt120deg = [tt120deg truthTable120d.Column3];
tt120deg = [tt120deg truthTable120d.Column4];
tt120deg = [tt120deg truthTable120d.Column5];
tt120deg = [tt120deg truthTable120d.Column6];

## 150-градусный
tt150deg = truthTable150d.Column1; 
tt150deg = [tt150deg truthTable150d.Column2];
tt150deg = [tt150deg truthTable150d.Column3];
tt150deg = [tt150deg truthTable150d.Column4];
tt150deg = [tt150deg truthTable150d.Column5];
tt150deg = [tt150deg truthTable150d.Column6];

## 180-градусный
tt180deg = truthTable180d.Column1; 
tt180deg = [tt180deg truthTable180d.Column2];
tt180deg = [tt180deg truthTable180d.Column3];
tt180deg = [tt180deg truthTable180d.Column4];
tt180deg = [tt180deg truthTable180d.Column5];
tt180deg = [tt180deg truthTable180d.Column6];

Зададим параметры моделирования, ИП, БДПТ и ИУМ:

In [ ]:
# Параметры моделирования
Ts = 5e-6; # Время дискретизации физ.мода

# Параметры ИП
Us = 24; # Напряжение питания, В

# Параметры БДПТ
R  = 2.25;             # Сопротивление статорной обмотки, Ом
L  = 0.0032;           # Индуктивность статорной обмотки, Гн
Cm = 0.03397;          # Постоянная момента, Н*м/А           
Ce = 0.0258;           # Постоянная противоЭДС, В*с/рад          
J  = 2.4e-6;           # Момент инерции ротора, кг*м^2
Bm = 0;                # Демпфирование ротора, Н*м*с/рад
p  = 4;                # Количество пар полюсов
Fmax = (2/3)*(Cm/p);   # Максимальная величина потокосцепления постоянных магнитов
ThetaConst = pi/(2*p); # Угол ротора, при котором противоЭДС постоянна

# Параметры ИУМ
f     = 5000;  # Частота преключения, Гц
Rds   = 4e-2;  # Сопротивление сток-исток, Ом
Goffs = 1e-6;  # Проводимость в выклюенном состоянии, См
Uthr  = 0.5;   # Пороговое напряжение, В
Udf   = 0.8;   # Прямое напряжение интегральных диодов, В
Ron   = 1e-3;  # Сопротивление интегральных диодов при прямом включении, Ом
Goff  = 1e-5;  # Проводимость интегральных диодов в закрытом состоянии, См
Csn   = 1e-7;  # Ёмкость снаббера, Ф
Rsn   = 1e4;   # Сопротивление снаббера, Ом

Выбор способа коммутации КЭ ИУМ осуществляется с помощью определения переменной comType соответствующим числом (120/150/180).

In [ ]:
# Выбор способа коммутации КЭ ИУМ
comType = 120; # 120 / 150 / 180

Аналогичным образом с помощью переменной woundType выбирается схема соединения фаз двигателя. Здесь схеме типа "треугольник" соответствует 1, а типу "звезда" - 2.

In [ ]:
## Выбор схемы соединения фаз двигателя
woundType = 1; # треугольник = 1, звезда = 2

# Загрузка модели Engee, если она еще не открыта на холсте
if "bldc_control_sixstep"  getfield.(engee.get_all_models(), :name)
    engee.load( "$demoroot/bldc_control_sixstep.engee");
end

bldc_root = "bldc_control_sixstep/БДПТ с датчиками Холла/БДПТ";
if woundType == 1
    engee.set_param!(bldc_root, "winding_type" => "Delta-wound")
elseif woundType == 2
    engee.set_param!(bldc_root, "winding_type" => "Wye-wound")
    engee.set_param!(bldc_root, "zero_sequence" => "Exclude")
end

Наконец определим переменные метода коммутации КЭ ИУМ CM, направления DR и скорости SP вращения вала двигателя:

In [ ]:
CM = 0;   # 0 - несимметричный (нижний) 100 - несимметричный (верхний), 50 - поочерёдный
DR = 0;   # 0 - прямое вращение, 1 - реверс
SP = 100; # ШИМ [0...100] - % от максимальной скорости двигателя

Откроем модель и запустим симуляцию:

In [ ]:
# Запуск симуляции модели Engee
model_data = engee.run("bldc_control_sixstep");

Извлечём данные, которые были получены в ходе симуляции:

In [ ]:
angle = model_data["Angle"].value;  # Угол поворота вала двигателя, град
speed = model_data["Speed"].value;  # Скорость вращения вала двигателя, об/мин

# Токи
is = model_data["is"].value;  # Ток потребления от ИП
ia = model_data["ia"].value;  # Ток фазы A
ib = model_data["ib"].value;  # Ток фазы B
ic = model_data["ic"].value;  # Ток фазы C

# Напряжения
Ua = model_data["Ua"].value;   # Фазное напряжение A
Ub = model_data["Ub"].value;   # Фазное напряжение B
Uc = model_data["Uc"].value;   # Фазное напряжение C
Uab = model_data["Uab"].value; # Линейное напряжение C
Ubc = model_data["Ubc"].value; # Линейное напряжение C
Uca = model_data["Uca"].value; # Линейное напряжение C

# Датчики Холла H
Hall = model_data["Hall"].value;    

Hall_1 = zeros(Float64, length(Hall));
Hall_2 = zeros(Float64, length(Hall));
Hall_3 = zeros(Float64, length(Hall));

for i = 1:length(Hall)
    Hall_1[i] = Hall[i][1];
    Hall_2[i] = Hall[i][2];
    Hall_3[i] = Hall[i][3];
end

if comType == 150
    Hall_4 = zeros(Float64, length(Hall));
    Hall_5 = zeros(Float64, length(Hall));
    Hall_6 = zeros(Float64, length(Hall));

    for i = 1:length(Hall)
        Hall_4[i] = Hall[i][4];
        Hall_5[i] = Hall[i][5];
        Hall_6[i] = Hall[i][6];
    end
end

# Ключевые элементы G
Gates = model_data["Gates"].value;    

Gates_1 = zeros(Float64, length(Gates));
Gates_2 = zeros(Float64, length(Gates));
Gates_3 = zeros(Float64, length(Gates));
Gates_4 = zeros(Float64, length(Gates));
Gates_5 = zeros(Float64, length(Gates));
Gates_6 = zeros(Float64, length(Gates));

for i = 1:length(Gates)
    Gates_1[i] = Gates[i][1];
    Gates_2[i] = Gates[i][2];
    Gates_3[i] = Gates[i][3];
    Gates_4[i] = Gates[i][4];
    Gates_5[i] = Gates[i][5];
    Gates_6[i] = Gates[i][6];
end

Результаты

Построим графики положения и скорости ротора БДПТ:

In [ ]:
#gr()      # Отключение интерактивности при построении графиков (легче для отрисовки)
plotlyjs() # Включение интерактивности (сложнее для отрисовки)
t = model_data["Angle"].time; # Время симуляции, с
plot(
    plot(t, angle, ylabel = "Угол поворота, град", lw = 1.5, c = "red",
    title = ""),
    plot(t, speed, xlabel = "Время, с", lw = 1.5, c = "green", 
    ylabel = "Скорость, об/мин"),
    layout = (2,1), legend=:false, link=:x
)
Out[0]:

Графики фазных токов и тока источника питания:

In [ ]:
#gr()      # Отключение интерактивности при построении графиков (легче для отрисовки)
plotlyjs() # Включение интерактивности (сложнее для отрисовки)
t = model_data["is"].time; # Время симуляции, с
plot(
    plot(t, is, ylabel = "Питания, А", lw = 1.5, c = "black",
    title = "Токи"),
    plot(t, [ia, ib, ic], lw = 1.5, c = ["red" "blue" "yellow"],
    xlabel = "Время, с", ylabel = "Фазные, А"),
    layout = (2,1), legend=:topright, label = ["is" "ia" "ib" "ic"], link=:x
)
Out[0]:

Ниже построены графики напряжений двигателя, сигналы с датчиков Холла и на КЭ ИУМ.

In [ ]:
#gr()      # Отключение интерактивности при построении графиков (легче для отрисовки)
plotlyjs() # Включение интерактивности (сложнее для отрисовки)
t = model_data["Ua"].time; # Время симуляции, с
plot(
    plot(t, [Ua, Ub, Uc], ylabel = "Фазные, В", lw = 1.5, c = ["red" "blue" "yellow"],
    title = "Напряжения БДПТ", label = ["Ua" "Ub" "Uc"]),
    plot(t, [Uab, Ubc, Uca], lw = 1.5, c = ["red" "blue" "yellow"],
    xlabel = "Время, с", ylabel = "Линейные, В", label = ["Uab" "Ubc" "Uca"]),
    layout = (2,1), legend=:right, link=:x
)
Out[0]:
In [ ]:
#gr()      # Отключение интерактивности при построении графиков (легче для отрисовки)
plotlyjs() # Включение интерактивности (сложнее для отрисовки)
t = model_data["Hall"].time; # Время симуляции, с
if comType == 150
plot(
    plot(t, Hall_1, ylabel = "H1", lw = 1.5,
    title = "Сигналы с датчиков Холла"),
    plot(t, Hall_2, lw = 1.5,
    ylabel = "H2"),
    plot(t, Hall_3, lw = 1.5,
    ylabel = "H3"),
    plot(t, Hall_4, lw = 1.5,
    ylabel = "H4"),
    plot(t, Hall_5, lw = 1.5,
    ylabel = "H5"),
    plot(t, Hall_6, lw = 1.5, 
    ylabel = "H6", xlabel = "Время, с"),
    layout = (6,1), legend=:none, link=:x
)
else
    plot(
        plot(t, Hall_1, ylabel = "H1", lw = 1.5,
        title = "Сигналы с датчиков Холла"),
        plot(t, Hall_2, lw = 1.5,
        ylabel = "H2"),
        plot(t, Hall_3, lw = 1.5,
        ylabel = "H3", xlabel = "Время, с"),
        layout = (3,1), legend=:none, link=:x
    )
end
Out[0]:
In [ ]:
#gr()      # Отключение интерактивности при построении графиков (легче для отрисовки)
plotlyjs() # Включение интерактивности (сложнее для отрисовки)
t = model_data["Gates"].time; # Время симуляции, с
plot(
    plot(t, Gates_1, ylabel = "G1", lw = 1.5,
    title = "Сигналы на КЭ ИУМ"),
    plot(t, Gates_2, lw = 1.5,
    ylabel = "G2"),
    plot(t, Gates_3, lw = 1.5,
    ylabel = "G3"),
    plot(t, Gates_4, lw = 1.5,
    ylabel = "G4"),
    plot(t, Gates_5, lw = 1.5,
    ylabel = "G5"),
    plot(t, Gates_6, lw = 1.5, 
    ylabel = "G6", xlabel = "Время, с"),
    layout = (6,1), legend=:none, link=:x
)
Out[0]:

Заключение

В данном проекте показана модель 6-шаговой коммутации БДПТ (BLDC). Рассмотрена структура, принцип работы и варианты исполнения данного типа управления. В результате моделирования получены эпюры токов, напряжений, а также логических сигналов с датчиков Холла и на ключевых элементах преобразователя постоянного тока.

Разработанная модель может быть использована, например, в качестве исполнительного элемента электропривода.

Список использованых источников

  1. Кривилёв А.В. Разработка и реализация на ПЛИС энергоэффективных способов импульсного управления системами «усилитель мощности — электродвигатель» на основе методов автоматизированного проектирования: автореф. дис. докт.техн.наук, М. : МАИ, 2013.