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

Управление роботом-пылесосом iRobot Roomba с помощью Arduino

Как уже отмечалось в статье про разборку робота-пылесоса iRobot Roomba,
у данных роботов, выведен консольный разъём mini-DIN-7, через который можно управлять роботом.
консольный разъём mini-DIN-7, через который можно управлять роботом

Узнать его распиновку можно в документах iRobot® Roomba® Serial Command Interface (SCI) Specification
или
iRobot® Roomba® Open Interface (ROI) Specification.

Распиновка консольного разъёма iRobot Roomba
Распиновка консольного разъёма iRobot Roomba
Как видим, на разъём выведены 2 линии питания от батареи робота, две линии земли и
три информационных линии, работающие на TTL уровнях (5В):
Rx, Tx, DD.
Первые две линии — это линии приёмника и передатчика UART, которые можно просто
подключать к линиям передатчика и приёмника нашего контроллера или через
соответствующий преобразователь уровней (например, MAX232) к последовательному порту ПК, а линия DD используется чтобы «разбудить» робота или изменить скорость работы последовательного соединения.
Её можно подключить к любому цифровому пину контроллера или, через преобразователь MAX232, к линии RTS последовательного порта ПК.

Принципиальная схема переходника на базе популярной микросхемы преобразователя RS232-TTL — MAX232


Обратите внимание, что питание микросхемы преобразователя осуществляется от батареи робота, после преобразования его к 5В при помощи интегрального стабилизатора.

В простом варианте, можно обойтись без такого преобразователя и подключить контроллер Arduino прямо к консольному разъёму робота, обычными проводками.
Arduino Pin 0 (Rx)  ——> Roomba Pin 4 (Tx)
Arduino Pin 1 (Tx)  ——> Roomba Pin 3 (Rx)
Arduino Pin 2  ——> Roomba Pin 5 (Device Detect)
Arduino Gnd ——> Roomba GND Pin 6/7

Даже питание на контроллер Arduino можно взять от батареи робота, выведенной на этот разъём, главное, чтобы оно проходило через преобразователь питания контроллера:
Arduino Vin ——> Roomba +16V Pin 1/2

Однако, всё же намного удобнее собрать переходник.
Для этого просто возьмём протошилд, набор UART(TTL)->RS232 на микросхеме MAX232 и набор интегрального стабилизатора на базе MC7805.
У меня разъёма для mini-DIN-7 под рукой не оказалось, но от какой-то видеокарты нашёлся разъём под S-Video — mini-DIN 9-pin

— как видите, он вполне подходит, учитывая что два центральных пина просто зайдут в центральное углубление разъёма на роботе.

Остаётся только расковырять разъём и припаять к нему 5-жильный шлейф, а на другом конце шлейфа можно использовать BLS-гнездо с контактами 2.54мм. Т.о., остаётся на протошилде запаять гребёнку пинов PLS, в которую будет удобно подключаться наш шлейф от робота.
я сделал такую распиновку:
1. Vcc
2. Rx
3. Tx
4. DD
5. GND

Так же, я добавил дополнительные джамперы на схему, чтобы этот шилд можно было использовать не только для общения роботом и ПК, но и для общения между роботом и Arduino, или Arduino и ПК через последовательный порт:
при его подключении к контроллеру требуется нуль-модемное соединение: приёмник контроллера к передатчику робота, а при общении контроллера и ПК через преобразователь уровней — прямое.
А кроме того, добавил джампер, чтобы в варианте шилда, питать контроллер Arduino через стабилизатор шилда (т.е. 5V заводятся через джампер на соответствующий пин питания 5V).

Уровни RS-232 выведены на стандартный 9-пиновый разъём (как на компьютерных материнских платах), поэтому можно использовать стандартный переходник от компьютера


