Математика на пальцах: ардуино головного мозга или линейно-квадратичный регулятор для управления электродвигателем / Хабр

Математика на пальцах: ардуино головного мозга или линейно-квадратичный регулятор для управления электродвигателем / Хабр Квадрокоптеры
Содержание
  1. Pid регулятор – что это
  2. Основные принципы работы pid контроллера (регулятора)
  3. Что такое двигатель с энкодером и как он работает
  4. D-параметр (дифференциальный)
  5. I-параметр (интегральный)
  6. P-параметр (пропорциональный)
  7. Библиотеки
  8. Видео, демонстрирующее работу проекта
  9. Имеющиеся в распоряжении железяки
  10. Индуктивный выброс напряжения
  11. Исходный код программы (скетча)
  12. Мосфет
  13. Моторы переменного тока
  14. Настройка и назначение pid регулятора
  15. Необходимые компоненты
  16. Новая формулировка линейно-квадратичного регулятора
  17. Полный код со стороны микроконтроллера
  18. Помехи от щёток
  19. Помехи по питанию, просадка
  20. Разделение питания
  21. Реле и мосфет
  22. Специальный драйвер
  23. Схема проекта
  24. Тестирование работы pid контроллера двигателя
  25. Управление щёточными моторами с arduino
  26. Уравнения максвелла на пальцах или как себя ведёт двигатель постоянного тока
  27. Уроки ардуино. регулировка скорости вращения двигателя без обратной связи. измерение периода и частоты сигналов с помощью ардуино. | оборудование, технологии, разработки
  28. Экранирование
  29. Постановка задачи: как со школьными знаниями дойти до выводов университетского уровня
  30. Заключение

Pid регулятор – что это

PID регулятор представляет собой компактное устройство, интегрированное в контур управления, где в обязательном порядке имеется обратная связь. Такой прибор используют для поддержания каких-либо заданных режимов и чаще всего, это коррекция температуры воздуха.

Сенсорные датчики снимают показания по существующим в данный момент параметрам, и подают сигнал на регулирующее устройство. Такому контроллеру присущи практически идеальные показатели точности переходных процессов, что полностью обеспечивает результативность своевременной регулировки параметров.

Основные принципы работы pid контроллера (регулятора)

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

Более подробно о том, что такое PID контроллер (регулятор) и как он работает, вы можете прочитать в Википедии. Но как применить принципы работы PID контроллера в микроконтроллере? Этой информации в Википедии уже нет.

Основные принципы работы PID контроллера показаны на следующей картинке. Рассмотрим кратко основные составляющие этого процесса.

PID контроллер получил такое название из-за принципов обработки сигналов ошибки, которые возникают в управляемом им процессе. На представленном рисунке вы можете увидеть, в пропорциональной части регулятора ошибка (сигнал ошибки) умножается на константу Kp.

В интегральной части ошибка умножается на константу Ki и затем интегрируется, а в дифференциальной части ошибка умножается на константу Kd, а затем дифференцируется. После всего этого все эти три значения суммируются чтобы сформировать выходное значение регулятора.

В PID контроллере параметры Kp, Kd и Ki называются коэффициентами усиления. Также они называются P, I и D параметрами регулятора. Эти коэффициенты настраиваются индивидуально, чтобы обеспечить выполнение заданного набора требований к системе, например, насколько чувствительной или устойчивой она должна быть. Рассмотрим каждый из этих параметров более подробно.

Что такое двигатель с энкодером и как он работает

Двигатель с энкодером (encoder motor) – это электродвигатель постоянного тока (со щетками), к которому прикреплен энкодер. Ранее на нашем сайте мы уже рассматривали подключение инкрементального энкодера к плате Arduino, можете прочитать эту статью если есть желание.

В двигателе с энкодером инкрементальный энкодер закрепляется на электродвигатель постоянного тока и обеспечивает обратную связь в этой связке при помощи отслеживания скорости или положения оси двигателя. На рынке сейчас доступно много типов двигателей, также существуют различные типы энкодеров: инкрементальные, абсолютные, оптические, магнитные и т.д.

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

D-параметр (дифференциальный)

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

Значение на выходе PID контроллера является суммой с выхода трех рассмотренных контроллеров. Но необязательно чтобы всегда работали эти три контроллера, при желании любой из этих контроллеров можно выключить из работы, просто приравняв нулю коэффициент усиления в его ветви.

