Фидер для рыб на даче я собрал из самого лучшего: 28BYJ-48, плата ULN2003, четыре батарейки АА на 2000 миллиампер-часов и аккуратный скетч с автокормлением дважды в сутки. Расчёт был щедрым: ход — четыре секунды, кормлений — два, значит, мотор работает восемь секунд в сутки, и запас энергии — в сотни раз. Реальность: через сутки батарейки сели, и рыбы остались голодными. Я искал утечку по-настоящему: отключил мотор — схема продолжала есть, отключил плату ULN2003 от Arduino — почти так же. Мультиметр в разрыве питания между кормлениями объяснил всё мгновенно: схема стабильно ела 240 миллиампер.
Двести сорок миллиампер в простое — это ток удержания из прошлого урока: заслонка фидера между кормлениями держалась магнитным полем, и четыре АА ушли на то, чтобы мотор просто стоял. Порция корма заняла восемь секунд в сутки, а заряжала батарейки дежурка остальные двадцать три часа пятьдесят девять минут пятьдесят две секунды. Полезная работа — девять тысячных долей времени, и вся экономия прячется именно там. Чувствуете пропорцию? Батарейный проект гибнет не от работы, а от дежурства, и никакая оптимизация ходов тут не поможет — лечится только сам простой.
Лечение простое до безобразия: обесточить обмотки, когда движение закончено. Четыре digitalWrite с LOW — и ток падает почти до нуля, мотор остывает, батарейки живут неделями. Но у бесплатного есть цена, и в этом уроке мы заплатим её на бумаге заранее: потерянный момент удержания, вал, который можно провернуть рукой, и позиция, которая умеет уползать, пока вы спите. Плюс честный список случаев, когда обесточивать нельзя ни в каком виде. И поскольку это последний урок раздела, в финале — сборная проверка всего маршрута от первого подключения до батарейки.
Обесточивание: четыре LOW
Механика предельно проста. Сигнальные пины 8, 10, 9, 11 в LOW закрывают все четыре канала ULN2003 — катушки теряют минус, ток в обмотках падает до нуля, и от мотора остаётся только потребление самой платы. Важная деталь: LOW не стирает счётчик шагов из памяти — он продолжает жить в переменных, просто больше не гарантирован физикой вала. Команды дешевле некуда: четыре вызова digitalWrite занимают микро- и такты, а следа в памяти не оставляют вовсе. Дешевле выглядит только перекрыть питание перемычкой на плате — но это ручной режим, а нам нужен автоматический. Проверка глазами мгновенная: четыре светодиода на плате гаснут полностью, мультиметр в разрыве плюса подтверждает — вместо 240 миллиампер счётчик показывает единицы. Приём мы уже трогали в уроке про скорость и позиционирование как совет на полях — теперь сделаем его системой с ценой и ограничениями.
Что происходит с валом? В уроке про передаточное число мы считали редуктор 1:64 — так вот, именно он теперь единственный держатель позиции. Шестерни дают заметное трение: провернуть вал рукой можно, но туго, и лёгкая заслонка на горизонтальной оси останется на месте. Однако любого приличного груза этого трения уже не хватает: вертикальная задвижка сползёт, откинутый рычаг упадёт, а карусель с перекосом медленно докрутится до равновесия. Магнитный замок выключен — держит только механика, и доверять ей можно только после проверки своей нагрузки рукой.
Вторая цена — позиция. Скетч после обесточивания уверен, что вал там, где его оставили: счётчик шагов в памяти не знает о внешнем мире. Если нагрузка провернула вал на пол-оборота, все следующие команды поедут мимо, и скетч этого не заметит. Честное лечение — репер: концевик, геркон или оптопара в нулевой точке, у которых счёт обнуляется, — энкодер как репер мы уже подключали. Для счётчиков между включениями питания спасает EEPROM, но проворот вала она тоже не видит — репер честнее.
| Режим простоя | Ток от питания | Удержание вала | Когда применять |
|---|---|---|---|
| Под током | Около 240 мА | Полное, магнитное | Вертикальные оси, груз, риск проворота |
| Обесточено | Почти 0 | Только трение редуктора 1:64 | Горизонтальные лёгкие механизмы, длинные паузы |
| Обесточено плюс репер | Почти 0 | Нулевое, позиция восстанавливается по метке | Батарейные проекты с произвольной нагрузкой |
Три страховки перед включением приёма в свой скетч. Первая: заканчивайте движение целым числом шагов и не обесточивайте посреди хода — ротор должен стоять в сетке положений, тогда первый такт после пробуждения встанет ровно. Вторая: перед новым движением ничего включать не нужно — первый же такт step() сам зарядит нужные фазы, и ротор дотянется до ближайшего положения сам. Третья: если механизм живёт на склоне или несёт груз — перед обесточиванием подёргайте вал рукой с подключенной нагрузкой; трение редуктора на гладкой оси и трение под грузом — разные вещи, и вторая иногда подводит. Отдельно про длину паузы: если она длиннее пары минут, обесточивание выгодно почти всегда; если короче десяти секунд, экономия мизерная, а ротор при каждом пробуждении дёргается — иногда дешевле оставить ток.
Теперь измерение экономии. USB-тестер или мультиметр в разрыве плюса покажут разницу в момент coilsOff: 240 миллиампер до, единицы после. За час паузы это 240 миллиампер-часов, за сутки дежурства — почти шесть ампер-часов, три комплекта АА. Но будьте честны с собой: сама Arduino Uno в простое ест 45-50 миллиампер с логикой и светодиодами, так что после обесточивания схема не станет невидимой — она станет терпимой: 240 превращаются в 50, а это уже недели вместо ночи. Полный сон платы с разрывом питания — отдельная история с MOSFET-ключом и будильником; для начала снимите мотор — это восемьдесят процентов счёта и весь нагрев.
#include <Stepper.h> const int STEPS_PER_REV = 2048;const int BUTTON = 2; Stepper stepper(STEPS_PER_REV, 8, 10, 9, 11); unsigned long lastFeed = 0; void coilsOff() { digitalWrite(8, LOW); digitalWrite(10, LOW); digitalWrite(9, LOW); digitalWrite(11, LOW);} void feed() { stepper.setSpeed(6); stepper.step(512); // отсыпать порцию coilsOff(); // обесточить: 240 мА -> 0 Serial.println("Porciya otdana, obmotki obestocheny");} void setup() { pinMode(BUTTON, INPUT); Serial.begin(9600); Serial.println("Fider gotov");} void loop() { if (digitalRead(BUTTON) == HIGH) { // ручное кормление кнопкой feed(); delay(2000); } if (millis() - lastFeed >= 600000) { // автокормление раз в 10 минут lastFeed = millis(); feed(); }}Разберём скетч по больным местам. coilsOff() вызывается сразу после step(): библиотека закончила такты, вал стоит — и мы немедленно снимаем ток, светодиоды на плате гаснут в тот же момент. Перед новым кормлением ничего включать не нужно: первый же такт step() сам зарядит нужные фазы. Скорость внутри feed() задаю перед каждым ходом — после пробуждения это стоит микросекунд, зато setSpeed не потеряется между правками скетча. Автокормление живёт на сравнении millis() с меткой прошлого хода — неблокирующий цикл здесь не роскошь: между кормлениями плата обязана опрашивать кнопку, а задержка delay(600000) в двадцати минутах могла бы это похоронить. И ещё деталь из моего фидера: порцию я считаю в шагах от репера-геркона, потому что после ночи простоя счётчик шагов не знает, что с валом делала упавшая на рычаг ветка.
Смотрим экономию в симуляторе
В симуляторе мотор идеальный, нагрузки на валу нет, и проворачивать его некому — поэтому экономику и риски мы, как и в двух прошлых уроках, выносим в Serial. Кнопка на D2 — ручное кормление, тумблер на D3 — условный груз на валу. После каждого хода скетч решает: с грузом ток оставляем — Serial печатает про удержание и model_tok_ma=240, без груза обесточиваем и печатаем model_tok_ma=0. Циферблат показывает позицию, модель — цену каждого решения в миллиамперах. Сравните два прогона подряд, с тумблером и без: разница в строках model_tok_ma= и есть дневной бюджет в миллиампер-минутах. На настоящей плате вместо строк про груз вас ждёт трение редуктора и проворот — их симулятор не покажет, поэтому честные ограничения выше перечитайте ещё раз перед сборкой.
Что попробовать и чем всё кончается. Запустите и дождитесь автокормления: kormlenie=1 и model_tok_ma=0 при выключенном тумблере. Включите тумблер — следующее кормление напечатает строку про груз и оставит ток: скетч сам решает по состоянию механики, как должен вести себя настоящий инженер. На этом раздел замкнулся: вы умеете подключать 28BYJ-48 через ULN2003, читать фазы, считать редуктор, управлять библиотекой, находить скоростной потолок, отличать рабочий нагрев от беды и экономить питание в простое. Соберите это в один батарейный проект — фидер, шторку или вертушку — и прогоните по чек-листам трёх последних уроков: скорость с запасом, воздух вокруг корпуса, обесточенная пауза. После симулятора сделайте то же на настоящей плате и посчитайте, за сколько дней окупается переход от ночи к неделям — у меня это случилось уже в первые сутки. Такой механизм живёт неделями без присмотра, и это, по большому счёту, и есть цель всей арифметики, которую мы считали.
- Четыре digitalWrite LOW на пины 8, 10, 9, 11 гасят ток удержания: 240 мА превращаются в ноль, светодиоды ULN2003 тухнут
- Цена — момент удержания: держит только трение редуктора 1:64, вал проворачивается рукой, груз проворачивает сам
- Позиция после обесточивания не охраняется: провернутый вал ломает весь дальнейший счёт шагов, скетч об этом не узнает
- Лечение — репер: концевик, геркон или энкодер в нулевой точке; EEPROM хранит счётчик, но проворота не видит
- Батарейный бюджет: без обесточивания четыре АА живут ночь, с обесточиванием — недели; между ходами живёт millis-планировщик
- 1. Сколько экономит обесточивание обмоток у 28BYJ-48 в простое?
- 2. Что мы теряем, обесточивая обмотки?
- 3. В каком случае обесточивать нельзя?
- 4. Что держит вал после снятия тока?
- 5. Как скетч фидера понимает, что пора кормить?
Частые вопросы по теме урока
- Сколько экономит обесточивание обмоток у 28BYJ-48 в простое?
- Ток удержания двух катушек с потерями драйвера — 200-240 мА. После четырёх LOW от мотора остаётся только потребление самой платы: светодиоды ULN2003 тухнут, а плата продолжает жить. Около 240 мА
- Что мы теряем, обесточивая обмотки?
- Магнитный замок выключен: позицию держит только трение шестерён. Лёгкую нагрузку это выдержит, груз — нет. Момент удержания
- В каком случае обесточивать нельзя?
- Груз провернет обесточенный вал: задвижка сползёт, а счётчик шагов об этом не узнает. Держим ток или меняем механику; репер после пробуждения вернёт счёт к нулю. Вертикальная задвижка с грузом
- Что держит вал после снятия тока?
- Магнитного поля нет, механика редуктора даёт тугой, но преодолимый проворот. Всё остальное — из области надежд. Трение шестерён редуктора 1:64
- Как скетч фидера понимает, что пора кормить?
- Автокормление живёт на millis: разница с меткой прошлого хода перевалила за интервал — едем. Пауза не блокирует плату. Сравнивает millis() с меткой прошлого кормления