Однако, у таких переходников на выходе разъём типа DB-9M (Male — по-нашему — «папа»), а у переходников USB-COM разъём такой же, а значит, чтобы их соединить нужно использовать два разъёма DB-9F (Female — по-нашему — «мама»), напрямую соединённые между собой (я использовал удобнейший провод типа МГТФ).
Т.е. соединяем пины 2 (Tx), 3 (Rx), 5 (GND) и 7(RTS).
Обычно, достаточно всего 3 линии — Tx, Rx, GND. Линия RTS нужна только чтобы управлять линией DD (Device Detect) робота.

Вот что получилось:
Подключение к ПК


Подключение старой CraftDuino к роботу



С подключением разобрались. Осталось узнать как управлять роботом.
Нет ничего проще! В том же iRobot® Roomba® Open Interface (ROI) Specification приводится полное описание взаимодействия с роботом.
Управление идёт посылкой нужных команд.

Формат ROI (Roomba Open Interface):
[байт_кода_команды] <опциональные_байты_параметров>


Т.е., каждая команда задается одним байтом кода операции. Также, некоторые команды должны сопровождаться дополнительными байтами данных. Значение байтов данных оговаривается для каждой отдельной команды.
Roomba не будет отвечать на ROI-команды, когда она спит. Поэтому, робота сначала нужно «разбудить», установив на линии DD низкий уровень на 500 мс.
// будим робота
  digitalWrite(ddPin, HIGH);
  delay(100);
  digitalWrite(ddPin, LOW);
  delay(500);
  digitalWrite(ddPin, HIGH);
  delay(2000);

После пробуждения робота, на нём загорятся светодиодная подсветка кнопок и он будет готов принимать команды.
Первым делом, нужно послать команду Start.

Start
Код команды (Command opcode): 128
Число байт данных: 0
Запускает ROI.
Команда Старт, должна быть отправлена до любых других команд ROI.
Эта команда устанавливает ROI в пассивный режим (passive mode).
Пишем в порт: [128]
Код:
Serial.write(128);


Далее, так как мы хотим поуправлять нашим роботом-пылесосом, нужно заслать команду Control

Control
Код команды: 130
Число байт данных: 0
Позволяет пользователю управлять Roomba. Эта команда должна быть направлена
после команды Start и перед любой командой контроля ROI.
ROI должен быть в пассивном режиме, чтобы принять эту
команду.
Эта команда устанавливает ROI в пассивный режим (passive mode).
Пишем в порт: [130]
Код:
Serial.write(130);


Всё — можно рулить :)
Для упраления движением робота, используется команда Drive

Drive
Код команды: 137
Число байт данных: 4
Управляет колёсами Roomb-ы.
Принимает в качестве параметров 4 байта данных, которые интерпретируются, как два знаковых 16-битных значения.
Первые два байта задают среднюю скорость движения колеса в миллиметрах в секунду (mm/s).
Вторые два байта задают радиус в миллиметрах, на который Roomba должна повернуться.
Большой радиус позволяет роботу двигаться прямее, а маленький — поворачивать.
Положительная скороть и радиус приведут к движению прямо и влево.
При отрицательном радиусе, робот будет поворачивать вправо.
Особые случаи для поворота робота на месте или движении прямо:
Байты данных 1 и 2: Скорость (-500 – 500 mm/s)
Байты данных 3 и 4: Радиус (-2000 – 2000 mm)
Специальный случай: Прямо = 32768 = hex 8000
Повернуть на месте направо (clockwise) = -1
Повернуть на месте налево (counter-clockwise) = 1

Эта команда изменяет режим работы робота.
Пишем в порт: [137] [Velocity high byte][Velocity low byte] [Radius high byte][Radius low byte]

Пример:
Чтобы двигаться назад со скоростью -200 mm/s и поворачивать с радиусом 500mm,
следую отправить в порт следующую последовательность байт:
[137] [255] [56] [1] [244].
Скорость = -200 = hex FF38 = [hex FF] [hex 38] = [255] [56]
Радиус = 500 = hex 01F4 = [hex 01] [hex F4] = [1] [244]
Код:

  Serial.write(137);
  Serial.write(0xFF);
  Serial.write(0x38);
  Serial.write(0x01);
  Serial.write(0xF4);