I-параметр (интегральный)

В интегральном контроллере происходит суммирование всех значений ошибки, при этом полученная сумма умножается на константу Ki. В подобном контроллере легко видеть, что результатом интегрирования является область лежащая под кривой: на представленном рисунке эта кривая показана синим цветом для положительной области и желтым цветом для отрицательной области.

В сложных системах интегральный контроллер используется для устранения постоянной ошибки, возникающей при работе системы. При этом неважно насколько мала величина ошибки, все равно суммирование достаточно большого их числа обеспечит достаточное значение на выходе контроллера. На представленном рисунке эта ошибка показана зеленым цветом.

P-параметр (пропорциональный)

Допустим, ошибка в системе изменяется во времени, как показано красной линией на представленном рисунке. В пропорциональном контроллере эта ошибка умножается на коэффициент усиления Kp. То есть если ошибка большая, то и значение ошибки на выходе контроллера будет большим, если ошибка равна 0, то и на выходе будет 0, если ошибка отрицательная – на выходе также будет отрицательное значение.

Библиотеки

У меня есть удобная библиотека для управления мотором – GyverMotor, документацию можно почитать вот здесь. Особенности библиотеки:

  • Контроль скорости и направления вращения
  • Работа с ШИМ любого разрешения
  • Программный deadtime
  • Отрицательные скорости
  • Поддержка всех типов драйверов
  • Плавный пуск и изменение скорости
  • Режим “минимальная скважность”

Видео, демонстрирующее работу проекта

Источник статьи

3 005 просмотров

Имеющиеся в распоряжении железяки

В распоряжении имеется оптический энкодер (1000 пульсов на оборот), электродвигатель (750 rpm при 12В без нагрузки),

и atmega 328 (arduino nano).

В зависимости от PWM сигнала, что я подаю на вход L6201, он выдаёт разное напряжение на электродвигатель. То есть, мой микроконтроллер умеет управлять только напряжением на клеммах электродвигателя.

Индуктивный выброс напряжения

Мотор – это индуктивная нагрузка, которая в момент отключения создаёт индуктивные выбросы. У мотора есть щетки, которые являются источником искр и помех за счёт той же самой индуктивности катушки. Сам мотор потребляет энергию не очень равномерно, что может стать причиной помех по линии питания, а пусковой ток мотора так вообще сильно больше рабочего тока, что гарантированно просадит слабое питание при запуске.

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

Отсечь индуктивный выброс с мотора можно при помощи самого обычного диода, чем мощнее мотор, тем мощнее нужен диод, то есть на более высокое напряжение и ток. Диод ставится встречно параллельно мотору, и чем ближе к корпусу, тем лучше. Точно таким же образом рекомендуется поступать с электромагнитными клапанами, соленоидами, электромагнитами и вообще любыми другими катушками. Логично, что диод нужно ставить только в том случае, если мотор или катушка управляется в одну сторону. Важные моменты:

  • При работе с драйвером и управлением в обе стороны диод ставить не нужно и даже нельзя!
  • При управлении ШИМ сигналом рекомендуется ставить быстродействующие диоды (например серии 1N49xx ) или диоды Шоттки (например серии 1N58xx).
  • Максимальный ток диода должен быть больше или равен максимальному току мотора.
  • Защитный диод, принимающий на себя обратный выброс ЭДС самоиндукции, также называется шунтирующим диодом, снаббером, flyback диодом.
  • В природе существуют мосфеты со встроенным защитным диодом. Этот диод является отдельным элементом и такой мосфет обычно имеет нестандартный корпус, читайте документацию на конкретный транзистор.
  • Диод, который показан на схематическом изображении мосфета, не является защитным диодом: это слабый и медленный “паразитный” диод, образованный при производстве транзистора. Он не защитит мосфет от выброса, нужно обязательно ставить внешний!

Исходный код программы (скетча)

Мосфет

Полевой транзистор, он же мосфет, позволяет управлять скорость вращения мотора при помощи ШИМ сигнала. При использовании мосфета обязательно нужно ставить диод, иначе индуктивный выброс с мотора очень быстро убьёт транзистор. Скорость мотора можно задавать при помощи ардуиновской analogWrite(пин, скорость) .

Вместо “голого” мосфета можно использовать готовый китайский модуль:

Купить мосфет модуль можно на Aliexpress.

Моторы переменного тока

Мотором переменного тока (220V от розетки) можно управлять при помощи диммера на симисторе, как в уроке про управление нагрузкой.

Настройка и назначение pid регулятора

В процессе настройки производится сравнение регулируемой величины с заданным значением, и при наличии отклонения в объект поступает воздействие, восстанавливающее номинал
Источник electricalschool.info

Существует, как минимум, два метода настройки PID: 

  • Синтез предусматривает расчет параметров на основании самой модели. Такая регулировка получается, чуть ли не идеальной, но она требует глубокой осведомленности в теоретических познаниях автоуправления, следовательно, для этого нужно иметь специальное образование.
  • Ручной метод основан на пробах – его также зачастую в шутку называют «методом научного тыка» – здесь основанием являются показатели готовой системы, которые корректируются коэффициентом регулятора. После наблюдения за системой в активно фазе, берутся конечные показатели и исправляются в нужную сторону. Так продолжается до тех пор, пока система не выйдет на желаемый уровень.

Необходимые компоненты

  1. Плата Arduino Nano (купить на AliExpress).
  2. N20 Encode Motor (двигатель N20 с энкодером) (купить на AliExpress).
  3. Регуляторы напряжения BD139 (2 шт.) и BD140 (2 шт.) (купить на AliExpress).
  4. Транзистор BC548 – 2 шт. (купить на AliExpress).
  5. Резистор 4,7 кОм – 2 шт. (купить на AliExpress).
  6. Резистор 100 Ом – 2 шт. (купить на AliExpress).
  7. Макетная плата.
  8. Соединительные провода.
  9. Источник питания.

Внешний вид необходимых для проекта компонентов показан на следующем рисунке.

Новая формулировка линейно-квадратичного регулятора

Внимание: тут предполагается, что вы хорошо прочли мою статью про линейно-квадратичный регулятор.

В ней наш пример моделировался следующей системой уравнений:

тут x_k — это положение каретки, v_k — её скорость, а u_k — её ускорение. Из предыдущей секции мы знаем, что ускорение очень нелинейно зависит от приложенного напряжения, и меня это слегка напрягает, так как микроконтроллер умеет напрямую управлять только напряжением.

тут x_k — это положение каретки, v_k — её скорость, а u_k — это уже не ускорение каретки, а напряжение, которое я прикладываю к клеммам электромотора. Для конкретно моего двигателя я нашёл a = .97, b = .218.

Вот код, который находит коэффициенты зависимости переменной управления (напряжение на клеммах) от вектора состояний (положение и скорость каретки). У меня каретка может максимально отклоняться от нулевого состояния на 245мм, поэтому я поставил начальную нулевую скорость и положение 245мм. Задача состоит в том, чтобы остановить каретку в нулевом положении (центр рельса).

Строчки 17-53 задают жесткие условия нашей системы (начальные и конечные условия, линейный переход состояний), а строчки 55-70 — оптимизируемую функцию. Основная задача — сходимость положения и скорости к нулю (строчки 56 и 61). Я постепенно увеличивал ограничение на управление (строчка 66), покуда результат не вписался в физические параметры системы (при данных параметрах напряжение не выходит за 24В).

Вот так выглядят теоретические кривые положения, скорости и напряжения, которое необходимо для их достижения:

Таким образом, вышеозначенный код говорит, что напряжение, которое необходимо приложить, может быть рассчитано как:

где x_k — это текущая позиция каретки, а v_k — её скорость.

Полный код со стороны микроконтроллера


Итак, самая последняя формула и есть наиглавнейшая для этой статьи,

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

Давайте я его приведу её основную часть:

void loop() {
    vi = xi-xi_1;
    int ui = 255.*(-0.000973669*xi -0.0563218*vi)/24.;
    xi_1 = xi;
    set_speed(ui);
    delay(2);
}

Подсчёт значений экодера (функция ISR) заслуживает отдельной небольшой статьи, это не суть важно на данный момент. Что важно — это функция loop(). Я считаю текущую скорость как разность положений энкодера сейчас и две миллисекунды назад; затем текущее напряжение ui подсчитывается по только что приведённой формуле. Всё! Вот и весь тот линейно-квадратичный регулятор.

