CraftDuino v2.0
  • - это CraftDuino - наш вариант полностью Arduino-совместимой платы.
  • CraftDuino - настоящий конструктор, для очень быстрого прототипирования и реализации идей.
  • Любая возможность автоматизировать что-то с лёгкостью реализуется с CraftDuino!
Просто добавьте CraftDuino!

Управление сервами с геймпада

Захотелось сделать что-то большое и интересное. Ардуина при мне, да пара серв имеется — смело в бой!
Всё большое начинается с малого и первым делом решил я попробовать поуправлять сервами, а для удобства управления геймпад приспособить.
Первым делом скетч для ардуины изготовил. Использовал библиотеку Servo и нехитрый код, который распознаёт получение строки на COM-порт (не более 200 символов).
#include <Servo.h> 

Servo myservo1;
Servo myservo2;

byte pos1 = 90;
byte pos2 = 90;

String inputString = "";
boolean stringComplete = false;

void setup() 
{ 
  myservo1.attach(9);
  myservo2.attach(8);
  Serial.begin(9600);
  inputString.reserve(200);
} 

void loop() 
{ 
  if (stringComplete) {
    pos1 = inputString[0];
    pos2 = inputString[1];
    myservo1.write(pos1);
    myservo2.write(pos2);
    delay(15);
    inputString = "";
    stringComplete = false;
  }
} 

void serialEvent() {
  while (Serial.available()) {
    char inChar = (char)Serial.read(); 
    inputString += inChar;
    if (inChar == '\n') {
      stringComplete = true;
    } 
  }
}
Передаваемая строка должна иметь формат: <байт угла для первой сервы><байт угла для второй сервы><символ конца строки "\n">. Значения, полученные в виде байтов определяют угол поворота, на который будут повёрнуты сервы. На этом этапе сервами можно управлять из «Serial Mоnitor» Arduino IDE. Надо только не забыть установить в окне монитора обработку строк «Newline».

Управлять сервами из консоли не интересно. Захотелось большего! Можно конечно использовать для этого мышь или клавиатуру, но кажется более разумным использовать геймпад. Хочется, оно конечно хочется, но как обработку данных с геймпада организовать? Можно на C# программу написать, можно ещё что-то поэксплуатировать, но нашел я, что народ для подобной обработки Processing использует (с библиотекой procontroll).

В результате получился вот такой скетч процессинга:
import processing.serial.*;
import procontroll.*;
import java.io.*;

Serial myPort;
PFont fontA;

ControllIO controll;
ControllDevice device;
ControllSlider sliderX;
ControllSlider sliderY;

byte mX;
byte mY;

void setup() 
{
  size(180, 180);
  String portName = Serial.list()[1];
  myPort = new Serial(this, portName, 9600);
  
  fontA = loadFont("Ziggurat-HTF-Black-32.vlw");
  textFont(fontA, 32);
  
  controll = ControllIO.getInstance(this);
  device = controll.getDevice("USB Gamepad ");
  device.setTolerance(0.05f);
  sliderX = device.getSlider(0);
  sliderY = device.getSlider(1);
}

void draw() {
  background(255);
  mX = byte(sliderX.getTotalValue());
  mY = byte(sliderY.getTotalValue());
  myPort.write(mX);
  myPort.write(mY);
  myPort.write("\n");
  fill(0);
  text(mX, 30, 60);
  fill(0);
  text(mY, 30, 120);
}

Пробуем! — Работает!!! :)

Дальше будем пробовать сделать из устройства что-то большее.
  • +3
  • 10 апреля 2012, 12:39
  • ZloAlien

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

RSS свернуть / развернуть
+
0
Подскажите пожалуйста как грамотно видео добавить в статью.
avatar

ZloAlien

  • 10 апреля 2012, 12:52
+
0
отлично! Вставил видео ;)
avatar

admin

  • 10 апреля 2012, 19:14
+
0
Пожалуйста, можно подробнее описать. И где скачать библиотеку procontroll?
avatar

Favorit777

  • 19 апреля 2012, 17:18
+
+1
Скачать библиотеку можно отсюда: creativecomputing.cc/p5libs/procontroll/. Как её установить зависит от версии процессинга, с которым вы собираетесь её использовать. Если требуется — я опишу как произвести установку.

Я могу подробно описать и об особенностях подключения данной сервы к ардуинине и о том как работать с Arduino через COM-порт и скетчи прокомментировать. Укажите с какими трудностями Вы столкнулись и я постараюсь более бодробно остановиться на том, что непонятно.
avatar

ZloAlien

  • 19 апреля 2012, 18:31
+
0
Компилятор Ардуино ругается на String inputString = "" пишет error: 'String' does not name a type In function 'void setup()':
In function 'void loop()':
In function 'void serialEvent()':
а Processing на шрифт: Невозможно загрузить шрифт «Ziggurat-HTF-Black-32.vlw»
avatar

ivanserov

  • 6 июня 2012, 19:27
+
0
Со шрифтом разобрался. Надо было его просто добавить в процессинг самому. Tool -> create font и добавить Ziggurat-HTF-Black-32 в строку Filename. По крайней мере сработало. Теперь ругается на «USB Gamepad ». У меня называется Logitech Extreme 3D — штурвал самолета
avatar

ivanserov

  • 6 июня 2012, 19:39
+
0
Обратите внимание, что моё устройство называется «USB Gamepad » (с пробелом на конце!!! — видать глюк разработчиков). Посмотреть, как действительно называется Ваше устройство, можно использовав примеры к procontroll (уж не помню какие именно). Там, помнится, пример был, который выводил названия всех устройств и клавиш для них, которые вообще системой видятся (клавиатура, мышь, штурвал, ...).
avatar

ZloAlien

  • 7 июня 2012, 19:20
