Энкодер для двигателя на Arduino и PID контроллере


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

Внешний вид проекта энкодера для двигателя на Arduino и PID контроллере

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

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

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

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

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

Принципы работы PID контроллера

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

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

Принцип работы пропорциональной составляющей ПИД регулятора

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

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

Принцип работы интегральной составляющей ПИД регулятора

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

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

Принцип работы дифференциальной составляющей ПИД регулятора

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

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

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

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

Внешний вид двигателя посмтоянного тока с энкодером

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

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

  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. Источник питания.

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

Внешний вид необходимых для проекта компонентов

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

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

Схема энкодера для двигателя на 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 – они оба имеют возможность формирования ШИМ (широтно-импульсная модуляция) сигналов. Эти контакты должны обязательно иметь возможность формирования ШИМ сигналов, иначе код программы работать не будет. PID контроллер управляет двигателем при помощи ШИМ.

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

Внешний вид конструкции проекта, собранной на макетной плате

Объяснение программы для Arduino

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

Сначала мы должны скачать и установить библиотеку PID контроллера для Arduino по следующей ссылке:

Download PID Controller Library for Arduino

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

Также в коде программы мы зададим значения коэффициентов __Kp, __Ki и __Kd. Они будут непосредственным образом влиять на выходное значение нашего контроллера.

Далее мы инициализируем все переменные, необходимые для проекта. Переменная encoder_count будет использоваться для подсчета количества генерируемых прерываний, то есть она будет подсчитывать число оборотов. В переменной integerValue будет храниться число, которое мы будем вводить в окне монитора последовательной связи. В символьной переменной incomingByte будут храниться символы, поступающие через последовательный порт связи. Переменная motor_pwm_value будет содержать значение, рассчитываемое в результате работы PID алгоритма, это значение будет поступать на ШИМ контакт для управления двигателем. Также мы создаем объект для работы с PID контроллером.

Далее, в функции setup(), мы задаем режимы работы для контактов ENCODER_A и ENCODER_B на ввод данных, а для контактов MOTOR_CW и MOTOR_CCW – режим работы на вывод данных. Далее мы задействуем на контакте ENCODER_A обработку прерывания по восходящему импульсу (RISING edge), при срабатывании прерывания будет вызываться функция encoder(). Более подробно о работе с прерываниями вы можете прочитать в следующей статье. Далее мы инициализируем PID контроллер с помощью функции begin(), затем мы производим его настройку с помощью параметров Kp, Ki и Kd. И, наконец, мы задаем ограничение на выходные значения контроллера.

В функции loop() мы первым делом проверяем доступна ли последовательная связь. Если последовательная связь доступна, мы принимаем из нее значение целого типа и сохраняем ее в переменной. Если мы принимаем символ ‘/n’, мы продолжаем цикл, далее мы устанавливаем точку назначения с помощью функции pidcontroller.setpoint(integerValue). Также мы выводим это значение целого типа в окно монитора последовательной связи для целей отладки.

Вычисляемое алгоритмом PID значение мы сохраняем в переменной motor_pwm_value. Если это значение больше 0, мы вызываем функцию motor_ccw(motor_pwm_value), иначе мы вызываем функцию motor_cw(abs(motor_pwm_value)).

Функция encoder() вызывается когда происходит прерывание на контакте ENCODER_B. В этой функции мы проверяем состояние контакта ENCODER_B, если оно HIGH, то мы инкрементируем счетчик, иначе мы декрементируем счетчик.

Далее рассмотрим функцию вращения двигателя по часовой стрелке. В этой функции проверяется больше ли 100 значение power. Если больше, то мы вращаем двигатель по часовой стрелке, иначе мы останавливаем двигатель.

Аналогичные операции производятся и в функции вращения двигателя против часовой стрелки. Если значение power больше 100, то мы вращаем двигатель против часовой стрелки, иначе мы останавливаем двигатель.

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

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

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

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

Вращение двигателя под управлением ПИД регулятора

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

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

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

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

(Проголосуй первым!)
Загрузка...
6 590 просмотров

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *