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

Серия-статей: Програмування Ардуіно з нуля #6

Серия-статей: Ардуіно, використання сервоприводів #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); // Даємо команду змінити положення

}

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)