Компонент · Исполнительный механизм

Редукторный двигатель N20 с энкодером

N20 — компактный двигатель с металлическим редуктором и встроенным энкодером для балансирующих роботов, которым нужны момент и положение колёс.

Что это такое

N20 — небольшой двигатель с металлическим редуктором, который применяется везде, где роботу нужен значительный момент в очень ограниченном пространстве. Сам двигатель примерно размером с батарею AA; редуктор в передней части меняет его очень высокую скорость на пригодный момент, а в версии с энкодером магнитный диск на заднем валу сообщает, насколько он повернулся.

Именно последняя функция обеспечивает двигателю место в балансирующем роботе. Без обратной связи по колёсам балансирующий робот может оставаться вертикальным, но не знает, где находится: он будет великолепно удерживать вертикаль, одновременно блуждая по комнате. Энкодер устраняет этот недостаток.

Временная диаграмма двух выходов квадратурного энкодера. Канал A показан над каналом B как прямоугольные волны одинаковой частоты, причём B отстаёт от A на четверть периода. Четыре вертикальные пунктирные линии отмечают переходы в пределах одного электрического периода, пронумерованные от одного до четырёх; подпись поясняет, что подсчёт всех четырёх даёт 1200 отсчётов за оборот для энкодера 300 CPR. Примечание указывает на фазовое смещение: B после A означает движение вперёд, а B перед A — движение колеса назад.
Два канала со сдвигом на четверть периода делают этот двигатель стоящим дополнительных проводов: порядок фаз задаёт направление, а число фронтов — расстояние. Скачать SVG

Почему здесь важен металлический редуктор

Двигатель с пластиковым редуктором, например редукторный двигатель TT, отлично подходит роботу, следующему по линии, который чаще всего едет вперёд. Балансирующий робот создаёт другую нагрузку: он непрерывно меняет направление сотни раз в секунду, небольшими шагами.

В каждом редукторе есть люфт — небольшая зона нечувствительности, в которой зубчатые колёса расцеплены и выход не движется до повторного зацепления с другой стороны. В пластиковом редукторе эта зона велика, а в балансирующем роботе она возникает именно там, где коррекция нужнее всего: в момент смены направления, когда колёсам нужно отреагировать сейчас. В результате робот колеблется около вертикали и никак не успокаивается, как бы тщательно ни были настроены коэффициенты усиления.

Металлические шестерни не устраняют люфт, но уменьшают его настолько, что контур может работать. Остаточную величину можно измерить примерно за десять минут — вот как это сделать.

Чтение энкодера

Энкодер формирует две прямоугольные волны со сдвигом 90° — стандартный квадратурный сигнал. Взаимное расположение фаз сообщает направление; подсчёт фронтов сообщает расстояние.

Провод (обычно) Подключение Примечание
M1, M2 Выходы драйвера двигателя Сам двигатель; полярность задаёт направление
VCC 3.3 V или 5 V Питание энкодера, не двигателя
GND Земля Общая с контроллером
C1 Вывод, способный вызвать прерывание Канал A энкодера
C2 Любой цифровой вывод Канал B энкодера

Цвета проводов различаются у поставщиков, поэтому проверяйте описание изделия, а не полагайтесь на догадку. Частая ошибка — питание энкодера от линии питания двигателя: энкодеру требуется чистое логическое питание, а подача напряжения двигателя либо уничтожит его, либо заполнит отсчёты шумом при каждом переключении двигателя.

Подключите канал A к выводу, который может вызвать прерывание. Опрос энкодера из loop() на балансирующем роботе теряет отсчёты, а потеря отсчётов означает, что внешний контур постепенно теряет представление о положении робота.

Выбор передаточного числа

Передаточное число задаёт компромисс между моментом и скоростью, а балансирующему роботу нужны обе величины:

  • Слишком большое передаточное число (1:250 и выше) обеспечивает избыточный момент, но колёса не могут раскрутиться достаточно быстро, чтобы остановить падающее тело.
  • Слишком малое передаточное число (1:30 и ниже) даёт быстрое вращение, но недостаточно момента для уверенного перемещения массы робота.

Значение около 1:100 при 12 V — примерно 200 RPM — надёжная отправная точка для небольшого робота. Если ваш робот восстанавливается после небольших возмущений, но теряет равновесие от больших, вероятно, ему нужно больше скорости, а не большее усиление.

Управление

Сочетайте N20 с TB6612FNG, а не с L298N. Причина — падение напряжения: L298N теряет на выходном каскаде примерно 2 V, поэтому значительная часть батареи вообще не достигает двигателя, а небольшие команды коррекции падают ниже порога, при котором двигатель движется. На балансирующем роботе эта зона нечувствительности находится именно там, где нужны тонкие коррекции.

Питайте его от батарейного блока, который одновременно обеспечивает ток останова обоих двигателей без значительной просадки: иначе просадка шины перезагрузит микроконтроллер посреди коррекции, и робот упадёт по причинам, никак не связанным с контуром регулирования.

