Официальный сайт компании Arduino по адресу arduino.cc
Замена контролера сервы на Ардуино.
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Втр, 08/09/2020 - 08:50
Всем привет.
Пытаюсь сделать контролер сервы из Ардуино.
Спалил одну, запас есть, но интересно сделать контролер самому.
Выпаял родной контролер, подключил к Ардуино энкодер и моторчик через драйвер L298n. Схема подключения на всякий случай:
Код:
#define PIN_ENA 6 // Вывод управления скоростью вращения мотора №1 #define PIN_IN1 5 // Вывод управления направлением вращения мотора №1 #define PIN_IN2 4 // Вывод управления направлением вращения мотора №1 #define PIN_POT A7 // Чтение данных с энкодера //#define PIN_ANGLEIN A6 // Получение угла с основного контролера int StartAngle; int PrevInput = -1; void setup() { Serial.begin(9600); pinMode(PIN_POT, INPUT); pinMode(PIN_ENA, OUTPUT); pinMode(PIN_IN1, OUTPUT); pinMode(PIN_IN2, OUTPUT); //pinMode(PIN_ANGLEIN A6, INPUT); } void loop() { int angleInput = /*map(analogRead(PIN_ANGLEIN), 0, 255, 0, 180)*/ 90; int angleEncoder = map(analogRead(PIN_POT), 0, 1023, 0, 180); if (angleInput != PrevInput) { PrevInput = angleInput; StartAngle = angleEncoder; } //-------------------------------------------- if (angleInput - angleEncoder > 2) //увеличение угла { analogWrite(PIN_ENA, 90); digitalWrite(PIN_IN1, LOW); digitalWrite(PIN_IN2, HIGH); } //-------------------------------------------- if (angleEncoder - angleInput > 2) //уменьшение угла { analogWrite(PIN_ENA, 90); digitalWrite(PIN_IN1, HIGH); digitalWrite(PIN_IN2, LOW); } //-------------------------------------------- if (angleInput == angleEncoder - 1 || angleInput == angleEncoder || angleInput == angleEncoder + 1) { digitalWrite(PIN_IN1, HIGH);//LOW digitalWrite(PIN_IN2, HIGH);//LOW } }
Строки
pinMode(PIN_ANGLEIN A6, INPUT);
int angleInput = /*map(analogRead(PIN_ANGLEIN), 0, 255, 0, 180)*/ 90;
подразумевают получение сигнала от основного контролера, но пока закомментированы, а угол задаю в скетче, в данном случае 90 градусов.
Углы (переменные):
angleInput - требуемый угол (получаем с основного контролера)
PrevInput - предыдущий требуемый угол
StartAngle - угол с которого начинается движения (угол энкодера в начале движения)
angleEncoder - угол энкодера
Проблема такая:
Даже на минимальной скорости вал проезжает заданную позицию, возвращается назад, снова проезжает, снова назад и так бесконечно. Получаю колебания +-10 градусов возле заданного угла. Пытался делать противоход, т.е. при "перелете" запускал моторчик в другую сторону- не помает.
Вопросы:
Как этот момент реализован в сервомоторе?
Почему серва из любого угла на максимальной скорости приезжает, достаточно точно, в любой угол и без всяких колебаний останавливается в заданной точке?
PI регулятор. С твоим кодом понятно, что ты не знаешь ни теории управления, ни цифровой обработки сигналов, так что начинай с литературы по этим направлениям.
Например http://www.cds.caltech.edu/~murray/amwiki/index.php/Main_Page
PI регулятор.
Большое спасибо за ответ.
Нашел статью http://robofob.ru/materials/articles/pages/Karpov_mobline1.pdf , очень доходчиво разжевано про ПИД-регулятор.
Разобрали каждую строчку, что делает, зачем делает. Вроде разобрались с интерпретацией результатов (ШИМ от 100 до 255, ниже 100 мотор не крутится, только пищит). Используем только пропорциональную и интегральную составляющие. return up + ui.
Код:
Но проблема с колебаниями осталась. Какие бы значения Kp и Ki не выставляли, происходят колебания вокруг заданной токчи ровно в 4 градуса, 2 в + и 2 в -.
Немного изменили концовку:
и добавили 5 сек задержку. Серва попадает в заданное положение - включается задержка. 5 сек проходит - серва отпрыгивает на два градуса, то в право, то в лево поочередно и снова возвращается в заданный угол.
А что это такое? Перечитай-ка еще раз.
А что это такое? Перечитай-ка еще раз.
Результат функции ПИД контрол выводится с + или с -. В зависимости от знака крутим моторчик в ту или иную сторону. А модулем от ПИД через мар задаем ШИМ на пин ENA. Ведь на ENA мы не можем минусовое значение подать.
А что это такое? Перечитай-ка еще раз.
Вот выдержка из статьи по ссылке:
Будем интерпретировать сигнал u(t) следующим образом: если u(t)<0, то будем притормаживать левый двигатель на величину, пропорциональную модулю u(t); если u(t)>0, то будем притормаживать правый двигатель на величину, пропорциональную u(t). Естественно, что если u(t)=0, то тележка едет прямо (никакие двигатели не притормаживаются).
Ну вот это я и делаю.
на величину, пропорциональную модулю u(t);
подумай еще
подумай еще
Блин, ну модуль это абсолютная величина. У минус 6 и у плюс 6 модуль будет шесть.
Пропорциональность я реализую через МАР.
U это управляющее воздействие.
Вот схема подключения мотора.
IN1, IN2 определяют направление движения, на пин ENA подаем ШИМ и он может быть только положительный
Другого не думается. Подскажите.
Нифига как сложно оказывается из ардуино и мотора сделать серву !
Пид какой то больше 0, меньше, а при 0 чего делать?
Не увидел вывода шим, извиняюсь. Разрешение по углу слишком маленькое. Работай в диапазоне 0-1023, а не 0-180.
Работай в диапазоне 0-1023, а не 0-180.
Вот здесь вообще не понял. От 0 до 180 изменяются градусы. У сервы ход 180 градусов.
Вот здесь вообще не понял. От 0 до 180 изменяются градусы. У сервы ход 180 градусов.
для контроллера нет никаких градусов, он берет сигнал с аналогового входа, с диапазоном 0-1023. А преобразуете этот диапазон к "градусам" 0-180 - вы сами в коде программы, таким образом теряя в точности в 6 раз
Вот эту строчку надо выкинуть
и работать напрямую со значениями analogRead(PIN_POT)
и работать напрямую со значениями analogRead(PIN_POT)
Работает два МК. Один основной (управляет сервами), второй в роли контролера сервомотора.
Основной подает ШИМ сигнал в формате 0-255 как на настоящую серву. Второй, тот что контролер сервы, соответственно принимает 0-255. Вот заготовка по это. Временно задаю в ручную (ноль градусов).
Энкодер выдает 0-1023. Мне надо сравнивать эти значения. Все равно преобразование где то придется делать.
А потом еще на мотор передавать 0-255 (100-255).
Если я уберу строку
мне придется эту строку
переделать в такую
а я не могу так сделать потому, что с основного МК получаю значение в виде 0-255.
Все равно преобразование где то придется делать.
да. в любом случае что-то придется преобразовывать, весь вопрос - что выбрать.
Чем больше размерность данных на ПИД регуляторе - тем более "гладко" он работает. Поэтому 0-1023 лучше. чем 0-180.
Спасибо, попробую.
Нифига как сложно оказывается из ардуино и мотора сделать серву !
Пид какой то больше 0, меньше, а при 0 чего делать?
не просто же так за цифровые сервы такие деньги просят )))
Вычисления в ПИ-регуляторе в диапазоне 0 - 1023.
Перевожу в градусы только в монитор порта.
При значениях Кп = 0,1; 1; 2; 5; 10 выходной вал колеблется возле заданной точки в диапазоне 3-4 градуса.
Причем серва часто попадает в заданное положение (на скрине видно), но не останавливается в нем. Более того, я её руками поворачиваю в заданный угол, как только отпускаю вал поворачивает и начинаются колебания.
Толи лыжи не едут, толи одно из двух.
Люди добрые, ПАМАЖИТЕ!!!
Можно для начала попробовать без ПИДа. Брал мотор-редуктор, прикручивал переменный резистор, драйвер L9110S и гонял по условиям <= или >= заданного. В принципе понравилось, но 65 Р за готовую серву проще оказалось в итоге.
Можно для начала попробовать без ПИДа.
Я в первом посте описывал без ПИДа. Только управление идет не с переменного резистора а с внешнего контролера, т.к. серва в составе проекта который управляется МК (тот самый внешний МК).
Серва не останавливается в заданном положении.
Серва не останавливается в заданном положении.
Так сначала надо выяснить, почему так происходит, где у вас в коде ошибка, прежде чем ПИД прикручивать
Вы, надеюсь, понимаете, что если даже при прямом регулировании серва не останавливается - значит ошибка есть?
Переменный резистор, жестко связанный с выходным валом сервы даёт контроллеру чёткое положение вала - "идеальная обратная связь". Иными словами как с энкодером мк узнаёт где находится сейчас вал на самом деле? Конечно ресурс такой связи ограничен, но мне кажется она легче в понимании.
Существуют абсолютные энкодеры, например...
Блин, точно. Читал уже, но забыл.Вот что значит ни разу не использовать )
Толи лыжи не едут, толи одно из двух.
Люди добрые, ПАМАЖИТЕ!!!
Да сказано сразу было, что без теории это дохлый номер. Одна статейка это не теория. Дальше нужно смотреть на помехи и увеличение пропускной полосы всей системы.
Может добавить else
Может добавить else
Да оно собственно так и было.
В коде из последнего сообщения сообщения, вынесли случай равенства и делали паузу. Пауза срабатывает отлично. Когда отправлял код на форум паузу убрал, а else назад не перенес.
Я увеличил скорость и разрядность ШИМ до 15.6 кГц, 10bit, в положении 0 серва стала останавливаться, в положении 180 продолжаются колебания.
Кстати микросхема в серве KC9102, инфы про неё в инете не нашел, только маленький даташит на китайском языке.
Забил, может позже еще подумаю.