Какой хороший набор значений ШИМ для создания синусоидальных волн для трехфазного двигателя?

Я строю синхронно вращающийся разрядник для катушки тесла. У меня есть рабочий микроконтроллер (Kinetis K64F), управляющий инверторной платой на 230 вольт, и он вращает трехфазный синхронный двигатель. Сам двигатель синхронного типа, и мощность, которую я ему подаю, тоже должна быть синхронизирована с сетью переменного тока. Вот почему я решил создать собственное оборудование. Я могу сравнить производительность моего ходового привода с коммерческим и вижу, что мой мотор недостаточно мощен.

Купленный в магазине 3-фазный инвертор разгоняет двигатель до нужной скорости, в синхронном режиме, который медленно смещается в одну сторону без возможности его контролировать. В то время как моему приводу требуется более минуты дрожащего звука, чтобы набрать скорость, а затем он абсолютно стабилен с частотой сети. Я могу перемещать его в любую сторону на один градус за раз. Это то что мне нужно.

Поэтому я думаю, что это должны быть данные, которые я отправляю на 6 каналов PWM. Мое наивное решение для этого состояло в том, чтобы заполнить массив синусоидальными значениями при запуске. Я делаю 2 положительных полуцикла следующим образом:

внутренний угол; двойной параметр; внешняя двойная задержка[370];

 for (angle=0; angle<=179; angle++) {
   param  = 255 * sin (angle*PI/180);
   hold[angle] = param;      // fill first half of the array
   hold[angle+180] = param;  // fill second half with duplicate data
 }

Затем в периодическом прерывании я считываю этот массив синусоидальных значений следующим образом:

    if (angle1 < 180) { PWM1_SetRatio8(hold[angle1]); }
    else if (angle1 == 180) { PWM1_SetRatio8(0); }
    else if (angle1 > 180) { PWM2_SetRatio8(hold[angle1]); }
    if (angle1 >= 360) { angle1 = 0; PWM2_SetRatio8(0); }

    if (angle2 < 180) { PWM3_SetRatio8(hold[angle2]); }
    else if (angle2 == 180) { PWM3_SetRatio8(0); }
    else if (angle2 > 180) { PWM4_SetRatio8(hold[angle2]); }
    if (angle2 >= 360) { angle2 = 0; PWM4_SetRatio8(0); }

и так далее для угла3, все из которых находятся на расстоянии 120 градусов друг от друга. Теперь я вижу, что 180 за полупериод слишком много, поэтому я разделил его до 20, но без изменения мощности двигателя.

Я блокирую свой внутренний массив 360 значений точным импульсом пересечения нуля извне, чтобы поддерживать их синхронизацию.

Итак, я прочитал о Magic Sine Waves, и это звучит хорошо. Но мне пришлось бы переписать много кода, чтобы использовать его, и мне нужно охватить скорости от 58 до 62 Гц, что мне и предоставляют энергетические компании. Если бы я заполнил массив значений Magic Sine, я думаю, что получил бы перекрестное искажение при переключении на разные частоты линии.

Затем я прочитал о треугольной волне, модулирующей синусоидальные значения и добавляющей дополнительную 3-ю гармонику, чтобы получить больше мощности. Это звучит как путь вперед. Я могу прочитать кучу предварительно вычисленных значений во время выполнения и уйти. У кого-нибудь есть опыт создания такого набора данных? Или может подскажете, как это сделать?

Если ваш MCU достаточно быстр, вы можете использовать второй таймер, чтобы настроить период первого, чтобы придерживаться одной таблицы.
Достаточно ли быстр ШИМ, чтобы нужна была точность таблицы в 1 градус? Бессмысленно обновлять выходное значение чаще, чем один раз за импульс. Я ожидаю, что вы сможете обойтись примерно 12 значениями и по-прежнему вращать двигатель, что будет в основном просто прямоугольной волной в каждом канале.
Да, процессор работает на частоте 120 МГц, так что в моем распоряжении много скорости. Если я создам волшебную таблицу синусоидальных волн для 60 Гц, то я могу внести небольшие корректировки в значения «за кулисами», чтобы моя процедура вывода всегда просто выбрасывала самые свежие числа без вычислений.

Ответы (2)

Я не знаю, помогает ли это вообще, но я немного поработал над этой проблемой. Harmonic Elimination PWM Звучит точно так же, как волшебные синусоидальные волны. Просто подумав, я бы предварительно вычислил объединенную единую таблицу времени переключения для всех трех фаз сигнала и использовал одно прерывание. Когда происходят прерывания, переключите конкретный канал, затем измените время до следующего прерывания. Для изменения масштаба частоты используйте данные из таблицы. Это не должно вызывать проблем с искажениями в указанном вами частотном диапазоне. Он также должен быть достаточно точным, учитывая, что у вас процессор с частотой 120 МГц. У меня была базовая версия этого, работающая с ультразвуковым преобразователем на частоте 40 кГц на AVR с частотой 4 МГц.

Большое спасибо за это. Я использовал блендер, чтобы сделать точный рисунок, и выбрал модуляцию треугольной волны. Я установил длину половины цикла синусоиды в единицах блендера на такое же количество микросекунд, которое мне нужно. Таким образом, я могу считывать ширину импульса непосредственно с рисунка в usecs. Я знаю, что это не лучшее решение, но мне нужно преодолеть это препятствие, чтобы я мог заняться всеми другими проблемами!

Я попробовал решение Гранта, и двигатель оказался еще более слабым! Поэтому я вернулся к своим наивным синусоидальным значениям и внес небольшое изменение:

 for (angle=0; angle<=179; angle++) {
   param  = 265 * sin (angle*PI/180);
   if (param > 255) param = 255;
   hold[angle] = param;
   hold[angle+180] = param;
 }

Как вы можете видеть, я умножил значение синуса на 265 вместо 255 и обрезал значения обратно до 255, когда они переполнились. Это приводит к усилению и ограничению синусоидальной волны. При подключении к двигателю эти значения раскручивают его до синхронизации примерно за 3 или 4 секунды. Мой измеритель измеряет сверхъестественные 120,0 вольт между каждой из 3 фаз.

Я все еще думаю, что это наивное решение, но пока сойдет!