Неплохо бы сравнить то, что мы натеоретизировали, с тем, что получается на практике. Вот эта картинка даёт сравнение:

Таким образом, реальное положение каретки слегка отличается от теоретического, я полагаю, что это из-за неучтённого трения: чем ближе к нулю, тем меньше подаваемое напряжение, и однажды оно уже не может бороться с трением. Борьба с этим феноменом будет темой одной из следующих статей. Stay tuned!

Смотрите про коптеры:  Квадрокоптер SYMA X5UW с камерой, красный, отзывы владельцев в интернет-магазине СИТИЛИНК (412329) - Ростов-на-Дону

Удачи вам и будьте любопытными!

Помехи от щёток

Искрящиеся щетки мотора, особенно старого и разбитого, являются сильным источником электромагнитных помех, и здесь проблема решается установкой керамических конденсаторов с ёмкостью 0.1-1 мкФ на выводы мотора. Такие же конденсаторы можно поставить между каждым выводом и металлическим корпусом, это ещё сильнее погасит помехи. Для пайки к корпусу нужно использовать мощный паяльник и активный флюс, чтобы залудиться и припаяться как можно быстрее, не перегревая мотор. Математика на пальцах: ардуино головного мозга или линейно-квадратичный регулятор для управления электродвигателем / Хабр

Помехи по питанию, просадка

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

Разделение питания

Если описанные выше способы не помогают – остаётся только одно: разделение питания. Отдельный малошумящий хороший источник на МК и сенсоры/модули, и отдельный – для силовой части, в том числе мотора. Иногда ради стабильности работы приходится вводить отдельный БП или отдельный аккумулятор для надёжности функционирования устройства.

Реле и мосфет

Если объединить реле и мосфет – получим весьма колхозную, но рабочую схему управления скоростью и направлением мотора:

Специальный драйвер

Лучше всего управлять мотором при помощи специального драйвера, они бывают разных форм и размеров и рассчитаны на разное напряжение и ток, но управляются практически одинаково. Рассмотрим основные драйверы с китайского рынка:

ДрайверVmotТок (пик)

Стоимость

Aliexpress
L298N4-50V1A (2A)100рКупить
MX15082-9.6V1.5A (2.5A)20рКупить
TA65863-14V5A (7A)100р (чип 30р)Купить, купить, купить чип
L9110S2.5-12V0.8A (1.5A)50рКупить
TB66124.5-13.5V1.2A (3A)80рКупить
BTS79605.5-27V10A (43A)300рКупить
Большой3-36V10A (30A)700рКупить

Остальные драйверы смотри у меня вот тут. Схемы подключения и таблицы управления:

Математика на пальцах: ардуино головного мозга или линейно-квадратичный регулятор для управления электродвигателем / Хабр

Пины направления управляются при помощи digitalWrite(pin, value) , а PWM – analogWrite(pin, value) . Управление драйвером по двум пинам может быть двух вариантов:

Схема проекта

Схема энкодера для двигателя на Arduino и PID контроллере представлена на следующем рисунке.

Принцип работы схемы достаточно прост. Двигатель N20 с экнкодером имеет 6 контактов, контакты M1, M2 используются для подачи питания на двигатель (он у нас очень маленький, работающий от 3.3V). Контакты VCC и GND используются для питания цепи энкодера.

Для питания энкодера необходимо подавать напряжение 5V, иначе цепь энкодера не будет корректно работать. Контакты PIN_A и PIN_B двигателя непосредственно подключены к энкодеру. Измеряя состояние этих контактов, мы легко можем определить число оборотов двигателя в минуту (RPM).

Наш двигатель N20 имеет 15RPM и передаточное число 1:2098, что означает, что ось двигателя должна совершить 2098 оборотов для того чтобы вспомогательный вал (на выходе коробки передач) совершил один оборот. Контакты PIN_A и PIN_B двигателя подключены к контактам 9 и 10 платы Arduino – они оба имеют возможность формирования ШИМ (широтно-импульсная модуляция) сигналов.

Также наша схема содержит драйвер двигателя в виде H-моста. Драйвер двигателя у нас имеет такую схему, что с помощью него мы можем управлять двигателем с использованием всего 2-х контактов платы Arduino. Также он защищает двигатель от ложных срабатываний.

Тестирование работы pid контроллера двигателя

