Урок 1.6. Управление сервоприводом
Базовый курс "Программирование микроконтроллеров"
Модуль 1. Введение в Arduino. Работа с цифровым и аналоговым сигналом
Сервопривод
Наряду с контроллером и сенсорами, активаторы являются важным составляющим всех без исключения роботов. Они вращают колеса робота, позволяя ему перемещаться в пространстве, и приводят в действие мощные манипуляторы, которыми он хватает предметы.
В этом уроке мы будем работать с одним из таких активаторов, который называется сервоприводом (или сервомашинкой). В отличие от обычного электромотора, сервопривод представляет собой сложное составное устройство, состоящее из двигателя постоянного тока, шестеренного редуктора, потенциометра и электронной схемы. Всё это позволяет сервоприводу поворачивать вал строго на заданный угол, и удерживать его.
Внутренне сервопривод устроен следующим образом:
– Микромотор обладает большой скоростью вращения, но низким крутящим моментом;
– Редуктор понижает скорость вращения мотора и увеличивает его крутящий момент;
– Выходной вал соединен с потенциометром и через редуктор с мотором;
– Потенциометр соединённый с выходным валом фиксирует угол поворота сервопривода. Так как потенциометр имеет ограниченный угол поворота, то и сервопривод ограничен углом поворота потенциометра;
– Плата-контроллер считывает показания потенциометра – таким образом она понимает угол поворота сервопривода.
Управление сервоприводом с потенциометра
Соберем небольшой проект по управлению сервоприводом с помощью потенциометра.
По сути, мы соберем проект электроусилителя, управлять углом поворота большой нагрузки мы будем с помощью потенциометра, управление которого требует небольших усилий пальцев. Примерами таких устройств могут служить электроусилитель руля, тяжелые клапаны управления потоком чего либо на заводах и прочее.
Соберем следующую схему:
Начнём с того, что научимся управлять сервоприводом, для этого подключим специальный программный блок называемый библиотекой.
Библиотека — это набор модулей или функционала. Дело в том, что для управления и работы с некоторыми устройствами и модулями может быть довольно сложным и требовать в процессе разработки написать не один десяток строк кода. Библиотека упрощает разработку тем, что она содержит упакованный в простые функции сложный код, которым мы можем пользоваться.
Для того, что бы подключить библиотеку, мы должны прокликать следующие пункты меню Arduino IDE:
Скетч -> Подключить библиотеку -> Servo
Напишем код:
// Подключение библиотеки для работы с сервоприводом
#include <Servo.h>
// Создание объекта сервопривода
Servo servo;
#define servo_pin 3
void setup()
{
Serial.begin(9600);
// привязка сервопривода с именем servo к пину 3
servo.attach(servo_pin);
}
void loop() {
// команда сервоприводу занять положение 0 градусов
servo.write(0);
delay(1000);
// команда сервоприводу занять положение 90 градусов
servo.write(90);
delay(1000);
// команда сервоприводу занять положение 180 градусов
servo.write(180);
delay(1000);
}
Загрузим программу и понаблюдаем за работой сервопривода.
Обратите внимание: во время работы сервопривода крайне не рекомендуется пытаться удержать его руками или другой нагрузкой - от больших нагрузок может выйти из строя мотор или редуктор сервопривода!
Теперь добавим в нашу программу управление сервоприводом ручкой потенциометра:
// Подключение библиотеки для работы с сервоприводом
#include <Servo.h>
// Создание объекта сервопривода
Servo servo;
#define servo_pin 3
#define pot A0
// переменная для записи угла поворота
int angle = 0;
void setup()
{
Serial.begin(9600);
// привязка сервопривода с именем servo к пину 3
servo.attach(servo_pin);
pinMode(pot,INPUT);
}
void loop() {
int val = analogRead(pot);
// масштабируем показания потенциометра в угол поворота сервопривода
angle = map(val,0,1023,0,180);
// команда сервоприводу занять положение angle градусов
servo.write(angle);
delay(10);
}
Загрузим программу и понаблюдаем как будет меняться положение вала сервопривода при вращении ручки потенциометра!
Управление сервоприводом с помощью кнопок
Теперь возьмём задачку посложнее, соберем кнопочный пульт управления сервоприводом.
Напишем и загрузим код для проверки всех компонентов:
// Подключение библиотеки для работы с сервоприводом
#include <Servo.h>
// Создание объекта сервопривода
Servo servo;
#define servo_pin 3
#define btnUp 4
#define btnDown 5
// переменная для записи угла поворота
int angle = 0;
// переменная для записи состояний кнопок
byte stateUp = 0;
byte stateUpLast = 0;
byte stateDown = 0;
byte stateDownLast = 0;
void setup()
{
Serial.begin(9600);
// привязка сервопривода с именем servo к пину 3
servo.attach(servo_pin);
pinMode(btnUp,INPUT);
pinMode(btnDown,INPUT);
}
void loop() {
// считываем состояние кнопок
stateUp = digitalRead(btnUp);
stateDown= digitalRead(btnDown);
// выводим состояния кнопок в монитор порта
Serial.println("BTN UP = " + String(stateUp) + " BTN DOWN = " + String(stateDown));
// проверяем работу сервопривода
servo.write(0);
delay(500);
servo.write(180);
delay(500);
}
Откроем монитор порта и прокликаем кнопки – мы должны увидеть, что в мониторе порта состояние кнопок изменяется корректно и сервопривод вращается.
Далее добавим отслеживание нажатий кнопок, и в зависимости от того, какая кнопка нажата – туда будет вращаться сервопривод.
// Подключение библиотеки для работы с сервоприводом
#include <Servo.h>
// Создание объекта сервопривода
Servo servo;
#define servo_pin 3
#define btnUp 4
#define btnDown 5
// переменная для записи угла поворота
int angle = 90;
// переменная для записи состояний кнопок
byte stateUp = 0;
byte stateUpLast = 0;
byte stateDown = 0;
byte stateDownLast = 0;
void setup() {
Serial.begin(9600);
// привязка сервопривода с именем servo к пину 3
servo.attach(servo_pin);
pinMode(btnUp, INPUT);
pinMode(btnDown, INPUT);
}
void loop() {
// считываем состояние кнопок
stateUp = digitalRead(btnUp);
stateDown = digitalRead(btnDown);
if (stateUp) {
angle++;
}
if (stateDown) {
angle--;
}
// обрезаем значения угла поворота не входящих в диапазон от 0 до 180
angle = constrain(angle, 0, 180);
// поворачиваем вал сервопривода
servo.write(angle);
Serial.println("Angle = " + String(angle));
}
Как Вы можете заметить, в данном коде мы использовали новую функцию – constrain.
Синтаксис
result = constrain(x, a, b);
Параметры
x: переменная, значение которой необходимо ограничить, любой тип данных
a: нижний предел, любой тип данных
b: верхний предел, любой тип данных
Возвращаемые значения
x: если x лежит в пределах между a и b
a: если x меньше a
b: если x больше b
Строчка:
angle = constrain(angle, 0, 180);
эквивалента записи:
if (angle > 180)
angle = 180;
else if (angle < 0)
angle = 0;
Изменим наш код так, что бы сервопривод поворачивался на 10 градусов при каждом клике по кнопке:
// Подключение библиотеки для работы с сервоприводом
#include <Servo.h>
// Создание объекта сервопривода
Servo servo;
#define servo_pin 3
#define btnUp 4
#define btnDown 5
// переменная для записи угла поворота
int angle = 90;
// переменная для записи состояний кнопок
byte stateUp = 0;
byte stateUpLast = 0;
byte stateDown = 0;
byte stateDownLast = 0;
void setup() {
Serial.begin(9600);
// привязка сервопривода с именем servo к пину 3
servo.attach(servo_pin);
pinMode(btnUp, INPUT);
pinMode(btnDown, INPUT);
}
void loop() {
// считываем состояние кнопок
stateUp = digitalRead(btnUp);
stateDown = digitalRead(btnDown);
if (stateUp && !stateUpLast) {
angle = angle + 10;
}
if (stateDown && !stateDownLast) {
angle = angle - 10;
}
// обрезаем значения угла поворта не вхлжящих в жиапозон от 0 до 180
angle = constrain(angle, 0, 180);
// поворачиваем вал сервопривода
servo.write(angle);
Serial.println("Angle = " + String(angle));
stateUpLast = stateUp;
stateDownLast = stateDown;
}
Отлично, Вы выполнили все задачи!