Сервопривод - механический привод с автоматической коррекцией состояния через
внутреннюю отрицательную обратную связь, в соответствии с параметрами,
заданными извне, в данном случае в соответствии с импульсами поступающими с платы
Arduino. Эти импульсы говорят сервоприводу, что необходимо двигаться.
Сервопривод имеет три провода, два из них это питание и земля, а по третьему
передается управляющий сигнал, который используется для выставления положения
устройства. Вы можете вращать механический привод на заданный угол с заданной
скоростью или усилием. Наиболее популярны сервоприводы, которые удерживают
заданный угол и сервоприводы, поддерживающие заданную скорость вращения.
Конструкция сервопривода:
Включая и выключая электромотор, можно вращать выходной вал - конечную шестерню
сервопривода, к которой можно прикрепить нечто, чем мы хотим управлять - рычаг
в форме круга, крестовины или перекладинки для передачи вращающего движения на
рабочий орган. Для контроля положения используется датчик обратной связи -
энкодер, который будет преобразовывать угол поворота обратно в электрический
сигнал. Для этого часто используется потенциометр. При повороте бегунка
потенциометра происходит изменение его сопротивления, пропорциональное углу
поворота. Проще говоря, двигатель будет вращаться, поворачивая вал сервопривода,
пока сопротивление потенциометра не достигнет нужного значение, как только это
произойдет - двигатель остановится.
Управляется сервопривод повторяющимися импульсами определенной длительности.
Ниже представлена картинка с управляющими импульсами для сервопривода SG90:
От ширины импульса зависит на какой угол повернется выходной вал сервопривода.
Ширина импульса для данного сервопривода может быть от 500 до 2500 микросекунд,
которые подаются на сервопривод с частотой 50 Гц (период поступления импульсов
20 миллисекунд). Изменяя ширину импульса мы можем точно задавать угол поворота
выводного вала.
Для демонстрации работы сервопривода, соберем простую схему в Tinkercad:
Сначала поуправляем двигателм напрямую, формируя импульсы почти также как это сделано в программе Blink:
int val=45; // угол поворота void setup() { pinMode(9, OUTPUT); // сигнальный провод от серво на пин 9 } void loop() { int pulse = (val * 11) + 500; // переменная pulse задает ширину управляющего импульса digitalWrite(9, HIGH); // устанавливаем высокий уровень на выводе 9 (начало импульса) delayMicroseconds(pulse); // ширина управляющего импульса digitalWrite(9, LOW); // устанавливаем низкий уровень на выводе 9 (конец импульса) delayMicroseconds(20000-pulse); // пауза до начала нового импульса. }
Переменной val будем задавать желаемый угол, на который нужно повернуть вал
сервопривода. В программе он установлен 45 градусов. Попробуйте поизменять
значение этой переменной от 0 до 180, и посмотреть как будет реагировать на эти
изменения сервопривод.
Конечно, каждый раз, когда нам необходимо повернуть вал сервопривода писать
такой код не очень удобно, лучше формирователь импульсов выделить в отдельную
подпрограмму:
int val; void setup() { pinMode(9, OUTPUT); // сигнальный провод от серво на пин 9 } void loop() { servo (30); servo (60); servo (90); servo (60); servo (30); servo (0); } void servo(int n) // подпрограмма servo() { for (int i=0; i <= 255; i++) { int pulse = (n * 11) + 500; // переменная pulse задает ширину управляющего импульса digitalWrite(9, HIGH); // устанавливаем высокий уровень на выводе 9 (начало импульса) delayMicroseconds(pulse); // ширина управляющего импульса digitalWrite(9, LOW); // устанавливаем низкий уровень на выводе 9 (конец импульса) delayMicroseconds(20000-pulse); // пауза до начала нового имульса. } }
Здесь формирователь имульсов оформлен в отдельную подпрограмму servo(), и теперь,
чтобы повернуть вал двигателя на определенный угол, необходимо вызвать
подпрограмму указав в её параметрах угол на который следует повернуть вал.
Например в приведенном выше примере сначала вал повернется на 30 градусов,
затем на 60 градусов, затем на 90 и далее в обратном порядке до нуля градусов,
после чего цикл повориться.
Можно еще упростить задачу, используя стандартную библиотеку Servo.h.
Перепишем эту программу, но с использованием библиотеки:
#includeУправление осуществляется следующими функциями:// подключаем библиотеку для работы с сервоприводом Servo servo1; // объявляем переменную servo типа "servo1" void setup() { servo1.attach(9); // привязываем сервопривод к аналоговому выходу 11 } void loop() { servo1.write(30); // ставим угол поворота под 30 delay(1000); // ждем 1 секунду servo1.write(60); // ставим угол поворота под 60 delay(1000); // ждем 1 секунду servo1.write(90); // ставим угол поворота под 90 delay(1000); // ждем 1 секунду servo1.write(60); // ставим угол поворота под 60 delay(1000); // ждем 1 секунду servo1.write(30); // ставим угол поворота под 30 delay(1000); // ждем 1 секунду servo1.write(0); // ставим угол поворота под 0 delay(1000); // ждем 1 секунду }