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

Серия-статей: Arduino, использование двигателей постоянного тока #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)); // Подаем на выход управления скоростью сигнал, который соответствует нужной скорости

}

void SetSpeed(int newspeed) // Устанавливаем скорость двигателя в процентах от максимума.

{

Power=(int)newspeed/2.55; // Поскольку скорость меняется от 0 дл 100 %, а мощность - в диапазоне от 0 до 255,

// вычисляем необходимое значение мощности

RunMotor(Power);

}

void 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()

}

void 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)