CUSTOMELECTRONICS.RU
Информационно-учебный блог о разработке электроники
Эл. почта: info@customelectronics.ru

Робо-рука. Часть 3. Электроника и программирование

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

Электроника

Для расширения аудитории и упрощения работы с манипулятором мы использовали Arduino, а точнее нашу Arduino-совместимую плату EduBoard. Также для подключения сервоприводов мы сделали простенький шилд. На нем установлен разъем для питания двигателей, PLS-контакты для сервоприводов, четыре резистора и две кнопки. Питание осуществляется от блока на 5В, 3А, но если планируются серьезные нагрузки одновременно по всем осям, то стоит увеличить нагрузочную способность БП до 5А.

Шилд для манипулятора

Шилд для манипулятора

На самом деле все это можно собрать просто на макетке. Резисторы и кнопки нужны только для упрощения разработки в некоторых ситуациях. Без них вполне можно обойтись. Исходный файл проекта в Sprint Layout можно скачать в конце первой статьи цикла.
EduBoard вместе с шилдом, установленные на манипулятор выглядят так:

EduBoard с щилдом для подключения двигателей

EduBoard с щилдом для подключения двигателей

Программирование

Всего мы подготовили три разных скетча для работы манипулятора в трех режимах:

Самый интересный из них — это управление по командам с компьютера. uFactory сделали очень удобное приложение для управления рукой, которое можно скачать либо на их сайте, либо опять же в первой части моего цикла статей. Это приложение достаточно просто скачать и загрузить следующий скетч для Arduino:

#include <Arduino.h>
#include <Servo.h>

void readSerial(void);
void dataToNormal(void);

int data[9];
int value[4];

Servo Stretch;
Servo Rotation;
Servo Height;
Servo HandRot;
Servo Grip;

const int stretchMin = 80;
const int stretchMax = 150;
const int stretchNormal = 146;

const int rotationMin = 16;
const int rotationMax = 170;
const int rotationNormal = 80;

const int heightMin = 35;
const int heightMax = 90;
const int heightNormal = 70;

const int handrotMin = 20;
const int handrotMax = 160;
const int handrotNormal = 116;

const int gripMin = 115;
const int gripMax = 157;
const int gripNormal = 140;

int grip = gripNormal;

void setup(){
    Stretch.attach(8);
    Rotation.attach(9);
    Height.attach(10);
    HandRot.attach(11);
    Grip.attach(12);

    Grip.write(gripNormal);
    Serial.begin(9600);
}

void loop(){
    readSerial();
    dataToNormal();

    if ( (value[0] <= stretchMax) & (value[0] >= stretchMin) ){
        Stretch.write(value[0]);
    }

    if ( (value[1] <= rotationMax) & (value[1] >= rotationMin) ){
        Rotation.write(value[1]);
    }

    if ( (value[2] <= heightMax) & (value[2] >= heightMin) ){
        Height.write(value[2]);
    }

    if ( (value[3] <= handrotMax) & (value[3] >= handrotMin) ){
        HandRot.write(value[3]);
    }

    if ( (data[8] == 0x01) & (grip <= gripMax) ) {
        Grip.write(grip++);
        data[8] = 0;
    }

    if ( (data[8] == 0x10) & (grip >= gripMin) ){
        Grip.write(grip--);
        data[8] = 0;
    }

}

void readSerial(){
    if (Serial.available() == 11)                 // one packet contains 11 bytes
            if (Serial.read() == 0xFF)            //
                if (Serial.read() == 0xAA){       //
                    data[0] = Serial.read();      // Flag Rotation 0x00 or 0xFF
                    data[1] = Serial.read();      // Rotation
                    data[2] = Serial.read();      //
                    data[3] = Serial.read();      // Stretch
                    data[4] = Serial.read();      // Flag Height 0x00 or 0xFF
                    data[5] = Serial.read();      // Height
                    data[6] = Serial.read();      // Flag HandRot
                    data[7] = Serial.read();      // HandRot
                    data[8] = Serial.read();
                    data[9] = Serial.read();      
                }
}

void dataToNormal(){
    // stretch
    value[0] = stretchNormal - data[3];
    //rotation
    value[1] = data[0] - data[1] + rotationNormal;
    //height
    value[2] = data[4] - data[5] + heightNormal;
    //handrot
    value[3] = data[6] - data[7] + handrotNormal;
}

Терминальная программа изменяет пять параметров. При движении мыши по поверхности изменяется положение манипулятора в плоскости XY. Вращение колесика — изменение высоты. ЛКМ/ПКМ — сжать/разжать клешню. ПКМ + колесико — поворот захвата. На самом деле очень удобно. Программа отправляет в COM-порт 11 байт. Первый из них всегда 0xFF, второй 0xAA и некоторые из оставшихся — сигналы для сервоприводов. Далее эти данные нормализуются и отдаются на отработку двигателям. У нас сервоприводы подключены к цифровым входам/выходам 9-12, но это легко можно поменять.
При желании можно написать любой терминальный софт, который будет общаться с манипулятором по такому протоколу. Можно создавать макросы, распознавать объекты по камере. Все ограничено только фантазией!
В конце первой статьи цикла вы сможете скачать и этот скетч, и скетч для работы манипулятора в демо-режиме и по командам с резисторов и кнопок. Во второй статье цикла подробно изложен процесс сборки манипулятора.
Ссылки на остальные статьи цикла:
Робо-рука. Часть 1. Описание (все ссылки на фалы для скачивания здесь)
Робо-рука. Часть 2. Инструкция по сборке

UPD

Также обратите внимание, что для управления манипулятором с компьютера можно использовать наш тестер сервоприводов и программу ServoStudio.

Мы будем очень рады, если вы поддержите наш ресурс и посетите магазин наших товаров shop.customelectronics.ru.

Метки: , , , , , , Просмотров: 13709