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


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

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


    Что такое сервопривод? Наверное, все знают, но на всякий случай: это привод, который в отличие от мотора постоянного тока не просто крутится пока подаётся напряжение, а стремится повернуться к заданному углу и удержаться в этом положении. Угол устанавливается с помощью ШИМ (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;
    }
    


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



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

    Комментарии 51

      +4
      Напомнило изобретение Гомера из Симпсонов.
        0
        А что он там собрал? Что-то не помню…
          0
          Молоток, забивающий гвозди.
            +2
            Фигню сказал. Конечно не обычный молоток, а так же забивающий гвозди с помощью сервопривода. Очень похоже на приведенное в этой статье устройство.
              +3
              Серию и сезон, если не сложно, хоть убей не помню такого :)
                +2
                Конечно. S10E02 «The Wizard of Evergreen Terrace», примерно 12-13 минуты.
                +1
                Там кажется гидропривод
        • НЛО прилетело и опубликовало эту надпись здесь
            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
                                                  Весьма интересная мысль. Правда в этом случае можно получать ответ только на вопрос «Достиг угла или нет?», нельзя узнать «Каков угол?»
                                                    0
                                                    Для двигателя постоянного тока (равно как и для другого электродвигателя) можно построить математический алгоритм, так называемый «наблюдатель», который по току и напряжению позволит сказать какая у вала угловая скорость. А вот получить из этой скорости угол — это надо интегрировать. Учитывая что с наблюдателя мы скорость получим с погрешностью за счет неточного определения параметров мотора и допущений модели, после интегрирования угол ещё уплывет в сторону. Сомнительная идея
                                                  –1
                                                  delay(1500);

                                                  За использование этой дряни следует больно бить по рукам. Молотком. Навязывает неверное понимание работы микроконтроллера. Нельзя, повторяю, категорически нельзя портить юные пытливые умы, читающие Ваши посты, позорной практикой реализации задержек «тупым» циклом

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

                                                  Самое читаемое