Для тестирования работы проекта мы прикрепили двигатель с помощью двухстороннего скотча на распределительный ящик. Также мы использовали небольшой понижающий конвертер для питания двигателя поскольку он у нас питается от 3.3V.

Также мы подключили USB кабель к плате Arduino, с его помощью устанавливается начальная тока PID контроллера. Также по USB кабелю мы передаем отладочную информацию.

Более подробно работу нашего проекта вы можете посмотреть на видео, приведенном в конце статьи.

Управление щёточными моторами с arduino

Как вы знаете, никакую нагрузку мощнее светодиода нельзя подключать к Ардуино напрямую, особенно моторчики. Ардуино, да и вообще любой микроконтроллер – логическое устройство, которое может давать только логические сигналы другим железкам, а те уже могут управлять нагрузкой.

При помощи обычного реле можно просто включать и выключать мотор по команде digitalWrite(пин, состояние) , прямо как светодиод:

При помощи двойного модуля реле (или просто двух реле) можно включать мотор в одну или другую сторону, а также выключать:

Купить модуль реле можно на Aliexpress.

Уравнения максвелла на пальцах или как себя ведёт двигатель постоянного тока

Совсем недавно я

о том, что из себя представляют уравнения Максвелла. Давайте повторим: уравнений Максвелла четыре по количеству следующих законов:

1. Закон Гаусса, «на пальцах» это просто закон сохранения: энергия из ниоткуда не берётся и в никуда не уходит.2. Закон Гаусса для магнитного поля — то же самое, только для магнитного, а не электрического поля.3. Закон Фарадея: если мы двигаем магнитами, то они порождают электрическое поле.4. Закон Ампера: если мы двигаем электрическим полем, то порождаем магнитное.

Векторные поля, являющиеся решением этих четырёх уравнений, называются электрическим полем и магнитным. В статье про магнитную левитацию я интересовался в основном законами Гаусса, в данной статье мне интересны законы Ампера и Фарадея. Как вообще работает электродвигатель постоянного тока?

Давайте попробуем представить, как работает такой двигатель. Пренебрегаем всем чем только можно (индуктивность, трение и прочее) и вспоминаем только курс седьмого-восьмого класса школы, а именно — закон Ома. Итак, закон ома гласит, что напряжение — это произведение силы тока на сопротивление (U=IR).

Сопротивление обмоток двигателя постоянно, поэтому, с точностью до постоянного множителя, напряжение на обмотке и ток через неё — это одно и то же. Далее, закон Ампера говорит, что сила, прикладываемая к ротору, пропорционалена пропускаемому току, а значит, и нашему напряжению.

Но наш двигатель вполне подчиняется второму закону Ньютона (F=ma). Таким образом, если у меня на обмотке двигателя постоянное напряжение, то это влечёт за собой постоянное ускорение вала двигателя (масса-то не меняется!). А вот этот вывод начинает уже совсем плохо пахнуть, ведь если у меня есть постоянное ускорение, то я так и скорость света преплюнуть могу…

Тут самая пора вспомнить о том, что есть вариант не подавать напряжение на двигатель, а крутить его вал, наоборот снимая напряжение с него (см. велогенератор). Это следствие закона Фарадея: если мы крутим магнитами, то это порождает электромагнитную индукцию.

И ведь какая заковыка: если мы-таки подаём напряжение на двигатель, то ротор крутится (закон Ампера), но при этом сам генерирует ЭДС (закон Фарадея), которая борется с поданным напряжением, уменьшая его! Таким образом, закон Ома для двигателя будет выглядеть скорее как U — I*R — C*v = 0.

Закон Ампера нам гласит о том, что ток пропорционален силе, создаваемой магнитным полем. А второй закон Ньютона гласит о том, что сила пропорциональна ускорению (а ускорение — это производная скорости по времени!). Таким образом, закон Ома для двигателя можно записать как u(t)

— const1 * v'(t) — const2 * v(t) = 0. В дискретном мире производную v'(t) можно представить как v'(t) = v(t 1)-v(t), таким образом, закон Ома можно записать как v(t 1) = a*v(t) b*u(t), где a и b — это константы, зависящие от физических параметров двигателя и от временного шага.

Я подал на остановленный двигатель четыре разных постоянных напряжения (24В, 18В, 12В, 6В) и записал скорость передвижения каретки при помощи инкрементального энкодера. Вот так выглядели испытания:

Вот эта картинка даёт четыре разных графика (некрасивые, зубчатые) для четырёх напряжений:

А также она даёт теоретическую кривую (я нашёл a=0.97, b=0.218) для этих напряжений. Параметры a и b найдены при помощи крайне тупого кода фиттинга. Разумеется, в реальном мире трение ненулевое, поэтому моя теоретическая кривая не совпадает со всеми измерениями, но постольку, поскольку я предполагаю, что моя каретка будет чаще двигаться с напряжением в районе нуля, а не в районе максимума, то теоретическая кривая лучше аппроксимирует движение при малых напряжениях.

Уроки ардуино. регулировка скорости вращения двигателя без обратной связи. измерение периода и частоты сигналов с помощью ардуино. | оборудование, технологии, разработки

Измерение частоты с помощью Ардуино

Продолжение разработки ПИД-регулятора скорости вращения двигателя постоянного тока. В уроке запустим двигатель без обратной связи. Научимся измерять временные параметры импульсов дискретного сигнала.

Предыдущий урок     Список уроков     Следующий урок

Попробуем управлять двигателем только с помощью ШИМ, не используя датчик оборотов.

Регулировка скорости вращения двигателя без обратной связи.

Я написал простую программу, которая формирует ШИМ пропорциональный напряжению на входе A0.

Она:

  • Измеряет напряжение сигнала на входе A0.
  • Усредняет его для защиты от помех.
  • Формирует ШИМ с коэффициентом заполнения пропорциональным среднему напряжению на выводе A0.
  • При формировании ШИМ учитывает “мертвое время”.
  • Выводит значение ШИМ в последовательный порт для контроля.

Вот скетч программы:

Поясню, что такое “мертвое время”. Допустим, ШИМ работает с высокой частотой, например, 62,5 кГц. Если мы зададим ему коэффициент заполнения 1, то это означает, что с периодом 16 мкс будет формироваться импульс длительностью 0,0625 мкс. Импульс такой короткой длительности транзисторный ключ не отработает, не успеет. В результате транзистор будет какое-то время в полуоткрытом режиме и не к чему хорошему это не приведет. Особенно на высоком напряжении.

Поэтому необходимо искусственно ограничивать импульсы минимальной длины. Если значение 1 транзистор не способен отработать, значит, вместо него необходимо формировать 0. Тоже самое в конце диапазона ШИМ. Например, значение 254 необходимо заменить на 255.

Отработку ”мертвого времени” производит следующий блок программы.

#define DEAD_TIME 10  // мертвое время

// мертвое время
if( valPwm < DEAD_TIME ) valPwm=0;
if( valPwm > (MAX_PWM – DEAD_TIME) ) valPwm= MAX_PWM;

Если значение ШИМ меньше заданного, оно заменяется на 0. Если больше, то оно равно максимальному значению ШИМ.

В программе в определенных пределах можно изменять частоту периода ШИМ.

TCCR2B= 1; // 62 500 Гц
//TCCR2B= 2; // 7 812 Гц
// TCCR2B= 3; // 1 953 Гц
// TCCR2B= 4; // 977 Гц
// TCCR2B= 5; // 488 Гц
// TCCR2B= 6; // 244 Гц
// TCCR2B= 7; // 61 Гц

Для формирования ШИМ используется таймер 2 и вывод 11.

Можно переключиться на вывод 3. Изменения коснутся только строки.

TCCR2A= 0b00100011;

Использование других выводов недопустимо.

Загружаем скетч в контроллер, открываем монитор последовательного порта.

Значение ШИМ мотора

Вращаю переменный резистор, подключенный к входу A0. Монитор показывает изменение ШИМ. В положении резистора от 0 до максимума ШИМ равен 0,  затем скачком меняется до 10. Дальше плавное изменение до 245 и скачок до 255. Т.е. заданное ”мертвое время” 10 отрабатывается правильно.

Дальше подключаем к схеме питание 12  В и проверяем работу ключа с мотором-вентилятором. Я проверил для разных частот ШИМ. Как не странно, лучше всего работает на низких частотах 244 и 61 Гц. Мотор начинает вращаться с ШИМ равным 30. На частоте 62,5 кГц вентилятор начинает вращаться при значении ШИМ 60. На средних частотах он еще противно пищит.

