Доброго всем времени суток!
Как-то решая задачу по автоматизации линейного перемещения фрезера (точность позиционирования не требовалась, так как выполнялась черновая обработка) из имеющегося в наличии оборудования пришлось подробно изучать вопрос управления скоростью вращения синхронных маломощных двигателей.
В наличие нашлись редукторы с двигателями на 24В 1450RPM (6Вт) и 230В 375RPM (12Вт).
Механическая доработка редукторов полностью проблему не решило, необходимо было собирать частотник.
Первая попытка управления двигателем на 220В хотя в итоге и была в целом успешная (т.к. двигатель все таки работал), но направление было выбрано в корне неправильное. За основу была взята схема преобразователя 12В -> 220В с управлением от мультивибратора, типа такой:
Соответственно, мультивибратор был доработан, чтобы выдавать 50-100Гц, причем управлять получилось даже 100Вт двигателем (12 В брались от 500Вт-ного компьютерного блока питания). Но все таки данное схемное решение годилось только для проверки возможности работы двигателей на высоких частотах, но не для практического применения.
Самое простое в итоге решение нашлось для 24В двигателя: управляющий генератор был собран на модуле Ардуино УНО, в качестве силового модуля взят ардуиновский модуль для управления коллекторными и шаговыми двигателями L298N, а также взят 24В импульсный блок питания.
Немного сложнее было с написанием подходящей программы для контроллера. Изначально решил для управления получить синус, но на практике самым действенным оказалось использование обычных прямоугольных импульсов. Программа, приведенная ниже, с небольшой доработкой позволяет регулировать площадь прямоугольника в зависимости от частоты, что необходимо учитывать особенно при управлении на низких частотах. В демонстрационном варианте для упрощения кода регулировка отдаваемой двигателю мощности не используется. Дискретность изменения частоты выбрана 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 - 150 Гц, при этом после 100-110 Гц ощущается значительная потеря мощности (все таки двигатель рассчитан на частоту 50/60Гц), но мне 100Гц как раз хватило.
Для управления двигателем на 220В конечно понадобится другой мост (у меня собран на IGBT, пробовал на киловатном двигателе, работает, если заинтересует дополню статью).