Амперка
Компания
35,90
рейтинг
5 сентября 2011 в 17:28

Разное → Обратная связь от сервопривода или «забиваем гвозди»


Всем хабраконструкторам, привет!

Пришла мне как-то в голову дурацкая мысль: собрать девайс, который бы молотком забивал гвозди. Просто ради демонстрации работы сервопривода. Алгоритм простой: даём команду на поднятие молотка, ждём пока он поднимется, отпускаем молоток; и так пока гвоздь не будет забит. Но как узнать, что молоток поднялся и что гвоздь забит, не пользуясь дополнительными датчиками? Спросить у «глупого» сервопривода! Как именно это сделать — об этом и пойдёт речь в статье.


Что такое сервопривод? Наверное, все знают, но на всякий случай: это привод, который в отличие от мотора постоянного тока не просто крутится пока подаётся напряжение, а стремится повернуться к заданному углу и удержаться в этом положении. Угол устанавливается с помощью ШИМ (PWM)-сигнала. Сервопривод стремится к определённому положению, а следовательно должен знать своё собственное. Перед началом сборки я был уверен, что запросить текущий угол будет проще простого и это возможно «из коробки». Не тут то было. Но обо всём по порядку.

Итак, предполагаемый девайс: сервопривод с прикреплённым к нему молотком на небольшом постаменте для равновесия. Сервопривод подключается к Arduino через IO Shield, а микроконтроллер исполняет алгоритм:
  • Установить сервоприводу определённый угол для поднятия молотка
  • Бездействовать пока сервопривод не сообщит, что угол достигнут
  • Отключить питание сервопривода, чтобы молоток упал на гвоздь
  • Прочитать угол в упавшем положении
  • Если угол после падения несколько раз подряд не изменился — значит гвоздь перестал вколачиваться. Предположительно он забит — прекращаем исполнение
  • Если угол изменился, начинаем сначала

Берём исходные части:



Пилим и скручиваем:



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

Быстро погуглив проблему, нашёл кучу сообщений на форумах, где на этот вопрос авторитетно отвечали: «Это не возможно! Сервоприводы — это write-only устройства». Меня это привело в замешательство, я интуитивно чувствовал, что достать эти данные как-то просто можно.

Матчасть

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

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



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

Вот как припаян потенциометр на сервоприводах от DFRobot:



Нам нужен сигнал с бегунка, который меняется в зависимости от угла поворота от минимального до максимального напряжения. Берём мультиметр, вращаем шпиндель и смотрим: каким углам какой сигнал соответствует. Для моей сервы углу в 0° соответствует напряжение 0.43 В, а максимальному углу поворота в 180° соответствует напряжение 2.56 В.

Аккуратно припаиваем новый сигнальный провод.



Подключаем его к аналоговому входу A5 на Arduino. Закрываем крышку. Пишем программу:

#include <Servo.h>

// разрешене аналогого порта
#define A_MAX 1024

// опорное напряжение на котором работает серва
#define A_VREF 5

// предельные уровни сигнала с сервы
#define A_VMIN 0.43
#define A_VMAX 2.56

Servo servo;

int lastHitAngle = 0;
int hitAngleMatches = 0;
bool jobDone = false;

/*
 * Возвращает текущий угол поворота сервы исходя
 * из сигнала с его потенциометра
 */
int realAngle()
{
    return map(
            analogRead(A5), 
            A_MAX * A_VMIN / A_VREF, 
            A_MAX * A_VMAX / A_VREF, 
            0, 180);
}

void setup()
{
}

void loop()
{
    if (jobDone)
        return;

    // включаем серву и просим повернуться до положения 70°
    servo.attach(6);
    servo.write(70);

    // ждём поворота. 5° запаса на всякие погрешности
    while (realAngle() < 65)
        ;

    // бросаем молоток и ждём немного пока он успокоится
    servo.detach();
    delay(1500);

    // запоминаем угол после падения и сопоставляем его с
    // предыдущим
    int hitAngle = realAngle();
    if (hitAngle == lastHitAngle)
        ++hitAngleMatches;
    else {
        lastHitAngle = hitAngle;
        hitAngleMatches = 0;
    }

    // если угол не менялся 5 раз — мы закончили
    if (hitAngleMatches >= 5)
        jobDone = true;
}


Включаем, пробуем, работает!



