Найти тему
Сергей Малофеев

Управляем частотой вращения синхронного двигателя переменного тока

Доброго всем времени суток!

Как-то решая задачу по автоматизации линейного перемещения фрезера (точность позиционирования не требовалась, так как выполнялась черновая обработка) из имеющегося в наличии оборудования пришлось подробно изучать вопрос управления скоростью вращения синхронных маломощных двигателей.

В наличие нашлись редукторы с двигателями на 24В 1450RPM (6Вт) и 230В 375RPM (12Вт).

Синхронные реверсивные двигатели (без редукторов)
Синхронные реверсивные двигатели (без редукторов)

Механическая доработка редукторов полностью проблему не решило, необходимо было собирать частотник.

Первая попытка управления двигателем на 220В хотя в итоге и была в целом успешная (т.к. двигатель все таки работал), но направление было выбрано в корне неправильное. За основу была взята схема преобразователя 12В -> 220В с управлением от мультивибратора, типа такой:

-2

Соответственно, мультивибратор был доработан, чтобы выдавать 50-100Гц, причем управлять получилось даже 100Вт двигателем (12 В брались от 500Вт-ного компьютерного блока питания). Но все таки данное схемное решение годилось только для проверки возможности работы двигателей на высоких частотах, но не для практического применения.

Самое простое в итоге решение нашлось для 24В двигателя: управляющий генератор был собран на модуле Ардуино УНО, в качестве силового модуля взят ардуиновский модуль для управления коллекторными и шаговыми двигателями L298N, а также взят 24В импульсный блок питания.

-3

Немного сложнее было с написанием подходящей программы для контроллера. Изначально решил для управления получить синус, но на практике самым действенным оказалось использование обычных прямоугольных импульсов. Программа, приведенная ниже, с небольшой доработкой позволяет регулировать площадь прямоугольника в зависимости от частоты, что необходимо учитывать особенно при управлении на низких частотах. В демонстрационном варианте для упрощения кода регулировка отдаваемой двигателю мощности не используется. Дискретность изменения частоты выбрана 5 Гц, диапазон регулировки частоты - 40 - 200Гц. При копировании программы необходимо убрать пробелы между символом "# " и ключевым словом, т.к. иначе редактор ДЗЕНа отказывался принимать текст.

# include <avr/io.h>
# include <avr/interrupt.h>
# define ENC_A 2 // пин энкодера 1
# define ENC_B 4 // пин энкодера 2
# define ENC_TYPE 1 // тип энкодера, 0 или 1
int koef = 8; // минимальное значение частоты - 40 Гц для шага 5 Гц
int val = 0; // переменная для хранения считываемого значения
const int min_Hz = 16000; //для формирования шага изменения частоты: 16000 - 5 Гц, 8000 - 10 Гц, 3200 - 25 Гц, 1600 - 50 Гц
volatile int encCounter;
volatile int number = 0; //вспомогательная переменная для вывода в порт
volatile boolean state0, lastState, turnFlag; //переменные для обработки внешнего прерывания
void setup(){
// Инициализация регистров, смотрите документацию для подробной информации
//настраиваем регистры для формирования ШИМ
TCCR1A = 0b10100010;
TCCR1B = 0b00011001;
TIMSK1 = 0b00000001;
ICR1 = int(min_Hz/koef); //начальная частота - 40Гц
DDRB = 0b00000110; // PB1 и PB2 выходные каналы ШИМ
attachInterrupt(0, int0, CHANGE);
sei(); // Разрешаем глобальные прерывания
}
void loop(){; /*Пустой цикл*/}
//обработка прерываний
void int0() { //обработка прерывания по внешнему событию (энкодер)
state0 = digitalRead(ENC_A);
if (state0 != lastState) {
# if (ENC_TYPE == 1)
turnFlag = !turnFlag;
if (turnFlag)
encCounter += (digitalRead(ENC_B) != lastState) ? -1 : 1; //шаг
# else
encCounter += (digitalRead(ENC_B) != lastState) ? -1 : 1; //шаг
# endif
lastState = state0;
}
//граничные условия
if (encCounter < 8) {
encCounter = 8; //40Гц
}
if (encCounter > 40) {
encCounter = 40; //200Гц
}
koef = encCounter;
}
ISR(TIMER1_OVF_vect){ //обработка прерывания по таймеру
static int num = 0;
// менять рабочий цикл каждый период.
if (num < 10)
{OCR1A = 0; OCR1B = 0 ;} //нет генерации - исключаем сквозной ток
else if ((num >= 10)&(num < 100))
{OCR1A = int(min_Hz/koef); OCR1B = 0;}
else if ((num >= 100)&(num <= 110))
{OCR1A = 0; OCR1B = 0 ;} //нет генерации - исключаем сквозной ток
else
{OCR1B = int(min_Hz/koef); OCR1A = 0;}
if(++num >= 200){ // Предварительно увеличьте значение num, затем проверьте, что оно меньше 200
OCR1A = 0; OCR1B = 0;
num = 0; // Сброс num.
cli();
ICR1 = int(min_Hz/koef); // задаем частоту 40-200Гц
sei();
}
}

Осциллограммы управляющих импульсов с выводов Ардуино приведены ниже:

Осциллограмма на частоте 40 Гц, промежутки между импульсами - программное исключение сквозного тока через ключи.
Осциллограмма на частоте 40 Гц, промежутки между импульсами - программное исключение сквозного тока через ключи.

Видео примера управления доступно по ссылке.

В целом, управление оказалось возможным в диапазоне 40 - 150 Гц, при этом после 100-110 Гц ощущается значительная потеря мощности (все таки двигатель рассчитан на частоту 50/60Гц), но мне 100Гц как раз хватило.

Для управления двигателем на 220В конечно понадобится другой мост (у меня собран на IGBT, пробовал на киловатном двигателе, работает, если заинтересует дополню статью).