кафедра
    Электротехники и прецизионных
электромеханических систем
Манипулятор «рука»

Задача: Разработать систему дистанционного управления многозвенным манипулятором типа «рука».

Описание первоначального устройства
























Изначально манипулятор Robotic Arm Edge фирмы OWI KIT управлялся проводным пультом управления,
который менял полярность питания каждого мотора в звеньях устройства, т.е. представлял из себя набор
механических реле.



















Общая схема создаваемой системы управления

 























Механические реле заменяются драйверами L293DNE, управляемые логическими слаботочными сигналами от
микроконтроллера и питаемые внешним источником питания. Пользовательские команды отправляются с ios
устройства посредствам беспроводной сети wifi в виде сообщений протокола OSC (Open Sound Control),
который имеет простую структуру. Затем сообщения обрабатываются на серверной части, установленной на
компьютере, и преобразуются в другой формат данных, удобный для передачи в микроконтроллер.

Исходя из выбранной схемы, возникают две главные задачи в плане программирования:

1.Обеспечение передачи команд с пользовательского устройства (клиента) на персональный компьютер (сервер) и передача их на микроконтроллер.
2.Обеспечение связи между микроконтроллером и компьютером для получения команд и последующая
интерпретация команд в управляющие сигналы на драйверы.

Клиент отправляет сообщения на сервер по протоколу OSC. Приложение на сервере в свою очередь
непрерывно опрашивает один из портов, на который должны поступить команды и при их получении передаёт
соответствующее команды на arduino. Серверное приложение написано на языке processing.

// импорт библиотеки для работы с COM-портом
import processing.serial.*;
// импорт библиотек для работы с протоколом OSC и работы с сетью
import oscP5.*;
import netP5.*;
Serial s;
OscP5 oscP5;
NetAddress myRemoteLocation;
// два управляющих байта, отправляемые в arduino
byte sendBytes[]={0, 0};
// начальная инициализация
void setup() {
  // установка работы COM-порта
  s = new Serial(this, "COM5", 9600);
  size(400,400);
  // создание объекта OscP5 для прослушивания порта 12000 и обработки приходящих сообщений
  oscP5 = new OscP5(this, 12000);
}
void draw() {
  background(0); 
}
// обработка сообщений, инициализируемая методом oscEvent
void oscEvent(OscMessage theOscMessage) {
  // получение сообщения
  String adr = theOscMessage.addrPattern();
  // выделение значения параметра
  int value = int(theOscMessage.get(0).floatValue());
  // выделение из сообщения номера двигателя
  int motor = adr.charAt(adr.length()-2)-48;
  // выделение из сообщения направления поворота
  int dir = (int(adr.charAt(adr.length()-1) == \'R\')+1)*value;
  // вывод сообщения в консоль (для отладки)
  println(adr+" "+value);
  print((motor-1)*2+dir);
  println(value);
  // отдельная обработка управления светодиодом
  if(adr.length() == 6) {
    upr[5] = byte(value);
  } else {
    upr[motor-1] = byte(dir);
  }
  // формирование двух управляющих байтов
  sendBytes[0] = 0;
  for(int i=0; i<4; i++)
    sendBytes[0] = (byte)(sendBytes[0]|(upr[i] << 2*i));
  sendBytes[1] = upr[5-1];
  sendBytes[1] |= (upr[6-1] << 2);
  // запись управляющих байтов в COM-порт (arduino)
  s.write(sendBytes);
  println(sendBytes);

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

// установка соответствий между выходами платы и переменными
int m1EN  = 13;
int m1DIR = 12;
int m2EN  = 11;
int m2DIR = 10;
int m3EN  = 9;
int m3DIR = 8;
int m4EN  = 7;
int m4DIR = 6;
int m5EN  = 5;
int m5DIR = 4;
int LED_EN= 3;
int byteNum = 0;
// принимаемые управляющие байты
byte incomingBytes[2];
int controlIndex[] = {m1DIR, m2DIR, m3DIR, m4DIR, m5DIR, LED_EN};
byte control[6];
// начальная инициализация
void setup() {
  // включение серийного порта
  Serial.begin(9600);
  // настройка управляющих пинов как цифровых и выходных
  for(int i=0; i<6; i++)
    pinMode(controlIndex[i], OUTPUT);
  pinMode(m1EN,  OUTPUT);
  pinMode(m2EN,  OUTPUT);
  pinMode(m3EN,  OUTPUT);
  pinMode(m4EN,  OUTPUT);
  pinMode(m5EN,  OUTPUT);
}

// главный цикл
void loop() {
  // если получены данные по серийному порту
  while (Serial.available()) {
    // побайтное чтение
    incomingBytes[byteNum] = (byte)Serial.read();
    byteNum++;
  }
  // если прочитаны оба байта
  if (byteNum > 1){
    // выделение управляющих сигналов для каждого двигателя из полученных байт и формирование управляющего вектора control
    for(int i=0; i<4; i++) {
      control[i] = (incomingBytes[0] >> i*2)&3;
    }
    control[5-1] = incomingBytes[1]&3;
    control[6-1] = (incomingBytes[1] >> 2)&1;
    // обновление состояний управляющих выходов в соответствии с управляющим вектором
    reLoadStatus();
    byteNum = 0;
  }
}
// обновление состояний управляющих выходов в соответствии с управляющим вектором
void reLoadStatus() {
  // каждый двигатель находится в одном из трёх состояний
  for(int i = 0; i<5; i++)
    switch (control[i]) {
      // включен и вращается вправо
      case 1:
        digitalWrite(controlIndex[i], LOW);
        digitalWrite(controlIndex[i]+1, HIGH);
        break;
      // включен и вращается влево
      case 2:
        digitalWrite(controlIndex[i], HIGH);
        digitalWrite(controlIndex[i]+1, HIGH);
        break;
      // выключен
      case 0:
        digitalWrite(controlIndex[i]+1, LOW);
        break;
    }
  // состояния светодиода обрабатывается отдельно
  if(control[6-1] == 1)
    digitalWrite(controlIndex[6-1], HIGH);
  else
    digitalWrite(controlIndex[6-1], LOW);

 Силовая часть представлена на следующей схеме
























Способы подключения двигателя к драйверу описаны в datasheet к L293DNE.




















Общий вид




















Три драйвера L293DNE
























Соединение Arduino и драйверов

Видео


 выполнил студент Плотицын А 4 курс (2011 год )

 
 
 
 
Кронверкский пр.,49
197101, г. Санкт-Петербург
тел. (812) 233-83-36
Служебная часть © 2010 ЭТиПЭМС