Что делать с полученным опытом — вариантов много: можно сделать контроллер вроде того, что используется на кораблях для установки тяги (полный вперёд / полный назад); можно использовать серву с обратной связью как элемент автономного рулевого управления какой-нибудь машины; можно много всего. Да прибудет со всеми нами фантазия!
Автор: @nailxx
Амперка
рейтинг 35,90
Компания прекратила активность на сайте

Комментарии (49)

  • +4
    Напомнило изобретение Гомера из Симпсонов.
    • 0
      А что он там собрал? Что-то не помню…
      • 0
        Молоток, забивающий гвозди.
        • +2
          Фигню сказал. Конечно не обычный молоток, а так же забивающий гвозди с помощью сервопривода. Очень похоже на приведенное в этой статье устройство.
          • +3
            Серию и сезон, если не сложно, хоть убей не помню такого :)
            • +2
              Конечно. S10E02 «The Wizard of Evergreen Terrace», примерно 12-13 минуты.
          • +1
            Там кажется гидропривод
  • 0
    А сколько может веса поднять этот сервопривод? Какая модель?

    Вот хочу собрать роборуку. Поэтому нужен серв, который может поднимать нагрузки и при этом определять достаточно ли он сжал предмет, чтобы тот не выпал, но и не раздавливал его.
    • 0
      Это модель DFRobot Standard 5kg Servo. Максимальный крутящий момент: 5 кг×см или если пересчитать в единицах си 0.5 Н×м. Не совсем корректно спрашивать сколько он может поднять — зависит от длины плеча. При креплении груза на расстоянии 1см от шпинделя по идее должен поднимать до 5кг.
    • 0
      На хоббикинг.ком посмотри, там очень шикарный выбор
    • +2
      Вот хочу собрать роборуку.
      image
      • +3
        Вы помните чем это всё закончилось?
  • +1
    Не поверите: вчера такой же молоток в метрике купил!

    Это знак)
  • +3
  • 0
    А шаговый двигатель использовать не проще было?
    • 0
      Для объяснения возможности обратной связи от сервопривода — нет. Для колотушки, пожалуй.
    • +1
      У шаговых двигателей при прочих равных — меньше мощность…
    • 0
      Для шагового двигателя нужен датчик начального положения. Плюс к этому, не исключены пропуски шагов, особенно с такой инерционной нагрузкой, как молоток.
    • 0
      А в каком месте проще? Шаговым и управлять сложнее и датчика положения там нет, надо будет дополнительно колхозить. А, да, они ещё, как правило, без редукторов, то есть ещё и редуктор мастырить.
  • –9
    Настоящий топик зла. Вы хотя бы не дома этим занимайтесь, пожалуйста.
  • +1
    У меня такие стандартные сервы в самолете, но кроме как по назначению я их не использовал. А вот допилить и сделать орехокол :-) к стенду изображенному выше приделать кнопку при нажатии на кторую произведется удар. И вот тебе и применение. :-)
    • +2
      Как вариант: приладить молоток к батарее. Включать по сигнаглу датчика вибрации, фиксирующем уровень шума у соседей.
      • +4
        Ваш вариант шикарен. Вспоминаю свою любимую бабушку, она жила над пивбаром, а с разваром СССР там появилось чтото вроде ресторана. Ну и под вечер те врубали музон, но до бабушки доходили только басы — бух-бух-бух. И бабушка гатила что есть силы молотком по трубам. После ресторан ей плотил за терпение. :-)

        Разработать эконом вариант, с крепежем на трубы и пультиком ик. Лежишь на диване — какое то движение по стояку пошло — и ты им ГУП-ГУП-ГУП!!!

        :-)
        • 0
          Тогда уж молот с ударом в пол!
  • 0
    Мне кажется выгоднее было бы собрать систему, где сервопривод поднимает молоток, а опускается он под своим весом, мне кажется сила удара была бы выше.
    • +2
      Тут так и сделано:
         // бросаем молоток и ждём немного пока он успокоится
          servo.detach();
          delay(1500);
      • 0
        ну просто на видео больше похоже на то что он поднимается и опускается именно приводом
        • 0
          Послушайте звук: при падении его частота по мере приближения к нижней точке увеличивается, что свидетельствует об увеличении угловой скорости. Контролируемый поворот не дал бы такого эффекта.
          • 0
            А как вы это реализовали? У мегя стандартная серва при отключенном питании практически не проворачивается. Это ей нужно опять же провернуть все шестерни вместе с мотором. И я думаю что после поднятия молотка и отключении питания он просто зависнет в воздухе.

            Например я разобрал механику в поворотном механизме от управляемой машинке, там чтото вроде сервы, только вал мотора не закреплен жестко на шестеренках, и передает усилиет только в момент когда мотор крутся и центробежной силой там как бы срабатывает сцепление. А при отключении питания шестерни уже не касаюься мотора и раскручиваются в обратном направление когда колеса и выравниваътся. Но ведь на серве не так. Как вы реализовали падение молотка?
            • 0
              Я даже над этим не задумывался. Молоток своим весом очень неплохо поворачивает отключенный от питания привод. Его в общем-то свободно можно поворачивать и голыми руками за качельку. Он заметно сопротивляется, но не настолько, чтобы потеть. Просто за шпиндель, да — не повернуть: пальцы проскальзывают. Если есть рычаг — не проблема.
              • 0
                Ясно. Но я думаю механика на рассчитана на обратную тягу такую и достаточно быстро выйдет серва из строя. Я тут одной машинкой так баловался пока самолет не собрал, так у нее после появились посторонние шумы.
                • 0
                  Не очень понимаю какая ей разница до обратной тяги. Скорее первым развалится вал сервопривода, мне кажется.
                  • 0
                    Ну мне кажется как система с блоками, если использовать по правильному назначению, то прилагая малое усилие на конце блоков получим высокую силу. А если наоборот то нужно приложить большое усилие чтоб раскрутить в конце моторчик. Я просто думаю что пластиковые шестерни не рассчитаны чтоб на них давили в обратном направлении.

                    Ладно, то мы в дебри полезли уже.
                    • 0
                      Серву нельзя крутить руками, хотя, можно, но не долго, а потом сколько угодно.
                      В смысле руками свернуть вал есть вероятность. А молоток его же не проворачивает, а возвращает в исходное, спокойное состояние, поэтому, полагаю, серва жить будет, опять же все зависит от типы сервы.
  • +3
    Дайте ему попробовать сотку забить ))
  • +2
    … ну а если вы не дружите с паяльником, или кроме положения вам нужен фидбек по усилию, току, температуре, задание ускорения, опциональная работа в режиме колеса и прочие плюшки — то существует вот это и вот это. Правда для того, чтобы воспользоваться всеми преимуществами, придётся посидеть над кодом несколько дольше, чем над паяльником у обычного привода.
  • +4
    Дожили, гвоздь забить без контроллера уже нельзя…
  • +3
    Вам нужно было не молоток привязывать, а пилу. Могли бы тогда писать Медведеву на счет получения гранта на внедрение изобретения :)
  • +1
    > Угол устанавливается с помощью ШИМ (PWM)-сигнала.

    Вы путаете PWM (Широтно-Импульсная Модуляция) и PPM (Импульсно-Позиционная Модуляция). Не следует этого делать.
    Сервоприводы, о которых идет речь в Вашем посте, используют PPM.
    • 0
      Тонкая разница… Спасибо!
      • 0
        Исправьте что ли текст поста, зачем вводить людей в заблуждение? :)
        • +1
          Не хотел править пока не убежусь, что вы правы. А вы не совсем правы: способ управления сервами нельзя однозначно отнести ни к PWM ни к PPM.

          Так как информация об угле переносится всё же в ширине пульса, а не в его временнОм положении, считаю, что термин PWM корректнее.
  • 0
    Этот звук… теперь сниться будет.
    • 0
      Спокойной ночи!
      • 0
        рано )))
  • +1
    Мне нравится название вашей компании =)
    • +2
      Спасибо! У вас ник — тоже ничего :)
  • 0
    А если не разбирать готовый серво-привод и не припаивать дополнительные провода?
    Зачем ломать готовое красивое изделие, и терять взаимо-заменяемость?

    А просто мерить потребляемый ток? Как только привод достигнет заданного положения — потребляемый ток заметно упадёт, что и будет индикатором достижения заданного угла… надо попробовать ;)
    • 0
      Весьма интересная мысль. Правда в этом случае можно получать ответ только на вопрос «Достиг угла или нет?», нельзя узнать «Каков угол?»

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Разное