Создаем класс для управления сервоприводом
Серия статей: Программирование Arduino с нуля #6
Серия статей: Arduino, использование сервоприводов #3
Подключение одного-двух сервоприводов не вызывает особого труда. Но может возникнуть необходимость использовать намного больше. Например у паукообразных роботов каждый сустав всех ног приводится в движение отдельным сервоприводом. Или, например, мы хоти использовать манипулятор – тогда на каждую степень свободы нам потребуется по сервоприводу. Как мы убедились ранее, в случае нескольких сервоприводов их управление однотипно. Но каждый раз, когда в проект добавляется новый севопривод, нам придется копировать один и тот-же код, только с другими переменными.
Есть смысл создать собственный класс для сервопривода, в котором один раз прописать все необходимые переменные и фунции. Тогда нам нужно будет только один раз инициализиовать этот класс для каждого из сервоприводов и не копировать все переменные.
Пример такого простейшего класса, который просто плавно поворачивает сервопривод на 180 градусов:
#include
// Подключаем библиотеку для работы с сервоприводом class ServoClass
{
Servo serv; // Собственно сам сервопривод, управляемый стандартной
// библиотекой servo
int servPosition; // Текущая позиция сервопривода
int interval;
unsigned long lastTimeCheck; // Время последнего движения сервопривода, в мс от начала работы программы
public:
ServoClass ()
{
interval=10;
servPosition=0;
lastTimeCheck=millis();
}
void AttachServo (int pin)
{
serv.attach(pin); // Подключаем сервопривод к указанному пину
servPosition= 0; // Позиция сервопривода должна сответствовать исходному положению – 0 градусов
serv.write(servPosition); // Даем команду изменить положение
}
void Update ()
{
if (servPosition<180)
{
if ((millis() - lastTimeCheck)>= interval) // проверяем, сколько прошло времени с последнего
//действия и сравниваем с нужным нам интервалом.
//Если времени прошло больше – совершаем следующее действие
{
servPosition++; // Изменяем угол на один градус
serv.write(servPosition); // Посылаем сервоприводу команду с новым углом поворота
lastTimeCheck= millis(); // Обновляем счетчик времени, для того чтобы следующий отсчет времени начался с этого момента
}
}
}
};
Теперь у нас есть класс, который описывает элементарный сервопривод. Переменные у нас те-же, что и в предыдущем примере. А вот функции несколько отличаются:
ServoClass ()
– Первой функцией мы определяем конструктор класса, имя которого совпадатет с именем класса. Именно он будет вызываться тогда, когда мы будем первый раз определять любую переменную типа
ServoClass. Здесь же устанавливаем переменные по умолчанию. Например, устанавливаем позицию в 0 градусов;
void AttachServo (int pin)
– Здесь мы указываем контроллеру, к какому выходу подключен сервопривод и инициализируем его. Если конструктор класса вызывается при определении переменной типа ServoClass
, то инициализацию мы должны произвести при старте программы, т.е. внутри функции setup();
void Update ()
– В этой функции прописываются действия, которые нужно выполнять постянно – в данном случае движение сервопривода по таймеру. Эту функцию мы добавляем в функцию loop()
Теперь напишем простейшую программу, которая будет использовать наш класс. Добавим к написанному ранее коду стандартные функции setup()
и loop()
#include
// Подключаем библиотеку для работы с сервоприводом class ServoClass
{
// Здесь код нашего класса, приведенный выше
};
ServoClass serv1; // Определяем переменную типа ServoClass (вызываем
// конструктор ServoClass() )
void setup()
{
serv1.AttachServo(2); // Инициализируем сервопривод, соединенный
// со 2 цифровым выходом
}
void loop()
{
serv1.Update(); // В бесконечном цикле опрашиваем, не нужно ли поменять
// положение сервопривода и организовываем его движение
}
При запуске мы добились того-же результата, что и в предыдущем примере – плавного движения сервопривода с 0 до 180 градусов. Сам функционал программы уместился в три строчки, а вот описание класса заняло большую часть программы. Поэтому для управления одним сервоприводом использовать классы не эффективно. Но попробуем добавить еще парочку сервоприводов:
Наш класс не изменился, а в основном теле программы добаится совсем немного кода:
#include
// Подключаем библиотеку для работы с сервоприводом class ServoClass
{
// Здесь код нашего класса, приведенный выше
};
ServoClass serv1; // Определяем переменные типа ServoClass для каждого
ServoClass serv2; //сервопривода (вызываем конструктор ServoClass() )
ServoClass serv3;
void setup()
{
serv1.AttachServo(2); // Инициализируем сервопривод, соединенный
// со 2 цифровым выходом
serv2.AttachServo(3); // Второй сервопривод подключен к 3 выходу
serv3.AttachServo(4); // Третий сервопривод подключен к 4 выходу
}
void loop()
{
serv1.Update(); // Движение первого сервопривода
serv2.Update(); // Движение второго сервопривода
serv3.Update(); // Движение третьего сервопривода
}
Теперь выгода от использования класса видна невооруженным глазом. Несмотря на увеличение количества используемых сервоприводов, размер программы практически не изменился, к тому же мы были избавлены от монотонной работы по копированию одинакового кода для каждого сервопривода с изменнием названий переменных.