Когда Игорь проводил эти испытания на мощном двигателе 500 Вт, он категорично выбрал высокую частоту 62,5 кГц. На высоких частотах его двигатель вращается равномерно, без вибраций. Тише работает, начинает крутиться с меньшего значения ШИМ. Т.е. для каждого двигателя лучше выбирать частоту ШИМ экспериментально.

В любом случае регулировка с помощью ШИМ без обратной связи работает, скорость двигателя изменяется плавно. Конечно, частота оборотов непредсказуема и зависит от механической нагрузки.

Измерение периода и частоты входных импульсов с помощью Ардуино.

Чтобы стабилизировать скорость вращения мотора необходимо ее измерять. А скорость в свою очередь определяется частотой импульсов датчика Холла. Об этом сказано в предыдущем уроке. Как следствие возникает задача – измерение периода и частоты импульсов. Давайте на короткое время забудем про двигатель и научимся измерять частоту импульсов дискретного сигнала.

Задача не очень простая. Скорость вращения мотора у Игоря достигает 12000 об/мин. При такой скорости и использовании с датчиком Холла двух магнитов надо измерять временные параметры с периодом 2,5 мс. Если мы хотим обеспечить точность не более 1%, то разрешающая способность измерителя должна быть не более 250 мкс.

Но бывают и более скоростные двигатели. Часто используются датчики, которые формируют более 2 импульсов на оборот. Это еще уменьшает время дискретности измерителя.

А с другой стороны двигатель может вращаться и со скоростью 60 об/мин. Это соответствует периоду импульсов 0,5 сек.

Вывод:

  • наш измеритель должен иметь высокую разрешающую способность по времени (не более десятков мкс)
  • и широкий диапазон измерения (не менее 1 сек).

Измерять период с точностью десятков микросекунд чисто программными средствами невозможно. Даже если мы подадим измеряемый сигнал на вход внешнего прерывания, вряд ли это позволит решить задачу. Обработка прерывания может задерживаться другими прерываниями, например, счетчиком системного времени. А это будет искажать время измерения.

Поэтому будем использовать аппаратный узел микроконтроллера – таймер в режиме захвата. У микроконтроллера ATmega328 только таймер 1 может работать в этом режиме.

Лучше будет, если вы почитаете об этом режиме в документации на ATmega328. Я расскажу коротко и чисто с практической точки зрения.

Входной сигнал подключаем к входу ICP1 (вывод 8). Использование других выводов недопустимо.

Микроконтроллер выделяет нужный фронт сигнала на входе ICP1 (я задал перепад с высокого уровня на низкий) и по нему перегружает содержимое таймера 1 в специальный регистр ICR1. Можно считать значение этого регистра и тем самым узнать, когда был перепад входного сигнала, даже если чтение произошло позже самого события.

Дальше немного сложно в понимании, но объем информации небольшой. При желании можно разобраться по шагам.

Мы задаем режим работы таймера 1. Переводим его в режим простого счетчика от внутреннего генератора с максимальной частотой. В этом режиме каждые 0,0625 мкс к счетчику прибавляется 1. При достижении максимального значения 65536, он начинает считать с 0. Также задаем режимы для захвата и разрешаем прерывания таймера 1 по захвату и переполнению.

// установка режима захвата таймера 1
pinMode (8, INPUT_PULLUP); // вход сигнала захвата ICP, входные измеряемые импульсы
TCCR1A = 0; // нормальный режим работы таймера 1
TCCR1B = 0; // выбор отрицательного фронта входного сигнала
TCCR1B = (1 << ICNC1) | (1 << CS10); // включение подавления шума входного сигнала, частота тактирования – внутренний генератор, без деления
TCNT1 = 0; // сброс счетчика
TIMSK1 = (1 << ICIE1) | (1 << TOIE1); // разрешения прерываний таймера 1 по захвату и переполнению

Создаем обработчик прерывания по захвату (фронту входного сигнала).

// прерывание по сигналу захват (по отрицательному фронту измеряемого сигнала)
ISR (TIMER1_CAPT_vect) {
  periodTime = (unsigned long)ICR1 | (((unsigned long)numOverflowTimer1) << 16);
  TCNT1 -= ICR1;
  numOverflowTimer1 = 0;
}

В нем мы считываем значение регистра ICR1 и сохраняем его в переменной periodTime.

