Создаем класс для управления сервоприводом

Серия-статей: Программирование 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 градусов. Сам функционал программы уместился в три строчки, а вот описание класса заняло большую часть программы. Поэтому для управления одним сервоприводом использовать классы не эффективно. Но попробуем добавить еще парочку сервоприводов: Схема подключения трех сервоприводов к Arduino для управления с помощью пользовательского класса

Наш класс не изменился, а в основном теле программы добаится совсем немного кода:

#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(); // Движение третьего сервопривода

}

Теперь выгода от использования класса видна невооруженным глазом. Несмотря на увеличение количества используемых сервоприводов, размер программы практически не изменился, к тому же мы были избавлены от монотонной работы по копированию одинакового кода для каждого сервопривода с изменнием названий переменных.

Еще:

Программирование контроллеров – с чего начать (Программирование Arduino с нуля #1)
Подключение периферии, платы расширения (Программирование Arduino с нуля #2)
Организация питания для Arduino (Программирование Arduino с нуля #3)
Программное ограничение перемещения сервопривода (Arduino, использование сервоприводов #4)
Подключение шагового двигателя. Контроллер L298 (Программирование Arduino с нуля #8)
Подключаем сервопривод к Arduino (Программирование Arduino с нуля #4)
Создаем класс для управления сервоприводом (Программирование Arduino с нуля #6)