Подключение и управление сервоприводом на Ардуино
Сервоприводы один из важных исполнительных механизмов умных устройств. Разберемся в некоторых приемах управления ими на базе платформы Ардуино. В статье показаны три типовых подхода: управление по заданной программе, по сигналу внешнего датчика и удаленное управление по цифровому интерфейсу. Показан подход для контроля фактического угла поворота.
Что такое сервопривод?
Вначале определимся, что представляет из себя сервопривод. Это умный двигатель, который может поворачивать свой ротор на заданный угол. Есть правда сервоприводы, вращающиеся непрерывно в разные стороны, с регулируемой скоростью, но сейчас речь не о них.
Т.е. сервопривод — довольно сложная система. Управляется она по одному проводу ШИМ сигналом. Импульсы подаются через 20 мс, длительностью от 1 до 2 мс, соответствующие крайним положениям угла (от 0* до 180*, соответственно). Для Ардуино существует встроенная с среду библиотека Servo.h.
Управление сервоприводом по заданной программе
Когда последовательность действий заранее известна, можно записать её в массив и затем поочередно передавать сервоприводу.
Соберем схему:
Для программного управления можно использовать следующую программу:
// Программное управление сервоприводом // (с) Роман Исаков, 2020 // (с) LabData.ru #include <Servo.h> #define servo_pin 8 // Разъем для подключения сервы #define servo_speed 500 // Скорость обработки команд uint32_t servo_T = 0; // Служебная переменная int pos = 0; // Номер текущей команды int prog[] = {180, 100, 80, 90, 85, 90, 85, 90, 70, 60, 50, 40, 20, 10}; // Команды серве Servo servo1; // Объект сервы void setup() { servo1.attach(servo_pin); // Подключение сервы servo_T = millis(); } void loop() { int N = sizeof(prog)/sizeof(int); // число элементов массива prog if (millis() - servo_T >= servo_speed) { // Программное прерывание по таймеру servo_T = millis(); servo1.write(prog[pos]); // Отправка команды серве pos++; // Выбор следующей команды if (pos>=N) pos = 0; // Если дошли до конца – повторить сначала } }
Команды можно легко убирать и добавлять, программа сама рассчитает их число.
Управление несколькими сервоприводами сигналом с датчика
Если сигнал управления зависит от каких-то внешних факторов, то нужно подключать к Ардуино соответствующий датчик. В данном примере — аналоговый датчик угла (потенциометр). Управлять будем независимо двумя сервоприводами. Задача — следить за напряжением на датчике и закрывать один сервопривод в одну строну, а другой — в другую. Как-бы имитируя ворота.
Схема подключения выглядит так:
Алгоритм реализован в программе Ардуино:
// Управление сервоприводами с датчика // (с) Роман Исаков, 2020 // (с) LabData.ru #include <Servo.h> #define servo_speed 200 // Установка скорости работы #define servo1_pin 8 // Выход 1 сервы #define servo2_pin 9 // Выход 2 сервы uint32_t servo_T = 0; #define DAT_pin A0 // Вход потенциометра Servo servo1; Servo servo2; void setup() { servo1.attach(servo1_pin); servo2.attach(servo2_pin); servo_T = millis(); } void loop() { if (millis() - servo_T >= servo_speed) { servo_T = millis(); int DAT = analogRead(DAT_pin); // Получение аналогового сигнала с потенциометра servo1.write(map(DAT, 0, 1024, 90, 180)); // Преобразование уровня напряжения от 0..1024 в угол от 90 до 180* и отправка на 1 серву servo2.write(map(DAT, 0, 1024, 90, 0)); // Преобразование уровня напряжения от 0..1024 в угол от 90 до 0* и отправка на 2 серву } }
Поворачивая ручку потенциометра сервоприводы приведутся в движение и станут следить за углом поворота.
Удаленное управление сервоприводом по последовательному порту Ардуино
Иногда нужно удаленно управлять исполнителем, подавая команды по последовательному порту UART Ардуино. Управлять можно с ПК и мобильных телефонов, а также с других устройств по USB, UART или Bluetooth.
Схема не отличается от первой:
Программа принимает по последовательному порту строку с числом равным углу требуемого отклонения сервопривода, а затем постепенно переводит рычаг на нужный угол. Затем опять ждет команд.
Благодаря этому, есть возможность определить угол поворота сервопривода.
#include <Servo.h> #define servo_pin 8 #define servo_speed 10 // Задержка перемещения рычага сервы uint32_t servo_T = 0; byte pos=90, newpos=90; // текущая и требуемая позиция сервы Servo servo1; void setup() { servo1.attach(servo_pin); servo_T = millis(); Serial.begin(9600); // Запуск последовательного порта servo1.write(pos); // Установка сервы на угол 90* delay(1000); // Ждем пока серва перейдет на нужный угол (не гарантировано!) Serial.println("Ready to command!"); // Подача сообщения о готовности в порт } void loop() { if ( Serial.available()) { // Если принята команда newpos = Serial.parseInt(); // Принять полученную строку и перевести её в целое число newpos = constrain(newpos, 0, 180); // Ограничить число 0…180 } if ((newpos != pos)&&(millis() - servo_T >= servo_speed)) { // Прерывание для обработки перемещения сервы, если позиция отличается servo_T = millis(); if (newpos > pos){ // Если новая позиция больше текущей pos++; // Повысить текущую на 1 } else { // …иначе pos--; // Понизить на 1 } pos = constrain(pos, 0, 180); // Ограничить число 0…180 servo1.write(pos); // Перемесить серву на полученный угол Serial.print("Status: "); // Показать текущий угол оператору через порт Serial.println(pos); if (pos == newpos) Serial.println("Completed!"); // Если угол достиг цели – уведомить оператора } }
Управление может осуществляться через монитор последовательного порта Ардуино, терминал порта или терминал Bluetooth на мобильном устройстве, если подключить Bluetooth модуль к Ардуино.
(с) Роман Исаков, 2020