Расчёт отсчётов на один оборот колеса

От этого значения зависят все расчёты расстояния, и именно его чаще всего вычисляют неверно — обычно в четыре раза.

counts per wheel revolution = PPR x 4 x gear ratio

Магнитный энкодер выдаёт 7 импульсов на оборот двигателя в каждом канале. Квадратурный сигнал означает два канала со сдвигом 90°, создающих четыре подсчитываемых фронта за цикл импульсов. А редуктор означает, что двигатель делает много оборотов на один оборот колеса.

Передаточное число Отсчёты на оборот колеса (×4) Разрешение на колесе 43 mm
1:30 840 0.16 mm
1:50 1400 0.10 mm
1:100 2800 0.048 mm
1:150 4200 0.032 mm
1:298 8344 0.016 mm

Затем расстояние вычисляется напрямую:

mm per count = (pi x wheel_diameter_mm) / counts_per_revolution

В первой формуле скрываются две ловушки. Множитель ×4 верен только при подсчёте всех четырёх фронтов — обоих фронтов в обоих каналах. Многие примеры считают только фронты канала A, то есть используют ×1; применение константы ×4 при подсчёте ×1 завышает расстояние ровно в четыре раза. Кроме того, передаточное число на двигателе часто приблизительное: N20 «1:100» нередко имеет отношение 1:99.5 или 1:100.37. Для одометрии на любом расстоянии проведите эмпирическую калибровку: толкните робота ровно на 2 m и разделите результат.

Подсчёт фронтов без потерь

При 200 RPM и редукторе 1:100 вал двигателя вращается с 20000 RPM, что даёт 20000/60 × 7 × 4 ≈ 9300 edges per second per motor. Для двух двигателей это почти 19000 прерываний в секунду даже на полной скорости без нагрузки.

Обработчик прерывания должен быть по-настоящему небольшим:

volatile long countL = 0;

// Full x4 decoding, table-driven. Both channels, both edges.
const int8_t QUAD_TABLE[16] = {0,-1,1,0, 1,0,0,-1, -1,0,0,1, 0,1,-1,0};
volatile uint8_t prevL = 0;

void isrLeft() {
  uint8_t now = (digitalRead(ENC_L_A) << 1) | digitalRead(ENC_L_B);
  countL += QUAD_TABLE[(prevL << 2) | now];
  prevL = now;
}

void setup() {
  pinMode(ENC_L_A, INPUT_PULLUP);
  pinMode(ENC_L_B, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(ENC_L_A), isrLeft, CHANGE);
  attachInterrupt(digitalPinToInterrupt(ENC_L_B), isrLeft, CHANGE);
}

long readCount() {           // long is not atomic on an 8-bit AVR
  noInterrupts();
  long v = countL;
  interrupts();
  return v;
}

Важны три детали.

volatile и атомарное чтение. Тип long на AVR занимает четыре байта и считывается по одному байту. Прерывание, попавшее посреди чтения, даёт значение, наполовину старое и наполовину новое, из-за чего одометрия примерно один раз в несколько тысяч чтений получает случайный огромный скачок.

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

Нагрузка на выводы. Полное декодирование ×4 для двух двигателей требует четырёх выводов, способных вызвать прерывания, а у Arduino Uno их ровно два. Варианты: использовать декодирование ×2 с одним каналом на двигатель и CHANGE, снизив разрешение вдвое, но сохранив направление; перейти на плату с большим числом прерываний, например Mega или ESP32; либо применить прерывания по изменению выводов, поддерживаемые каждым выводом AVR, но требующие обработки всего порта целиком.

Скорость по отсчётам

Положение — это отсчёт. Для скорости нужна разность за некоторое время, и способ её вычисления определяет пригодность контура регулирования.

long lastCount = 0;
unsigned long lastMicros = 0;

float speedMmPerSec() {
  long   c  = readCount();
  unsigned long t = micros();

  float dt = (t - lastMicros) * 1e-6f;
  if (dt < 0.005f) return lastSpeed;        // too short: quantisation dominates

  float mm = (c - lastCount) * MM_PER_COUNT;
  lastCount = c; lastMicros = t;

  lastSpeed = mm / dt;
  return lastSpeed;
}

Защита dt — важнейшая строка. При слишком частом опросе вы делите разность в один-два отсчёта на крошечный интервал, поэтому преобладает ошибка квантования и «скорость» состоит в основном из шума, который производная в контуре ПИД-регулятора (PID) затем охотно усиливает.

Существуют два честных способа измерения скорости по энкодеру, подходящих для разных участков диапазона. Подсчёт фронтов в фиксированном окне (код выше) хорош на высокой скорости и плох на низкой, где на окно приходит мало фронтов. Измерение интервала между фронтами даёт обратный результат: отлично на низкой скорости и шумно на высокой. Роботу, нуждающемуся в обоих режимах, обычно переключают между ними по порогу.

Диагностика

