Катапульту для канцелярии — стрелять скомканной бумагой через стол — я собрал из палочек от мороженого и SG90 за один вечер. Первый выстрел вышел комичным: write(130) одной командой, резинка дёрнула ложку, серво просела, снаряд упал в пяти сантиметрах от качалки, а серво ещё и загудела. Второй вечер ушёл на то, чтобы понять: я боролся с библиотекой, а надо было честно посчитать рычаг и разложить движение на фазы. Этот урок — про то, как серво встаёт в снаряжение с механикой, а не просто машет рогом.
Смысл не в самой катапульте. Те же два принципа — рычаг и тайминг — держат и шлагбаум, и кормушку, и любые дозаторы: где-то плечо умножает ход, где-то противовес делит усилие, а тайминг превращает угол в событие нужной длительности. Ниже разбор катапульты как витрины, затем перенос того же каркаса на шлагбаум и кормушку — каждый механизм там уже доведён до жизни в отдельном уроке, я оставлю ссылки.
Плечо: что рычаг делает с моментом
Момент на валу — это сила, умноженная на плечо. У SG90 заявлены 1,8 кг·см при 4,8 В: с ложкой в шесть сантиметров серво вытянет на её конце триста граммов, с ложкой в двенадцать — вдвое меньше. Но у длинного плеча есть вторая сторона: конец описывает дугу, пропорциональную длине рычага, — на вдвое более длинной ложке снаряд вылетает вдвое быстрее при вдвое меньшем усилии. Рычаг — это обмен силы на скорость, и катапульта построена на этом обмене целиком: серво не может дать снаряду скорость сама, зато может дать ей рычаг.
Вторая часть силы — резинка. Серво не разгоняет снаряд: она медленно заводит рычаг против натяжения, запасает энергию в резинке и в нужный момент отпускает — вся взрывная работа происходит без мотора. Отсюда требование к серво мягче, чем кажется: держать натяг — режим удержания, а не разгона. Моя катапульта с ложкой 11 см и двумя резинками жила на SG90 с запасом, хотя расчёт по моменту давал впритык. Проверять всё равно надо на своём снаряде: перегруженная ложка — и серво не доезжает до защёлки.
Крепёж решает больше, чем серво: боковая тяга резинки, прикрученная мимо плоскости качания, выворачивает вал и выбирает пластиковые шестерни боком — азы посадки и выбора качалок я собирал в уроке про механику крепежа. Держите натяг в плоскости качания: тяга параллельна рычагу в крайних точках или шарнир между резинкой и ложкой. Качалка — зубчатая или с винтом, потому что рывок при выстреле худший из случаев для гладкой качалки на усиках.
Расчёт на бумаге занимает пять минут и экономит вечер. Мой пример: снаряд тридцать граммов, ложка десять сантиметров, значит статический момент от веса снаряда — триста граммо-сантиметров, то есть 0,03 кг·см — на фоне 1,8 кг·см у SG90 это ничто; основную нагрузку даёт натяг резинки, у моих двух резинок он добавил порядка 0,5 кг·см. Итого около трети паспортного момента — запас втрое, и серво не проседает на заводе. Если у вас сумма выходит за половину паспортного момента — берите MG996R и отдельное питание, а не надейтесь.
Тайминг: скорость — это мс на градус
Библиотека Servo не умеет скорость — она умеет угол. Скорость в серво-скетчах всегда руками: пауза между соседними градусами. В катапульте три скорости: завод двадцать мс на градус — медленный натяг без просадки питания; выстрел четыре мс на градус — ложка летит к защёлке за треть секунды; откат пятнадцать мс на градус — резинку возвращаем плавно, чтобы не хлестала по раме. Все три — константы вверху скетча, а не числа внутри loop: тайминг подбирается на столе, и прыгать по коду ради каждой правки — верный способ запутаться.
Фазы движения — маленький автомат: натяг, прицел, выстрел, отбой, возврат. Между натягом и выстрелом стоит пауза полторы секунды — прицел; серво в это время attached и держит натяг, ест свои десятки-сотни мА, но альтернативы нет: отпустишь — резинка сольёт запасённую энергию мимо защёлки. Автомат на millis без delay — каркас из урока про millis вместо delay, а те же пять состояний в мирной роли я применял в светофоре из урока про конечный автомат: меняются только таймеры и выход.
Кнопка в этой схеме не требует анти-дребезга, и вот почему: её читает только фаза PROSTOJ, дальше автомат игнорирует её до полного возврата. Дребезг при нажатии дал бы пять-десять фальшивых фронтов, но все они попадают в момент, когда серво уже ушла в NATYAG, — повторного выстрела не будет. Гнать кнопку через прерывание тут тоже незачем: пропущенное во время цикла нажатие не беда, новое делается после возврата, а автомат и так опрашивает пин каждый проход loop.
#include <Servo.h> Servo rythag; // D11; кнопка «огонь» — D2, диод готовности — D12 const int PIN_OGON = 2; // INPUT_PULLUP: нажат = LOWconst int PIN_GOTOV = 12; const int NATYAG_DO = 130; // угол натягаconst int VYSTREL_DO = 60; // куда летит рычаг при выстреле const unsigned long T_NATYAG = 20; // мс на градус: медленный заводconst unsigned long T_PRICEL = 1500; // пауза прицелаconst unsigned long T_VYSTREL = 4; // мс на градус: разгонconst unsigned long T_OTBOJ = 2000; // дать рычагу затухнутьconst unsigned long T_VOZVRAT = 15; // мс на градус: плавный возврат const byte PROSTOJ = 0, NATYAG = 1, PRICEL = 2, VYSTREL = 3, OTBOJ = 4, VOZVRAT = 5;byte faza = PROSTOJ; int tek = 0;unsigned long tHod = 0;unsigned long tFaza = 0; void setup() { Serial.begin(9600); pinMode(PIN_OGON, INPUT_PULLUP); pinMode(PIN_GOTOV, OUTPUT); digitalWrite(PIN_GOTOV, HIGH); rythag.attach(11); rythag.write(tek); Serial.println("gotova: knopka - ogon");} void loop() { unsigned long now = millis(); bool knopka = digitalRead(PIN_OGON) == LOW; if (faza == PROSTOJ && knopka) { faza = NATYAG; tFaza = now; digitalWrite(PIN_GOTOV, LOW); Serial.println("faza=natyag"); } switch (faza) { case NATYAG: if (tek < NATYAG_DO && now - tHod >= T_NATYAG) { tHod = now; tek++; rythag.write(tek); } if (tek >= NATYAG_DO) { faza = PRICEL; tFaza = now; Serial.println("faza=pricel"); } break; case PRICEL: if (now - tFaza >= T_PRICEL) { faza = VYSTREL; tHod = now; Serial.println("faza=vystrel"); } break; case VYSTREL: if (tek > VYSTREL_DO && now - tHod >= T_VYSTREL) { tHod = now; tek--; rythag.write(tek); } if (tek <= VYSTREL_DO) { faza = OTBOJ; tFaza = now; Serial.println("snaryad poshel"); } break; case OTBOJ: if (now - tFaza >= T_OTBOJ) { faza = VOZVRAT; tHod = now; Serial.println("faza=vozvrat"); } break; case VOZVRAT: if (tek > 0 && now - tHod >= T_VOZVRAT) { tHod = now; tek--; rythag.write(tek); } if (tek == 0) { faza = PROSTOJ; digitalWrite(PIN_GOTOV, HIGH); Serial.println("gotova snova"); } break; }}Разберу тонкие места скетча. Выстрел — самый быстрый участок, и на нём нельзя срезать угол: если сыпать приказы по градусу каждые четыре миллисекунды, серво не успеет за командами и будет доезжать по своей внутренней скорости — это нормально, важно, что скетч её не тормозит. Реальный потолок всё равно механический: у SG90 это порядка 0,1 с на 60 градусов, цифры и замеры скорости я собирал в уроке про скорость серво. Скетч лишь не мешает ей разгоняться.
Пауза прицела — не украшение: за полторы секунды вы доворачиваете раму, а серво успевает сесть в удержание натяга и перестать гудеть. После выстрела стоит отбой две секунды: рычагу дают затухнуть, резинке — перестать звенеть, и только потом возврат. Спешка на этом участке — источник вторых ложных выстрелов у новичков: рычаг ещё в колебании, а скетч уже завёл его обратно, и снаряд уходит в пол, а не по дуге.
Тайминги я подбираю на столе по журналу фаз: Serial печатает имя фазы с миллис-меткой, из двадцати выстрелов складывается картина — сколько занимает завод, когда щёлкает защёлка, не опережает ли выстрел колебания рычага. Дальше рулетка: замеряю дальность при натяге 120, 130 и 140 градусов и выбираю угол, при котором снаряд ложится в цель, а не в монитор. Все три числа — угол натяга и два тайминга — после этого записываются в константы и больше не правятся руками в коде.
И то, о чём в весёлых проектах принято молчать: снаряд в тридцать граммов с рычага в десять сантиметров на дистанции метра — это скорость, которой можно выбить глаз. Стреляйте вдоль стола, а не через комнату, и держите руку вне сектора рычага: серво при удержании натяга действительно запасает энергию, и случайное срабатывание даёт ощутимый удар. Кнопка на проводе в тридцать сантиметров, а не на самой раме, — простейшее правило, которое я вывел после первого же выстрела мимо стола.
Тот же каркас: шлагбаум и кормушка
Шлагбаум — та же пара «рычаг плюс тайминг», развёрнутая в вертикаль: стрела длинная, и серво поднимает её с усилием, умноженным на плечо. Два приёма делают проект живым: противовес на противоположном конце стрелы режет требуемый момент примерно вдвое, а подъём двумя фазами — медленный отрыв от земли на первых пятнадцати градусах, дальше быстрее — снимает удары по редуктору. Полный проект с дальномером, двумя порогами и гистерезисом я собирал в уроке про шлагбаум на дальномере.
Кормушка переворачивает принцип: здесь рычаг не удлиняют, а укорачивают до дозатора, и угол становится порцией. Заслонка-сектор на 60 градусов высыпает полную порцию, на 30 — половинную; тайминг тут не скорость, а пауза после приезда: зерно сыплется с инерцией ещё двести миллисекунд, и торопливый возврат заслонки урежет порцию непредсказуемо. Дозирование и отладку порций по весам я описывал в уроке про кормушку-дозатор, а полная кормушка с расписанием собрана в итоговом проекте кормушки.
Общий знаменатель трёх построек такой: сначала посчитать рычаг на бумаге — момент, плечо, запас в полтора раза; затем разложить движение на фазы с собственным таймингом у каждой; и только потом писать автомат. Я нарушал этот порядок в обе стороны и всегда платил вечерами: без рычага серво проседала, без фаз — дёргалась, без автомата — рассыпалась на delay, которые нельзя ни подстроить, ни отладить. Порядок экономит вечера, а не наоборот.
| Постройка | Что делает рычаг | Тайминг | Где ловишь грабли |
|---|---|---|---|
| Катапульта | ложка 10-12 см плюс резинка: серво заводит, снаряд летит без мотора | натяг 20 мс/°, прицел 1,5 с, выстрел 4 мс/° | боковая тяга резинки выворачивает вал |
| Шлагбаум | противовес режет момент вдвое, стрела — плечо | медленный отрыв 15°, середина быстрее, мягкий приезд | ветер уводит стрелу, приезд бьёт в упор |
| Кормушка | сектор-заслонка: угол равен порции | пауза 200 мс после приезда: зерно сыплется с инерцией | торопливый возврат режет порцию |
| Пан-тилт | две оси без умножения хода | шаг 12-15 мс/° без рывков | кабель камеры тянет платформу вбок |
- 1. Плечо рычага удвоили. Что стало с усилием на конце?
- 2. Как в скетче задаётся скорость поворота серво?
- 3. Зачем между натягом и выстрелом пауза 1,5 секунды?
- 4. Что даёт противовес на противоположном конце стрелы шлагбаума?
- 5. Почему у кормушки угол поворота связан с порцией?
- Рычаг — обмен силы на скорость: плечо ×2 даёт усилие /2 и дугу конца ×2
- Серво не разгоняет снаряд: заводит рычаг, копит энергию в резинке, отпускает
- Скорость в скетче — мс на градус: натяг 20, выстрел 4, откат 15 — константами вверху
- Автомат фаз на millis: натяг → прицел → выстрел → отбой → возврат, без delay
- Тот же каркас у шлагбаума (противовес плюс две фазы) и кормушки (угол равен порции плюс пауза на инерцию)
Частые вопросы по теме урока
- Плечо рычага удвоили. Что стало с усилием на конце?
- Момент = сила на плечо: при том же моменте серво двойное плечо даёт вдвое меньшее усилие — зато вдвое большую скорость и дугу на конце. Упало вдвое: сила меняется обратно пропорционально плечу
- Как в скетче задаётся скорость поворота серво?
- Servo.h умеет только угол. Скорость строится руками: интервал между градусами — 20 мс натяг, 4 мс выстрел, 15 мс откат. Паузой в миллис между соседними градусами
- Зачем между натягом и выстрелом пауза 1,5 секунды?
- Пауза прицела — рабочее время: рама доворачивается, серво сидит в удержании натяга. Отпускать нельзя — уйдёт запасённая энергия. Чтобы серво остыла
- Что даёт противовес на противоположном конце стрелы шлагбаума?
- Противовес уравновешивает часть веса стрелы: серво поднимает разницу, момент падает примерно вдвое, редуктор живёт дольше. Снижает момент, который серво должна развить для подъёма
- Почему у кормушки угол поворота связан с порцией?
- Сектор-заслонка превращает угол в объём: 60° — полная порция, 30° — половина. Тайминг здесь — пауза на инерцию зерна после приезда. Дозатор высыпает тем больше, чем дальше повернулась заслонка