Дальше нам надо сбросить счетчик таймера в 0, чтобы отсчет следующего времени начался с 0. Но с момента, когда реально был захват, прошло неизвестное нам время. Надо было его сбрасывать в 0 в момент захвата. Но тогда мы, возможно, отрабатывали другое прерывание. Поэтому мы вычитаем из счетчика значение его в момент захвата.

TCNT1 -= ICR1;

Что равносильно сбросу в 0 в момент захвата.

В результате вышеописанных действий в переменной periodTime оказывается время между захватами. Т.е. время между отрицательными фронтами входного сигнала. Реальное время будет равно значению periodTime, умноженному на дискретность таймера 0,0625 мкс.

Все было бы хорошо, но при периоде сигнала более 4096 мкс ( 65536 * 0,0625 мкс) таймер 1 переполнится. Значит, нам надо считать еще и переполнения таймера 1.

Для этого создаем обработчик прерываний по переполнению таймера.

// прерывание по переполнению таймера 1
ISR (TIMER1_OVF_vect) {
  numOverflowTimer1 ;
}

И полученное значение прибавляем к periodTime.

periodTime = (unsigned long)ICR1 | (((unsigned long)numOverflowTimer1) << 16);

Теперь все. В переменной periodTime получаем период входных импульсов. Для вычисления реального времени необходимо умножить его на 0,0625 мкс.

Пишем программу измерения временных параметров входного сигнала и проверяем ее работу.

Для проверки формируем на выводе 5 сигнал ШИМ с частотой 976,56 Гц.

analogWrite(5, 200); // формирование тестовых импульсов на выводе 5 (976,56 Гц)

Соединяем вывод 8 с выводом 5. Запускаем монитор последовательного порта.

Тестирование измерителя частоты Ардуино

Тестовый сигнал формируется аппаратным способом, поэтому имеет высокую стабильность.

Надо проверить работу нашего измерителя в полном диапазоне.

Для этого тестовый сигнал на выводе 5 формируем с помощью системного времени Ардуино.

Период  задается в строке.

#define TEST_TIME 10 // время периода тестового сигнала (мс)

Проверяем для периода 10 мс.

Тестирование измерителя частоты

Вот период 100 мс

Тестирование измерителя частоты Ардуино

Период 1 сек.

Тестирование измерителя частоты Ардуино

Высокой точности от формирования тестового сигнала с помощью системного времени ждать не приходится. Но измеритель работает нормально в широком диапазоне периода входного сигнала.

Такой способ измерения частоты и периода сигналов может использоваться в других приложениях.

В следующем уроке вернемся к двигателю. Будем измерять его скорость вращения.

Предыдущий урок     Список уроков     Следующий урок

1

Экранирование

В отдельных случаях критичными являются даже наводки от питающих проводов моторов, особенно при управлении ШИМ мощными моторами и управлении мощными шаговиками в станках. Такие наводки могут создавать сильные помехи для работающих рядом чувствительных электронных компонентов, на аналоговые цепи, наводить помехи на линии измерения АЦП и конечно же на радиосвязь.

Защититься от таких помех можно при помощи экранирования силовых проводов: экранированные силовые провода не всегда удаётся купить, поэтому достаточно обмотать обычные провода фольгой и подключить экран на GND питания силовой части. Этот трюк часто используют RC моделисты, летающие по FPV.

Постановка задачи: как со школьными знаниями дойти до выводов университетского уровня

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

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

Задача для этой статьи — показать, как воплотить в железе одномерный пример из статьи про линейно-квадратичный регулятор. Грубо говоря, я хочу написать написать управление для сервомотора: у меня есть текущее положение оси привода и текущая скорость её вращения, я хочу её остановить в заданном положении.

Продолжая рабочий эксгибиционизм, знакомлю вас с Bubble Bobble, который живёт у нас с коллегой в кабинете. Он рецензирует статьи для конференции SIGGRAPH.

Заключение

Подобную систему можно собрать своими руками, например, для поддержания микроклимата в каком-либо помещении, но это уже тема для отдельной статьи и мы выложим ее немного позже. На данный момент у вас есть возможность ознакомиться PID регулятором на Arduino в общих чертах, чтобы определить его необходимость в вашем хозяйстве.

Оцените статью
Радиокоптер.ру
Добавить комментарий

Adblock
detector