Я сидел и тупо смотрел на колесо своей платформы. Оно послушно вращалось. Потом я нажал кнопку «Назад» на джойстике — оно продолжало вращаться вперёд. Я переполяризовал провода — оно закрутилось назад. Я перезалил скетч — бдыщь — оно снова поехало вперёд, игнорируя мои молитвы. Внутри меня что-то щёлкнуло. Нет, это не колесо наехало на камень. Это мой мозг наконец-то понял, что для управления направлением обычным мотором одной ножки Arduino — категорически мало.
Диагноз: а что вообще пошло не так?
В интернете полно схем, где к моторчику подключают транзистор, дают HIGH на базу, и мотор крутится. Работает? Работает. До первого раза, когда вы захотите, чтобы он крутился обратно.
Почему это не работает? Потому что Arduino — это цифровая логика. HIGH или LOW. Ей плевать на полярность. А постоянный (коллекторный) мотор меняет направление, только если поменять местами плюс и минус физически. Когда у вас один провод всегда на GND, а второй — просто «включено/выключено», прощай реверс. Ваш ШИМ-сигнал регулирует скорость, но не направление. Вы просто заставляете мотор вращаться по кругу, меняя частоту его дрожания, но не вектор. Это как крутить руль автомобиля, не поворачивая его.
Экзекуция: решение
Выкидываем одноногий транзистор в ящик и строим H-мост. Не бойтесь этого слова. На коленке это делается на двух реле или на микросхеме L293D (берём самую простую, без драйверов шаговых). Схема для нищебродов:
- Вход IN1 и IN2 — два пина Arduino.
- Подаём HIGH на IN1 и LOW на IN2 — мотор крутит влево.
- Меняем на LOW на IN1 и HIGH на IN2 — мотор крутит вправо.
Код — это даже не код, это магия двух строк. Забудьте про digitalWrite(motorPin, HIGH). Теперь у вас святая святых:
// Допустим, мотор подключён к выходам драйвера
#define MOTOR_A 9
#define MOTOR_B 10
void setup() {
pinMode(MOTOR_A, OUTPUT);
pinMode(MOTOR_B, OUTPUT);
}
void loop() {
// Крутим вперёд
digitalWrite(MOTOR_A, HIGH);
digitalWrite(MOTOR_B, LOW);
delay(2000);
// Крутим назад
digitalWrite(MOTOR_A, LOW);
digitalWrite(MOTOR_B, HIGH);
delay(2000);
// Тормозим (коротким замыканием выходов драйвера, если он это умеет)
digitalWrite(MOTOR_A, LOW);
digitalWrite(MOTOR_B, LOW);
delay(1000);
}
Вот и всё. Никаких реле, щёлкающих как пулемёт. Два пина — два состояния.
Мораль ROBOTUMER
Ошибка «Я думал, что HIGH — это вперёд» — это не баг, а первый шаг к пониманию архитектуры. Запомните: Arduino мыслит битами, а мотор — полярностью. Пока вы не дадите ему ДВЕ управляющие ноги, он будет двигаться только в одну сторону — в сторону вашего разочарования.
Не пытайтесь обмануть физику одним транзистором. Хотите управлять миром? Стройте мосты. H-мосты.