Створення класу для роботи з двигуном постійного струму

Серія-статей: Ардуїно, використання двигунів постійного струму #3

Один контролер може керувати кількома двигунами постійного струму. Оскільки код управління буде той самий, тобто виділити для нього окремий клас. Тоді при додаванні нового двигуна достатньо буде додати всього кількох рядків, а не копіювати однакові функції та пріменні для кожного.

Зберемо схему з двох двигунів:

Підключення двох двигунів постійного струму до Arduino через драйвер L298P

Створимо клас MotorClass і додамо до нього пермінні для поточного стану двигуна (швидкість та напрямок обертання). Крім того, створимо змінні, які будуть використовуватися при плавній зміні швидкості.

У нашого класу буде кілька методів:

MotorClass(pE, pI) – конструктор класу, тут ми будемо вказувати, якими виходами керуватимемо двигуном

RunMotor(motorpower) - змінюємо внутрішні змінні (потужність, напрямок) і безпосередньо керуємо двигуном.

SetSpeed(newspeed) – встановлюємо нову швидкість. Потужність змінюється в діапазоні 0.255, що не завжди зручно. Тому задаватимемо швидкість у % від максимуму

SetSpeed(newspeed, smooth) – встановлюємо нову швидкість, робимо це не стразу, а плавно – встановлюємо відповідні змінні, а безпосередньо швидкість змінюватиметься функцією UpdateSpeed()

UpdateSpeed() – тут перевірятиметься тимчасовий інтервал та змінюватиметься швидкість, якщо попереднім методом були встановлені відповідні змінні. Поміщаємо цю функцію в loop()

Ось що в нас вийшло:

/* Користувальницький клас управління двигунами постійного струму з підтримкою плавної зміни швидкості */

class MotorClass

{

public:

byte pinE; // Номер цифрового виходу для управління швидкістю – повинен підтримувати ШІМ

byte pinI; // Номер цифрового виходу керувати напрямом обертання

boolean SpeedChanging; // Чи увімкнено режим прискорення двигуна (обробляється функцією UpdateSpeed())

unsigned long StartTimer; // Таймер для плавного запуску

int StartTimeStep; // Інтервал зміни потужності двигуна, мс

int StartPowerStep; // Один крок зміни потужності двигуна

int ReqPower // До якого закінчення змінюватиметься потужність двигуна

int Power; // Потужність двигуна (0 - зупинка, 255 - повна потужність)

int Direction; // Напрямок обертання

MotorClass(int pE, int pI) // Конструктор класу. Перший аргумент – номер піна управління швидкістю, другий – напрямком

{

pinE = pE; // Задаємо керуючі піни для швидкості

pinI = pI; // І напрямки обертання

pinMode (pinE, OUTPUT); // Задаємо роботу відповідних пінів як виходи

pinMode (pinI, OUTPUT);

Power = 0; // за умовчанням двигун стоїть

SpeedChanging=false; // За умовчанням двигун не пришвидшується

}

void RunMotor(int motorpower) // Задаємо швидкість і напрямки обертання двигуна

// Негативне значення - обертання у зворотний бік

{

Direction=(motorpower>0)?HIGH:LOW; // Якщо вказано позитивну швидкість - на вихід напрямку подається сигнал HIGH

digitalWrite(pinI,Direction); // для негативної – LOW

digitalWrite(pinE,abs(Power)); // Подаємо на вихід керування швидкістю сигнал, який відповідає потрібній швидкості

}

setSpeed (int newspeed) // Встановлюємо швидкість двигуна у відсотках від максимуму.

{

Power=(int)newspeed/2.55; // Оскільки швидкість змінюється від 0 дл 100%, а потужність - в діапазоні від 0 до 255,

// обчислюємо необхідне значення потужності

RunMotor(Power);

}

setSpeed (int newspeed, int smooth) // Плавно змінюємо швидкість двигуна у відсотках від максимуму.

// Негативне значення - обертання у зворотний бік

// Плавність зміни регулюється значенням smooth (час на один крок зміни швидкості, мс)

{

ReqPower=(int)newspeed/2.55; // Оскільки швидкість змінюється від 0 дл 100%, а потужність – у діапазоні від 0 до 255, обчислюємо потрібне значення

if (ReqPower>=Power) // У який бік змінюватиметься потужність?

StartPowerStep=1; // збільшуватись на 1 (1/255 від повної)

else

StartPowerStep=-1; // зменшуватись на 1 (1/255 від повної)

StartTimeStep=smooth;

StartTimer=millis(); // Починаємо відлік часу зміни швидкості

SpeedChanging=true; // встановлюємо режим зміни швидкості, для подальшої обробки функції UpdateSpeed()

}

UpdateSpeed()

{

if (SpeedChanging) // Якщо встановлено режим зміни швидкості

if ((millis()-StartTimer)>= StartTimeStep) // Якщо з попередньої зміни швидкості пройшло більше часу, ніж задано

{

if (Power! = ReqPower) // Поки не досягли потрібної швидкості

{

Power+=StartPowerStep; // міняємо швидкість

RunMotor(Power); // даємо команду двигуну

StartTimer=millis(); // встановлюємо таймер для початку відліку для наступного зміни потужності

}

else // Якщо потрібна швидкість досягнута

SpeedChanging=false; // Вимикаємо режим зміни швидкості

}

}

};

MotorClass M1(5,4); // Перший двигун управляється виходами 5 і 4 (швидкість та напрямок відповідно)

MotorClass M2(6,7);// Другий двигун управляється виходами 6 та 7

void setup()

{

M1.SetSpeed(50); //Перший двигун - увімкнути на 50% швидкості

M1.SetSpeed(-100, 2); // Другий двигун - включити на 100% швидкості у зворотний бік з плавним розгоном

}

void loop()

{

M1.UpdateSpeed(); // Обробити зміни швидкості першого двигуна

M2.UpdateSpeed(); // Обробити зміни швидкості другого двигуна

}

При запуску програми перший двигун максимально швидко розженеться до половини максимальної швидкості. А ось другий буде обертатися у зворотний бік, причому на розгін з нуля до максимуму у нього піде пів секунди (255 кроків зміни через 2мс). Управління двигунами незалежне, причому додавання ще кількох двигунів не викличе труднощів. На нашому motor-shield немає більше висновків для підключення моторів, але нам ніщо не заважає використовувати два однакових (єдине обмеження - ззовні контролера можна встановити тільки один, другий потрібно буде підключати проводами до відповідних виходів. Але для таких випадків існують чотириканальні motor-shield, в яких використовуються дві та більше мікромхеми L298P: Мотор шилд на базі двох L298P сумісний з Arduino UNO

Така плата може керувати чотирма двигунами постійного струму, тобто можна, наприклад, зробити повністю незалежне управління кожного колеса чотириколісного робота. Єдиний недолік-у такому варіанті використовуються практично всі цифрові виходи звичайної плати UNO. Але ця проблема вирішується або використанням більш функціональної плати (наприклад Arduino MEGA з 54 цифровими виходами) або підключенням motor-shielda через L2P.

Еще:

Подключаем двигатель постоянного тока. Микросхема L298P (Arduino, использование двигателей постоянного тока #1)
Плавный пуск двигателя постоянного тока с использованием таймеров (Arduino, использование двигателей постоянного тока #2)
Создание класса для работы с двигателем постоянного тока (Arduino, использование двигателей постоянного тока #3)
Создание собственной библиотеки управления двигателем постоянного тока (Arduino, использование двигателей постоянного тока #4)