Симптом Вероятная причина Исправление
Отсчёты в 4× меньше Считается один фронт, но используется константа ×4 Декодировать все четыре фронта или исправить константу
Отсчёты растут в обоих направлениях Считывается только один канал Квадратурному сигналу нужны оба канала — использовать табличный декодер
Случайный огромный скачок положения Неатомарное чтение long Поместить чтение в noInterrupts()
Отсчёты дрейфуют при остановленном двигателе Электрический шум на линиях энкодера Питать энкодер от чистого источника, не от шины двигателя; скрутить пару
Отсчёты теряются на высокой скорости Слишком долгий обработчик прерывания или опрос вместо прерываний Сделать ISR минимальным; никогда не опрашивать в цикле
Расстояние постоянно отличается на 2–3% Номинальные передаточное число и диаметр колеса Откалибровать на 2 m и определить mm на отсчёт
Одно колесо считает, другое нет Канал энкодера не подключён к выводу прерывания Проверить возможности выводов; у Uno есть только D2 и D3
Энкодер вышел из строя после подключения Напряжение двигателя подано на VCC энкодера Энкодеру нужна логика 3.3–5 V, а не шина двигателя
Положение робота уплывает за длительный заезд Одометрия по своей природе не ограничена Ожидаемо — корректировать по абсолютной опорной величине

N20 или редукторный двигатель TT?

Редукторный двигатель TT Двигатель N20 с металлическими шестернями
Редуктор Пластиковый Металлический
Люфт Большой — несколько градусов на выходе Малый
Размер Громоздкий Примерно с батарею AA
Напряжение 3–6 V Варианты 6–12 V
Доступные передаточные числа Практически одно (~1:48) От 1:30 до 1:298
Энкодер Сторонний, неудобный Встроенный магнитный, стандартный
Стоимость ~$2 ~$8
Лучшее применение Роботы, следующие по линии, первые проекты Балансировка, точная одометрия, тесные пространства

Решающим фактором редко бывает момент — почти всегда это люфт и обратная связь. Робот, следующий по линии, чаще едет вперёд и управляется датчиком, смотрящим в пол; он никогда не замечает люфт редуктора, и двигатель TT является правильным дешёвым решением. Балансирующий робот сотни раз в секунду меняет направление небольшими шагами, поэтому зона нечувствительности при каждой смене направления находится ровно там, где нужна коррекция, а пластиковые шестерни делают контур неустойчивым при любой настройке.

Та же логика применима к решателю лабиринта: он навигирует по пройденному расстоянию, поэтому потеря хода на каждом повороте непосредственно накапливается в ошибку положения.

Где применяется

Исследуйте граф

Используется в этих сборках

Проекты, учебные пути и симуляторы, в которых используется Редукторный двигатель N20 с энкодером.

Сравнение

Альтернативы

Вопросы

Редукторный двигатель N20 с энкодером: частые вопросы

Что такое двигатель N20 с энкодером?

N20 — микроредукторный двигатель размером примерно 12 × 10 × 26 mm с металлическим редуктором; версия с энкодером добавляет небольшой магнитный диск и датчик на задней стороне вала двигателя. Редуктор обеспечивает намного больший момент, чем можно ожидать по размеру, а энкодер сообщает, насколько вал действительно повернулся, а не насколько требовалось повернуть его по команде.

Почему балансирующие роботы используют двигатели N20, а не TT?

По двум причинам. Металлический редуктор имеет намного меньший люфт, чем пластиковый редуктор двигателя TT, а люфт губителен для балансирующего робота: при каждой смене направления расшатанный редуктор бесполезно расходует первые несколько градусов коррекции. Энкодер также даёт внешнему контуру регулирования реальное положение колёс, позволяя удерживать точку, а не дрейфовать.

Сколько отсчётов энкодера N20 даёт на один оборот колеса?

Умножьте число импульсов вала двигателя на передаточное число. Типичный энкодер выдаёт по 7 импульсов на оборот двигателя на каждый канал; с редуктором 1:100 это 700 импульсов на оборот выходного вала или 2800 отсчётов при подсчёте всех четырёх переходов квадратурного сигнала. Всегда проверяйте значение для конкретного двигателя, поскольку число импульсов и точное передаточное число различаются у поставщиков.

Можно ли питать N20 непосредственно от вывода Arduino?

Нет. При работе N20 потребляет несколько сотен миллиампер, а при останове около 700 mA, что значительно превышает возможности вывода; индуктивный выброс также повредит его. Используйте драйвер двигателя вроде TB6612FNG, у которого достаточно низкое падение напряжения, чтобы даже небольшие команды коррекции действительно двигали двигатель.

Какое передаточное число выбрать для балансирующего робота?

Обычный компромисс — диапазон от 1:50 до 1:150. Слишком большое передаточное число даёт много момента, но колёса не могут разогнаться достаточно быстро, чтобы поймать падение; слишком малое не обеспечивает момента для перемещения массы робота. Значение около 1:100 при 12 V, дающее примерно 200 RPM, подходит типичному небольшому балансирующему роботу.

Дополнительные материалы

Источники