Arduino: Робо-рука на двух сервоприводах


Никогда раньше не имел дело с микроконтроллерами, поэтому решил начать своё знакомство с Ардуино. Понадобились базовые знания С/C++ и немного электроники.

Цель: При помощи Arduino Uno и двух сервоприводов (9g SG90 Mini Micro Servo) написать на листе бумаги любое словосочетание.

Стояли такие задачи:

1) Установить среду разработки под Linux Fedora, получилось не сразу, но долго мучиться не пришлось. Был баг с поискам “Serial Port”, но гугл и терпение сделали свое дело.

2) Разобраться в том, что же такое за чудо сервопривод, в народе “серва”. Так как изначально у меня были сервы с вращением против часовой стрелки, весь код писался под них, но когда пришло время поменять их на новые “дешёвые” SG90, вдруг обнаружилось, что новые вращаются по часовой стрелке! Проблема решается просто: при помощи паяльника, меняются местами провода: на двигателе, и крайние (1ый и 3ий) провода на потенциометре.

3) Собрать техническую конструкцию “руки”, название “рука” звучит конечно громко, но главное чтобы отличалось от “плоттера”. Для этого:

  •  Обзавелся макетной платой и горсткой проводов из витой пары, на оба конца провода я припаял ножки от старых электронных компонентов, в моем случае я пожертвовал конденсаторами.
  • Выпилил из гетинакса, найденном на помойке радиозавода в 90-х, “плечо” и “предплечье”, их длина 80мм, а расстояние от крепления к серве до другого крепления и стержня 50мм.
  • Для выведения каракуль сначала использовал стержень от гелевой ручки, но за тонкой линией сложно было скрыть мелкие подёргивания серв, остановился на варианте с фломастером.
  • Закрепил первую “серву” в металлической банке. Всё, конструкция готова, но к сожалению без программной начинки она только немного вздрагивает при подаче питания на Ардуину.

4) Программирование:

  1. Как полагается, на бумажке, я вывел две небольшие формулы определения углов поворота для “серв” по заданной координате (X,Y). Точкой отсчета (0;0) — служит крепление плеча к первому сервоприводу. 
  2. После череды экспериментов, я понял, что до конца моей задумки еще далеко, а сервоприводы, с каждым моим багом, всё страдали и страдали от бестолковых значений переменных. Поэтому было принято решение писать сначала визуализированную модель в graphics.h старого доброго BorlandC. Кому интересно, что я там свизуализировал, пишите лично.
  3. Теперь, уже не опасаясь за сохранность имущества я продолжал писать код. С помощью миллиметровой бумаги откалибровал систему определения координат и перешел к рисованию прямых линий, так как задумывалось именно линиями создавать шрифт для букв. Выглядит это так:
     //Процедура для проведения линии из точки (x,y) в точку (x1,y1)
    void ServoLine::PrintLine(double x, double y, double x1, double y1 , int A, int C){
            int i=0;
            int r1=50,r2=50;
            double a,b;
            a=(x1-x)/(A);
            b=(y1-y)/(A);
    
            while(i<=A){
                x=x+a;
                y=y+b;
                i++;
                servo1.attach(10); // Servo1 присоединен к 10 выводу
                servo2.attach(9);  // Servo2 присоединен к 9 выводу
    
                servo2.writeMicroseconds(FindBeta(x,y,r1,r2)*8.88889+700);
                servo1.writeMicroseconds(FindAlpha(x,y,r1,r2)*8.88889+700);
              delay(C);
            }
        }
  4. Дальше я задался вопросом: ”Как бы оригинально разместить слова?”, придумал, что пользователем будет задаваться середина и угол наклона слова, что в итоге превратилось только в угол наклона. Вот и здорово, нечего лишними вводными данными мозг людям пудрить.
  5. Думал, как не изобретать велосипед и с помощью FreeType использовать метод вывода векторного текста на экран, но не хватило терпения разобраться в структуре библиотек шрифтов. В итоге написал собственную библиотеку Alphabet.h, которая создаёт шаблон из точек, а я уже по этим точкам строил прямые для каждой латинской буквы.
     
  6.  // Печать буквы "А"
            void Alphabet::print_A (double X00, double Y00,int V,int S) {
            // V - кол-во точек в 1 прямой
            // S - время ожидания между прорисовкой точек
            ServoLine1.PrintLine(X00,Y00,X12,Y12,V,S );
            ServoLine1.PrintLine(X12,Y12,X24,Y24,V,S );
            ServoLine1.PrintLine(X24,Y24,X32,Y32,V,S );
            ServoLine1.PrintLine(X32,Y32,X12,Y12,V,S );
            ServoLine1.PrintLine(X12,Y12,X32,Y32,V,S );
            ServoLine1.PrintLine(X32,Y32,X40,Y40,V,S );
        }
    
  7. Написав цикл по считыванию символов, столкнулся с задачей: “Как же мне не сравнивать каждый ASKII-код символа IF-ом, а сделать сразу, чтобы считанная буква воспринималась функцией?”. Тут я полез задавать вопросы на ГИК форумы, пока ожидал на них регистрации, на авось понадеялся и выложил свой вопрос на “Вопрос и ответ” от Google, не успело пройти 15мин, проблема была решена массивом указателей на функции.
     
  8.  void (Alphabet::*fArray[26])(double X00, double Y00,int V ,int S)=
      {
         &Alphabet::print_A, &Alphabet::print_B, &Alphabet::print_C,
         &Alphabet::print_D, &Alphabet::print_E, &Alphabet::print_F,
         &Alphabet::print_G, &Alphabet::print_H, &Alphabet::print_I, etc...
      };
    


  9. Не буду описывать, как создавал библиотеки, об этом хорошо написано на сайте. Скажу одно, что создавал их не зря, так как код уменьшился с 600 строк до 60, а это визуально приятней! Правда, созданием библиотек я увеличил вес скетча на 2Кб, 6% — ощутимо!