Остаётся запрограммировать наш контроллер для выдачи подобных команд.
Возьмём готовый пример скетча для книги Hacking Roomba — RoombaBumpTurn.pde
и подредактируем его, чтобы робот двигался 2 секунды двигался прямо, а затем одну секунду поворачивал направо.
Так как, код скетча предназначен для версии Arduino IDE < 1.0, то его придётся подправить.
Например, в коде используется
Serial.print(137, BYTE);
, которого больше нет в Arduino IDE > 1.0.
Эти методы нужно просто заменить на
Serial.write(137)


RoombaBumpTurn-my.ino
/*
 * RoombaBumpTurn 
 * --------------
 * Implement the RoombaComm BumpTurn program in Arduino
 * A simple algorithm that allows the Roomba to drive around 
 * and avoid obstacles.
 * 
 * Arduino pin 0 (RX) is connected to Roomba TXD
 * Arduino pin 1 (TX) is connected to Roomba RXD
 * Arduino pin 2      is conencted to Roomba DD
 * 
 * Updated 20 November 2006
 * - changed Serial.prints() to use single print(v,BYTE) calls instead of 
 *    character arrays until Arduino settles on a style of raw byte arrays
 *
 * Created 1 August 2006
 * copyleft 2006 Tod E. Kurt <tod@todbot.com>
 * http://hackingroomba.com/
 */

int rxPin = 0;
int txPin = 1;
int ddPin = 2;
int ledPin = 13;
char sensorbytes[10];

#define bumpright (sensorbytes[0] & 0x01)
#define bumpleft  (sensorbytes[0] & 0x02)

void setup() {
//  pinMode(txPin,  OUTPUT);
  pinMode(ddPin,  OUTPUT);   // sets the pins as output
  pinMode(ledPin, OUTPUT);   // sets the pins as output
  Serial.begin(57600);

  digitalWrite(ledPin, HIGH); // say we're alive

  // wake up the robot
  digitalWrite(ddPin, HIGH);
  delay(100);
  digitalWrite(ddPin, LOW);
  delay(500);
  digitalWrite(ddPin, HIGH);
  delay(2000);
  // set up ROI to receive commands  
  Serial.write(128);  // START
  delay(50);
  Serial.write(130);  // CONTROL
  delay(50);
  digitalWrite(ledPin, LOW);  // say we've finished setup
}

void loop() {
  digitalWrite(ledPin, HIGH); // say we're starting loop
  updateSensors();
  digitalWrite(ledPin, LOW);  // say we're after updateSensors
#if 0
  if(bumpleft) {
    spinRight();
    delay(1000);
  }
  else if(bumpright) {
    spinLeft();
    delay(1000);
  }
#endif
  goForward();
#if 1
  delay(2000);
  spinRight();
  delay(1000);
#endif
}

void goForward() {
  Serial.write(137);   // DRIVE
  Serial.write((byte)0x00);   // 0x00c8 == 200
  Serial.write(0xc8);
  Serial.write(0x80);
  Serial.write((byte)0x00);
}
void goBackward() {
  Serial.write(137);   // DRIVE
  Serial.write(0xff);   // 0xff38 == -200
  Serial.write(0x38);
  Serial.write(0x80);
  Serial.write((byte)0x00);
}
void spinLeft() {
  Serial.write(137);   // DRIVE
  Serial.write((byte)0x00);   // 0x00c8 == 200
  Serial.write(0xc8);
  Serial.write((byte)0x00);
  Serial.write(0x01);   // 0x0001 == spin left
}
void spinRight() {
  Serial.write(137);   // DRIVE
  Serial.write((byte)0x00);   // 0x00c8 == 200
  Serial.write(0xc8);
  Serial.write(0xff);
  Serial.write(0xff);   // 0xffff == -1 == spin right
}
void updateSensors() {
  Serial.write(142);
  Serial.write(1);  // sensor packet 1, 10 bytes
  delay(100); // wait for sensors 
  char i = 0;
  while(Serial.available()) {
    int c = Serial.read();
    if( c==-1 ) {
      for( int i=0; i<5; i ++ ) {   // say we had an error via the LED
        digitalWrite(ledPin, HIGH); 
        delay(50);
        digitalWrite(ledPin, LOW);  
        delay(50);
      }
    }
    sensorbytes[i++] = c;
  }    
} 

