Я сидел и тупо смотрел на колесо своей платформы. Оно послушно вращалось. Потом я нажал кнопку «Назад» на джойстике — оно продолжало вращаться вперёд. Я переполяризовал провода — оно закрутилось назад. Я перезалил скетч — бдыщь — оно снова поехало вперёд, игнорируя мои молитвы. Внутри меня что-то щёлкнуло. Нет, это не колесо наехало на камень. Это мой мозг наконец-то понял, что для управления направлением обычным мотором одной ножки Arduino — категорически мало.

Диагноз: а что вообще пошло не так?

В интернете полно схем, где к моторчику подключают транзистор, дают HIGH на базу, и мотор крутится. Работает? Работает. До первого раза, когда вы захотите, чтобы он крутился обратно.

Почему это не работает? Потому что Arduino — это цифровая логика. HIGH или LOW. Ей плевать на полярность. А постоянный (коллекторный) мотор меняет направление, только если поменять местами плюс и минус физически. Когда у вас один провод всегда на GND, а второй — просто «включено/выключено», прощай реверс. Ваш ШИМ-сигнал регулирует скорость, но не направление. Вы просто заставляете мотор вращаться по кругу, меняя частоту его дрожания, но не вектор. Это как крутить руль автомобиля, не поворачивая его.

Экзекуция: решение

Выкидываем одноногий транзистор в ящик и строим H-мост. Не бойтесь этого слова. На коленке это делается на двух реле или на микросхеме L293D (берём самую простую, без драйверов шаговых). Схема для нищебродов:

  1. Вход IN1 и IN2 — два пина Arduino.
  2. Подаём HIGH на IN1 и LOW на IN2 — мотор крутит влево.
  3. Меняем на 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-мосты.