Изучаем Arduino: инструметы и методы технического волшебства - [22]

Шрифт
Интервал

Анализируя рис. 4.5, делаем следующие выводы:

1. Для вращения двигателя один из выключателей должен быть замкнут, другой разомкнут.

2. Чтобы двигатель вращался в обратном направлении, замкнутый в n. 1 выключатель должен быть разомкнут, а разомкнутый - замкнут.

3. Для остановки двигателя оба выключателя должны быть разомкнуты.

ПРИМЕЧАНИЕ

Перед изменением состояния выключателей всегда отключайте ток, чтобы не вызвать короткого замыкания Н-моста.

Сначала напишем код функций для выполнения описанных действий (листинг 4.3).


Листинг 4.3. Вспомогательные функции для управления двигателем

// Вращение двигателя вперед с заданной скоростью (диапазон 0-255)

void forward (int rate)

{

digitalWrite(EN, LOW);

- 95 -

digitalWrite(MC1, HIGH);

digitalWrite(MC2, LOW);

analogWrite(EN, rate);

}

// Вращение двигателя в обратном направлении с заданной скоростью

//(диапазон 0-255)

void reverse (int rate)

{

digitalWrite(EN, LOW);

digitalWrite(MC1, LOW);

digitalWrite(MC2, HIGH);

analogWrite(EN, rate);

}

// Остановка двигателя

void brake()

{

digitalWrite(EN, LOW);

digitalWrite(MC1, LOW);

digitalWrite(MC2, LOW);

digitalWrite(EN, HIGH)

}

Обратите внимание, что в начале каждой функции на контакте EN всегда устанавливается низкий уровень, и затем задаются значения на входах блока управления MC1 и MC2. После установки значений на входах MC1 и MC2 можно снова включить ток. Подавая сигнал ШИМ на вход EN, можно управлять скоростью двигателя.

Значение переменной rate должно быть в диапазоне от 0 до 255. Основной цикл программы (листинг 4.4) считывает данные с потенциометра и в зависимости от результата вызывает требуемую функцию.


Листинг 4.4. Программа вызова вспомгательных функций

void loop()

{

val = analogRead(POT);

// Движение вперед

if (val > 562)

{

velocity = map(val, 563, 1023, 0, 255);

forward(velocity);

}

// Движение назад

else if (val < 462)

{

velocity = map(val, 461, 0, 0, 255);

- 96 -

reverse(velocity);

}

// Остановка

else

{

brake();

}

}

Сигнал с аналогового входа преобразуется в цифровое значение в диапазоне от 0 до 1023. Чтобы лучше понять принцип управления, обратимся к рис. 4.8.

Рис. 4.8. Принцип управления двигателем

При значениях сигнала от потенциометра в диапазоне от 462 до 562 ( 100 отсчетов в районе средней точки) вызывается функция break() для остановки двигателя, при значениях от 562 до 1023 - функция запуска двигателя в прямом направлении forward(), при значениях от 0 до 462 - функция запуска двигателя в обратном направлении reverse(). Функция map() знакома вам из предыдущей главы. При определении обратной скорости значение потенциометра 461 соответствует значение скорости 0, а значение потенциометра 0 соответствует значение скорости 255.

Функция map() инвертирует значения так, что на вход они подаются в обратном порядке. Объединив цикл loop() со вспомогательными функциями и начальной установкой setup(), получим полный код программы управления скоростью и направлением движения двигателя с помощью потенциометра (листинг 4.5).

Листинг 4.5. Программа управления двигателем с помощью потенциометра

!! Управление двигателем с помощью Н-моста


const int EN=9;// Вход включения двигателя EN

const int MC1=3;// Вход 1 управления двигателем

const int MC2=2;// Вход 2 управления двигателем

const int POT=0;// Аналоговый вход 0 для подключения потенциометра

int val = 0;// Переменная для хранения значения потенциометра

int velocity = 0;// Переменная для хранения скорости двигателя (0-255)


void setup()

{

pinMode(EN, OUTPUT);

pinMode(MC1, OUTPUT);

pinMode(MC2, OUTPUT);

brake();// Остановка двигателя при инициализации

}

- 97 -


void loop()

{

val = analogRead(POT);

// Движение вперед

if (val > 562)

{

velocity = map(val, 563, 1023, 0, 255);

forward(velocity);

}

// Движение назад

else if (val < 462)

{

velocity = map(val, 461, 0, 0, 255);

reverse(velocity);

}

// Остановка

else

brake();

}

// Движение двигателя вперед с заданной скоростью

// (диапазон 0-255)

void forward (int rate)

{

digitalWrite(EN, LOW);

digitalWrite(MC1, HIGH);

digitalWrite(MC2, LOW);

analogWrite(EN, rate);

}

// Движение двигателя в обратном направлении с заданной скоростью

// (диапазон 0-255)

void reverse (int rate)

{

digitalWrite(EN, LOW);

digitalWrite(MC1, LOW);

digitalWrite(MC2, HIGH);

analogWrite(EN, rate);

}

// Остановка двигателя

void brake()

{

digitalWrite(EN, LOW);

digitalWrite(MC1, LOW);

digitalWrite(MC2, LOW);

digitalWrite(EN, HIGH);

}

- 98 -

Загрузите программу в плату Arduino и запустите на выполнение. Все работает, как ожидалось? Если нет, еще раз внимательно проверьте монтаж.

В качестве упражнения подключите к драйверу H-моста SN754410 второй двигатель постоянного тока и напишите программу управления двумя двигателями.

4.11. Управление серводвигателем

Двигатели постоянного тока прекрасно действуют в качестве моторов, но очень неудобны для точных работ, т. к. не имеют обратной связи. Другими словами, без какого-нибудь внешнего датчика нельзя узнать положение вала двигателя постояого тока. Серводвигатели (или сервоприводы), напротив, отличаются тем, что с помощью команд можно установить их в определенное положение, в котором они будут находиться до поступления новых команд. Это важно, когда необходимо некоторую систему переместить в определенное положение. В этом разделе вы узнаете о серводвигателях и их управлении с помощью Arduino.