Вот что у меня получилось:

Чтобы остановить робота — его нужно приподнять от пола ;)

Красота! Что теперь можно с ним сделать? Да что угодно! Теперь роботу можно добавить «интеллекта» и управлять им с обычного ПК или какого-нибудь одноплатника типа BeagleBoard или Raspberry Pi. Превратить его в TurtleBot-а или что-нибудь другое. А можно использовать Bluetooth-модуль или Wi-Fi роутер под OpenWRT и управлять роботом дистанционно. Масса идей и простор для фантазии!
а у Вас какие есть идеи? :)


PS. Уважаемый mishmash несколько опередил меня и выложил свои заметки по управлению Roomb-ой, так что с одной стороны эта статья выступает в роли дублирования материала и я уже не хотел её публиковать, но с другой стороны тема настолько интересная и захватывающая, что, думаю, оно того стоит.
Как звучит: «хакинг бытовых роботов при помощи Arduino»!
Помните в старом «Судья Дредд» бывший преступник «взламывал» роботов? Да… будущее уже наступило ;)


продолжение следует...

Ссылки:
Build a Roomba Serial Tether
Add scheduling to Roomba 532 via Arduino
en.wikipedia.org/wiki/Mini-DIN_connector
ru.wikipedia.org/wiki/S-Video
iRobot® Roomba® Serial Command Interface (SCI) Specification

По теме:
Turtlebot — первые шаги
Новогоднее исследование ADSL-роутера на базе Linux — 0x6 — последовательный порт

Автор: Vladimir (noonv), 2011-2012

Эксклюзивно для www.robocraft.ru
копирование на другие ресурсы и публикация
без разрешения автора запрещены.
  • +4
  • 7 июля 2012, 17:00
  • noonv

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

RSS свернуть / развернуть
+
+2
Здорово!

Вчера собрали таки Тёртлбота, уже опробовали Follow Me. Всё работает прекрасно.
На днях выложим новую статью.
avatar

mishmash

  • 7 июля 2012, 17:11
+
+2
супер! поздравляю и жду статью :)
avatar

noonv

  • 7 июля 2012, 17:13
+
+2
Нужно сделать веб-интерфейс управления роботом + веб-камеру, и за 5 рублей продавать доступ — убери мою комнату и заплати за это деньги! :)))
avatar

lehha

  • 8 июля 2012, 18:08
+
0
:)))
Если серьёзно, мы думали об этом, только без уборки. Это, по сути, робот телеприсутсвтия. Его уже сейчас можно реализовать при помощи ROS через ssh. В ближайшем будущем, думаю, сделаем нечто подобное.
avatar

mishmash

  • 8 июля 2012, 19:29
+
0
Доброго дня суток! А кто подскажет, возможно ли управление более старой моделью румбы, у меня roomba floor vac и консольного разъема на ней нет (( но на мамке есть свободный 4 х контактный разъем, только хз как подключить ((
avatar

risc11

  • 30 мая 2016, 16:07
+
0
Спасибо сделал почти по вашему примеру.
Дополняю документацией irobot.lv/uploaded_files/File/iRobot_Roomba_500_Open_Interface_Spec.pdf
и на моей iroomba 650 сразу правильно работает на 115200,
avatar

Guron

  • 11 октября 2017, 07:22
+
0
если интересно могу выложить свой код для ардуины, и код для esp8266 для управления удаленно по телнету\putty
avatar

Guron

  • 11 октября 2017, 07:35
+
0
avatar

Guron

  • 11 октября 2017, 21:50

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