Компиляция прошла успешно! Боялся за память на Arduino и не зря, несмотря на то что в Uno 32Kb, скетч размером больше 29 не пройдет, так как 3Kb заняты загрузчиком:

Binary sketch size: 29972 bytes (of a 32256 byte maximum)

Немного переписав букву ”R” через “P”, и “Q” через “O”, уменьшил вес и все заработало как надо!

Binary sketch size: 28468 bytes (of a 32256 byte maximum)

Исходники библиотек качать ОТСЮДА >> "Alphabet.h", "Alphabet.cpp", "ServoLine.h", "ServoLine.cpp" и сам скетч "robo_arm.pde"

 

***ВИДЕО***



5) Финансовые затраты небольшие, всё заказывал на ebay.com: “Arduino Uno”(~30$) + 2x “Micro Servo SG90”(~3$) Итого: 36$ + риски, мало ли “Почта России” не донесёт! Макетную плату мне одолжили, она кое-где идет в комплекте с Arduino. Плата освобождает от пайки, но и без неё легко можно обойтись.

6) Вывод: Получился интересный девайс, которым можно: удивить гостей, портить похабными надписями важные документы, пугать кота, подписывать документы (добавив предварительно свою подпись в библиотеку), рисовать. Я познакомился с Arduino, увидел много креативных идей, понял, что надо бы изучить Assembler. Если не потеряю интерес, то закажу Arduino Ethernet Shield и сделаю, чтобы “рука” писала Твиттер-имя человека приславшего мне Reply.

7) Если бы я начинал что-то подобное сейчас, чтобы сделал по-другому?

1) Не парился бы с графической моделью руки в graphics.h, а использовал бы “Google Sketchup + plugin SketchyPhysics
2) Для создания конструкции модели использовал бы “поликапролактон”.


Надеюсь, мой опыт окажется кому-то полезным, ведь это так здорово, когда своим трудом и идеями оживляешь "неоживляемое"! Удачи!


0 комментариев на «“Arduino: Робо-рука на двух сервоприводах”»

  1. Здорово! Еще-бы серву или что-нибудь электромагнитное для отрыва от бумаги…

    Вспомнилось видео часов на ардуине. На куске оргстекла маркером рисовались цифры. Устаревшие цифры автоматически стирались проходом «дворника» с мягкой тряпочкой. Корявенько, но эффектно!

    • Думал, но замысел был научиться Ардуиной пользоваться! Сейчас планирую чем-нибудь дельным заняться, рука конечно здорово, но толку от неё не много)

      Часы видел, меня тоже порадовали, но всё же для написания легче сделать плоттер, там кажется он и был!

    • Да, да. Плоттер. Ваш вариант занятнее. Удачи!

  2. Весьма достойно.

    Но ИМХО, код крайне расточительный.
    Можно было составить алгоритм гораздо компактней…

    Но механика мне очень нравится.

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

Добавить комментарий

Arduino

Что такое Arduino?
Зачем мне Arduino?
Начало работы с Arduino
Для начинающих ардуинщиков
Радиодетали (точка входа для начинающих ардуинщиков)
Первые шаги с Arduino

Разделы

  1. Преимуществ нет, за исключением читабельности: тип bool обычно имеет размер 1 байт, как и uint8_t. Думаю, компилятор в обоих случаях…

  2. Добрый день! Я недавно начал изучать программирование под STM32 и ваши уроки просто бесценны! Хотел узнать зачем использовать переменную типа…

3D-печать AI Android Arduino Bluetooth CraftDuino DIY IDE iRobot Kinect LEGO OpenCV Open Source Python Raspberry Pi RoboCraft ROS swarm ИК автоматизация андроид балансировать бионика версия видео военный датчик дрон интерфейс камера кибервесна конкурс манипулятор машинное обучение наше нейронная сеть подводный пылесос работа распознавание робот робототехника светодиод сервомашинка собака управление ходить шаг за шагом шаговый двигатель шилд

OpenCV
Робототехника
Будущее за бионическими роботами?
Нейронная сеть - введение