Как уже отмечалось в статье про разборку робота-пылесоса iRobot Roomba,
у данных роботов, выведен консольный разъём mini-DIN-7, через который можно управлять роботом.
Узнать его распиновку можно в документах iRobot® Roomba® Serial Command Interface (SCI) Specification
или
iRobot® Roomba® Open Interface (ROI) Specification.
Распиновка консольного разъёма 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 * -------------- * 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* 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
http://en.wikipedia.org/wiki/Mini-DIN_connector
http://ru.wikipedia.org/wiki/S-Video
iRobot® Roomba® Serial Command Interface (SCI) Specification
По теме
Turtlebot - первые шаги
Новогоднее исследование ADSL-роутера на базе Linux - 0x6 - последовательный порт
Автор: Vladimir (noonv), 2011-2012
Эксклюзивно для robocraft.ru
копирование на другие ресурсы и публикация
без разрешения автора запрещены.
0 комментариев на «“Управление роботом-пылесосом iRobot Roomba с помощью Arduino”»
Здорово!
Вчера собрали таки Тёртлбота, уже опробовали Follow Me. Всё работает прекрасно.
На днях выложим новую статью.
супер! поздравляю и жду статью 🙂
Нужно сделать веб-интерфейс управления роботом + веб-камеру, и за 5 рублей продавать доступ — убери мою комнату и заплати за это деньги! :)))
:)))
Если серьёзно, мы думали об этом, только без уборки. Это, по сути, робот телеприсутсвтия. Его уже сейчас можно реализовать при помощи ROS через ssh. В ближайшем будущем, думаю, сделаем нечто подобное.
Доброго дня суток! А кто подскажет, возможно ли управление более старой моделью румбы, у меня roomba floor vac и консольного разъема на ней нет (( но на мамке есть свободный 4 х контактный разъем, только хз как подключить ((
Спасибо сделал почти по вашему примеру.
Дополняю документацией irobot.lv/uploaded_files/File/iRobot_Roomba_500_Open_Interface_Spec.pdf
и на моей iroomba 650 сразу правильно работает на 115200,
если интересно могу выложить свой код для ардуины, и код для esp8266 для управления удаленно по телнету\putty
Документация на русском
Это все здорово, Но все мимо кассы.
По сути вопроса: для roomba единственное что надо сделать — это изменить алгоритм уборки. Смотрю как он хаотично носиться и тыкается по углам и думаю что с разработчиками что то явно не так. Для построения виртуальной карты помещения даже зрения не надо. Сначала построить периметр а потом пылесосить внутри этого периметра постепенно сдвигаясь к центру помещения. Препятствия тоже можно на этой карте перемещениями вычислить. И неплохо бы было хранить эту карту в памяти пылесоса.
1.лет 6 назад было видео и тестирование, где показали что такой рандомный метод чистки лучше, но возможно все подстроили что бы оправдаться.
2.энкодеры накапливают ошибку, стукаться об стены что бы найти ее еще больше копит ошибку, + одно колесо может проехать по чему то не ровному и тп. мой маленький опыт показал что энкодеров мало(
3. хранить карту нет смысла, т.к. в следующий раз пылесос может начать не со своего прежнего места, или обтановка в комнате может изменится.
ps мой румба работает после нескольких разборок\сборок уже больше 5 лет(с перерывами), один раз только аккум с али заказывал. и текущим алгоритмом доволен