+
0
Также обращаю внимание на то, что «сервы» в моём примере инициализированы значениями по умолчанию. Т.е. при вызове «myservo1.write(pos1);», когда pos1=0 серва постарается повернуться к нулевому углу и возможно начнёт жужжать. Произойдёт это из-за того, что выдаваемые ардуиной управляющие импульсы будут короче тех, которые минимально возможны по документации сервы (это плохо для сервы). Вам необходимо изучить документацию к серве и грамотно инициализировать её управление в ардуино.
avatar

ZloAlien

  • 7 июня 2012, 19:28
+
+1
С джойстиком разобрался. Действительно пробел там лишний :). При компиляции вышла еще одна ошибка: ArrayIndexOutOfBoundsException 1 в строке String portName = Serial.list()[1]; [1] изменил на [0] и в окошке стали появляться координаты джойстика :) А пример который определяет все подключенные устройства называется procontrol_printDevice.
avatar

ivanserov

  • 9 июня 2012, 20:37
+
+1
Я бы теперь хотел сделать так чтобы при возврате джойстика в центральное положение сервы тоже возвращались в центральное положение. Пока не могу разобраться. Опыта маловато :(
avatar

ivanserov

  • 9 июня 2012, 20:39
+
+1
вот нашел справку по ошибке www.amse.ru/courses/oopjava/07.php
avatar

ivanserov

  • 9 июня 2012, 20:48
+
+1
С ошибкой в ардуино тоже разобрался. Использовал версию 1.0.1
avatar

ivanserov

  • 9 июня 2012, 21:07
+
+1
Также нужно использовать библиотеку code.google.com/p/c328r-java/downloads/detail?name=rxtx-2.1-7-bins-r2.zip&can=2&q=
Если есть такое сообщение:
WARNING: RXTX Version mismatch
Jar version = RXTX-2.1-7
native lib Version = RXTX-2.2pre2
avatar

ivanserov

  • 9 июня 2012, 21:36
+
+1
Теперь заработало, но как-то странно:
если джойстиком повернуть до упора серву на 180°, то она потом обратно на 0° возвращается сама и так пока не отпустишь джойстик. В processing-е при этом бегут числа от 0 до 127, а потом сразу от -127 до 0 и так по кругу.
avatar

ivanserov

  • 9 июня 2012, 21:41
+
0
Тут всё печально :(((((((((((( Дело в несовместимости форматов передачи данных. Конкретнее в передаче знаковых и беззнаковых переменных. Дело в том, что переменные можно разделить на знаковые и беззнаковые — те, которые хранят только положительные числа, и те, которые могут ещё и отрицательные хранить. При этом не стоит забывать про разрядность (количество бит на одну переменную), которая у обоих переменных может быть одинакова. Объясню на примере двух типов переменных, которые можно использовать в MS Visual Studio: int8 и uint8. Первая переменная может содержать числа от -127 до 128, вторая от 0 до 255. У обоих для хранения числа (тут я могу ошибаться, но смысл верен — см. справку для MS Visual Studio) используется 8 бит, но у первой первый бит хранит не число, а признак является ли число отрицательным. Так вот, ардуинина считает, что ей приходит беззнаковое число, а процессинг работает со знаковым. Отсюда такое непонимание, каково собственно положение джойстика должно быть.
avatar

ZloAlien

  • 10 июня 2012, 10:55
+
0
Тут всё печально :(((((((((((( Дело в несовместимости форматов передачи данных. Конкретнее в передаче знаковых и беззнаковых переменных. Дело в том, что переменные можно разделить на знаковые и беззнаковые — те, которые хранят только положительные числа, и те, которые могут ещё и отрицательные хранить. При этом не стоит забывать про разрядность (количество бит на одну переменную), которая у обоих переменных может быть одинакова. Объясню на примере двух типов переменных, которые можно использовать в MS Visual Studio: int8 и uint8. Первая переменная может содержать числа от -127 до 128, вторая от 0 до 255. У обоих для хранения числа (тут я могу ошибаться, но смысл верен — см. справку для MS Visual Studio) используется 8 бит, но у первой первый бит хранит не число, а признак является ли число отрицательным. Так вот, ардуинина считает, что ей приходит беззнаковое число, а процессинг работает со знаковым. Отсюда такое непонимание, каково собственно положение джойстика должно быть.

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

Я бы теперь хотел сделать так чтобы при возврате джойстика в центральное положение сервы тоже возвращались в центральное положение.
— самому интересно такое реализовать. Если вы пришлёте мне код, который сейчас Вами написан, а также укажете модель серв, которые используете — я мог бы попробовать написать программку, которая Вашу задачу решает. Там, скорее всего, потребуется добавить в программу таймер (например, на 0,250 секунды) и при срабатывании таймера отправлять ардуинене не значение сдвига джойстика, а значение, на сколько данный сдвиг изменился.
avatar

ZloAlien

  • 10 июня 2012, 11:09
+
0
Подскажите, пожалуйста, что в конечном счёте собрать хотите?
avatar

ZloAlien

  • 10 июня 2012, 11:10
+
0
Да задача стоит в некотором смысле обычная: сделать поворотный механизм для камеры (или еще для чего-нибудь). Скетч скопировал полностью у Вас. Изменил только название джойстика и СОМ-порт. Единственное только смог добавить ось Z в Processing.
avatar

ivanserov

  • 12 июня 2012, 00:12
+
0
примет я совсем не разбирусь как изменить код для управления с клавиатуры чтобы было управление радиоуправляемой машинкой. Я эту тему уже 2 месяца изо дня в день ищу и наконец то нашел благодаря вам! Заранее спасибо!
avatar

TimofeixXx

  • 21 августа 2012, 14:16

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