使用 Arduino 和 Android 设备控制 Roomba 机器人
组件和用品
| × | 1 | ||||
![]() |
| × | 1 | |||
![]() |
| × | 1 |
应用和在线服务
|
关于这个项目

作为 2016 年 Instructables 机器人大赛的获胜者之一,我获得了 iRobot Roomba Create2 作为奖品。这是一个很棒且非常实惠的机器人开发平台,成本约为 200 美元。 Create 2 允许使用多种编程方法。首先,我将它与 Arduino 和 Android APP 一起使用来移动机器人。在第一个教程中,我将探索如何通过串行端口将 Arduino 与 Roomba 连接,以及如何控制其电机、LED 和声音。在未来的项目中,我将探索它的传感器,并使用 Raspberry Pi 将 Roomba 连接到互联网。
Bellow,一段视频,展示了我对 Roomba 机器人进行编程的第一个结果:
第 1 步:物料清单

- iRobot Create2
- Arduino UNO
- 蓝牙模块 HC-06
- 按钮
第 2 步:Roomba Create2


Roomba 是一款差速驱动机器人,有 2 个轮子和一个前脚轮。它的速度高达 500 毫米/秒,可以命令向上或向后。
对于信号指示,我们可以用四个 7 段显示器和 5 个 LED 进行计数(见图):
- 干净
- 现货
- 停靠
- 警告/检查
- 污垢/碎屑
作为内部传感器,我们有:
- 悬崖探测器(前面 4 个)
- 碰撞检测器(前面 2 个)
- 滚轮编码器
对于编程,应使用文档:iRobot® Create® 2 Open Interface (OI)。 Roomba 可以设置为 3 种模式:
被动模式:
- 在发送开始命令或任何一种清洁模式命令(例如 Spot、Clean、Seek Dock)后,OI 进入被动模式。当 OI 处于被动模式时,您可以使用任何传感器命令请求和接收传感器数据,但您不能将执行器(电机、扬声器、灯、低侧驱动器、数字输出)的当前命令参数更改为其他参数.
安全模式:让您完全控制 Roomba,但以下与安全相关的情况除外:
- 充电器已插入并通电。
- 检测车轮掉落(在任何车轮上)。
- 在向前移动(或向后移动,转弯半径小于机器人半径)时检测到悬崖。
- 如果在 OI 处于安全模式时出现上述安全相关情况之一,Roomba 会停止所有电机并恢复到被动模式。
完整模式:
- 让您完全控制 Roomba、其所有执行器,以及当 OI 处于安全模式时受限制的所有安全相关条件,因为完全模式会关闭悬崖、车轮跌落和内部充电器安全功能.
第三步:串口连接



对于 Roomba 和 Arduino 之间的通信,将使用串行端口。默认情况下,Roomba 以 115,200 波特通信,但为了与 Arduino 通信,我们将其切换为 19,200。
有两种设置 Roomba 波特率的方法:
- 在关闭 Roomba 电源时,在灯关闭后继续按住清洁/电源按钮。大约 10 秒后,Roomba 会播放一首降音调。 Roomba 将以 19,200 波特进行通信,直到处理器失去电池电量或通过 OI 明确更改波特率。
- 使用波特率更改引脚(Mini-DIN 连接器上的引脚 5)更改 Roomba 的波特率。打开 Roomba 后,等待 2 秒钟,然后将波特率更改脉冲降低 3 次。每个脉冲应该持续 50 到 500 毫秒。 Roomba 将以 19200 波特进行通信,直到处理器失去电池电量或通过 OI 明确更改波特率。
上图显示了 Arduino 应该如何连接到 Roomba Mini-DIN 连接器
第 4 步:启动 Roomba
对 Roomba 进行编程时必须做的第一件事是:
- “唤醒”机器人
- 定义模式(安全或完整)
我们可以“唤醒”它,向 Mini-DIN 引脚 5(检测设备输入)发送一个低电平脉冲,如下图所示:
void wakeUp (void){ setWarningLED(ON);数字写入(ddPin,高);延迟(100);数字写入(ddPin,低);延迟(500);数字写入(ddPin,高);延迟(2000);}
要启动 Roomba,必须始终发送 2 个代码:“启动”[128] 和模式,在我们的例子中是“安全模式”[131]。如果您想要“FULL MODE”,则应发送代码 [132]。
void startSafe(){ Roomba.write(128); //启动 Roomba.write(131); //安全模式延迟(1000);}
第 5 步:打开 LED 和显示屏


打开 LED
如介绍中所述,Roomba 有 5 个 LED:
- 电源/清洁(双色红/绿和强度控制)
- 点(绿色,固定强度)
- 停靠(绿色,固定强度)
- 警告/检查(橙色,固定强度)
- 污垢/碎片(蓝色,固定强度)
可以使用代码 [139] 控制所有 LED。要控制电源 LED,您必须向 Roomba 发送两个数据字节:“颜色”和“强度”。
颜色:
- 绿色 =0
- 橙色 =128
- 红色=255
强度:
- 低=0
- 最大=255
函数setPowerLED(byte setColor, byte setIntensity) 这样做:
void setDigitLEDs(byte digit1, byte digit2, byte digit3, byte digit4){ Roomba.write(163); Roomba.write(digit1); Roomba.write(digit2); Roomba.write(digit3); Roomba.write(digit4);}
例如,要以一半的强度打开橙色的 POWER LED,您可以调用如下函数:
setPowerLED (128, 128);
要打开剩余的 4 个 LED,必须使用以下功能:
setDebrisLED(ON);setDockLED(ON); setSpotLED(ON); setWarningLED(ON);
以上所有函数都有一个类似的代码:
void setDebrisLED(bool enable){ fragmentLED =enable; Roomba.write(139); Roomba.write((debrisLED ? 1 :0) + (spotLED ? 2 :0) + (dockLED ? 4 :0) + (warningLED ? 8 :0)); Roomba.write((byte)color); Roomba.write((byte)intensity);}
基本上区别在于:
debrisLED =enable;
必须更改启用其他 LED 中的每一个(spotLED、dockLED、warningLED ).
发送消息以显示
Roomba 有四个 7 段显示器,您可以使用它们以两种不同的方式发送消息:
- 代码 [163]:原始数字 LED(数字)
- 代码 [164]:数字 LED ASCII(字母和特殊代码的近似值)
显示数字非常容易。您必须在要显示的 4 位数字之后发送代码 [163]。函数:setDigitLEDs(byte digit1, byte digit2, byte digit3, byte digit4) 为你做这个:
void setDigitLEDs(byte digit1, byte digit2, byte digit3, byte digit4){ Roomba.write(163); Roomba.write(digit1); Roomba.write(digit2); Roomba.write(digit3); Roomba.write(digit4);}
例如要显示“1,2,3,4”,必须调用函数:
setDigitLEDs(1, 2, 3, 4);
使用代码 [164],可以发送 ASCII 的近似值。函数setDigitLEDFromASCII(byte digit, char letter) 对我们这样做:
void setDigitLEDFromASCII(byte digit, char letter){ switch (digit){ case 1:digit1 =letter;休息;情况 2:数字 2 =字母;休息;情况 3:digit3 =字母;休息;情况 4:digit4 =字母;休息; Roomba.write(164); Roomba.write(digit1); Roomba.write(digit2); Roomba.write(digit3); Roomba.write(digit4);}
为简化起见,我创建了一个新函数来同时发送 4 位数字:
void writeLEDs (char a, char b, char c, char d){ setDigitLEDFromASCII(1, a); setDigitLEDFromASCII(2, b); setDigitLEDFromASCII(3, c); setDigitLEDFromASCII(4, d);}
例如,要显示“STOP”,必须调用函数:
writeLEDs ('s', 't', 'o', 'p');
第 6 步:四处移动 Roomba

对于移动性,Roomba 有 2 个独立的直流电机,可通过编程以高达 500 毫米/秒的速度运行。有几个命令可用于驱动机器人。主要有:
- 代码 [137]:驱动 ==> 必须以毫米/秒为单位发送 +/- 速度和以毫米为单位的 +/- 半径
- 代码 [145]:直接驱动 ==> 必须以 mm/s 为单位发送左/右速度(+ 表示前进,- 表示后退)
- 代码 [146]:驱动 PWM ==> 必须为左右轮发送 +/- PWM 数据
以下是这 3 个选项的代码:
void drive(int velocity, int radius){clamp(velocity, -500, 500); //定义最大和最小速度(毫米/秒)夹钳(半径,-2000,2000); //以毫米为单位定义最大和最小半径 Roomba.write(137); Roomba.write(速度>> 8); Roomba.write(速度); Roomba.write(radius>> 8); Roomba.write(radius);}//---------------------------------------- -----------------------void driveWheels(int right, int left){clamp(right, -500, 500);钳子(左,-500, 500); Roomba.write(145); Roomba.write(right>> 8); Roomba.write(右); Roomba.write(left>> 8); Roomba.write(左); }//---------------------------------------------- ----------------void driveWheelsPWM(int rightPWM, int leftPWM){clamp(rightPWM, -255, 255);钳位(leftPWM, -255, 255); Roomba.write(146); Roomba.write(rightPWM>> 8); Roomba.write(rightPWM); Roomba.write(leftPWM>> 8); Roomba.write(leftPWM);}
注意“clamp”函数定义了允许输入的最大值和最小值。此函数在文件 rombaDefines.h: 中定义
#define clip(value, min, max) (value max ? max :value)
使用上面的代码,可以创建更简单的函数来驱动 Roomba:
/------------------------------------------- --------------------void turnCW(无符号短速度,无符号短度数){驱动(速度,-1);钳位(速度,0, 500);延迟(6600); drive(0,0);}//---------------------------------------- -----------------------void turnCCW(无符号短速度,无符号短度数){驱动器(速度,1);钳位(速度,0, 500);延迟(6600); drive(0,0);}//---------------------------------------- ---------------void driveStop(void){ drive(0,0);}//----------- -------------------------------------------------- --void driveLeft(int left){ driveWheels(left, 0);}//---------------------------------------- --------------------------------void driveRight(int right){ driveWheels(0, right);}
请注意,要转入角度,必须针对给定速度专门计算“延迟”参数。下面是一些可用于测试电机的示例:
turnCW (40, 180); // 顺时针旋转 180 度并停止驱动轮 (20, -20); // 旋转 driveLeft(20); // 左转
为了测试电机,最好添加一个外部按钮(在我的情况下连接到 Arduino 引脚 12),因此您可以将代码下载到 Arduino,启动 Roomba,但在按下按钮之前停止执行。通常,对于电机测试,您可以在代码的设置部分进行。
举个例子,请看下面简单的Arduino代码(注意代码使用了之前开发的函数和定义):
#include "roombaDefines.h"#include // Roomba Create2 connectionint rxPin=10;int txPin=11;SoftwareSerial Roomba(rxPin,txPin);//------ ---------------------------------------void setup() { Roomba.begin(19200); pinMode(ddPin,输出); pinMode(buttonPin, INPUT_PULLUP); // 连接到 Arduino 引脚 12 并用于“启动”延迟(2000);醒来 (); // 唤醒 Roomba startSafe(); // 在安全模式下启动 Roomba while (digitalRead(buttonPin)) { } // 等待按钮被按下以继续运行代码 turnCW (40, 180); //测试 Roomba 顺时针旋转 180 度并停止}//----------------------------------- ----------void loop() { }
第 7 步:通过蓝牙控制 Roomba



为了完成我们项目的第一部分,让我们为我们的 Arduino 安装一个蓝牙模块 (HC-06)。上图显示了如何做到这一点。通常 HC-06 是出厂设置的,波特率为 9,600。将其更改为 19,200 以与 Arduino-Roomba 通信速度兼容非常重要。您可以这样做,向模块发送 AT 命令(AT+BAUD5,其中“5”是 19,200 的代码)。
如果您对 HC-06 的工作原理有任何疑问,请查看我的教程:通过蓝牙 / Android / Arduino 连接“东西”。
为了控制 Roomba,我们将使用我开发的通用应用程序来控制移动机器人,使用 MIT AppInventor 2:“MJRoBot BT Remote Control”。该应用程序可通过以下链接从 Google 商店免费下载:应用程序:MJRoBot BT 遥控器。
该应用程序具有简单的界面,允许您以文本模式或直接通过预编程按钮(每次按下按钮时发送一个字符)向 BT 模块发送命令:
- w:前进
- s:向后
- d:对
- a:左
- f:停止
- p:开/关(未在第一部分使用)
- m:手动/自动(用于在安全模式下发现悬崖等障碍物时重新启动 Roomba)
- +:速度 +
- -:速度 -
如有必要,您还可以将其他命令作为文本发送。还有一个文本窗口,用于接收从 BT 模块接收的消息。此功能在测试阶段非常重要,它可以像“串行监视器”一样使用。
loop() 部分代码将“侦听”蓝牙设备并根据收到的命令采取行动:
void loop() { checkBTcmd(); // 验证是否收到来自BT遥控器的命令manualCmd();}
函数 checkBTcmd() 如下图:
void checkBTcmd() // 验证是否从 BT 遥控器接收到命令 { if (BT1.available()) { command =BT1.read(); BT1.flush(); } }
一旦接收到命令,函数 manualCmd() 将采取适当的行动:
void manualCmd(){ switch (command) { case 'm':startSafe(); Serial.print("Roomba 处于安全模式"); BT1.print("Roomba BT Ctrl OK - 安全模式"); BT1.println('\n');命令 ='f';播放声音(3);休息;案例'f':driveStop(); //关闭两个电机 writeLEDs ('s', 't', 'o', 'p');状态 =命令;休息; case 'w':drive (motorSpeed, 0); writeLEDs (' ', 'g', 'o', ' ');状态 =命令;休息;案例'd':driveRight(motorSpeed); writeLEDs ('r', 'i', 'g', 'h');休息;案例'a':driveLeft(motorSpeed); writeLEDs ('l', 'e', 'f', 't');休息; case 's':drive (-motorSpeed, 0); writeLEDs ('b', 'a', 'c', 'k');状态 =命令;休息; case '+':if (state =='w') { motorSpeed =motorSpeed + 10; if (motorSpeed> MAX_SPEED) { motorSpeed =MAX_SPEED; } 命令 ='w'; } else {命令 =状态;} 中断; case '-':if (state =='w') { motorSpeed =motorSpeed - 10; } if (motorSpeed
第 8 步:结论

此处使用的完整 Arduino 代码和相关文档可以在我的 GITHUB 中找到:Roomba_BT_Ctrl。
请注意,本教程并未对所有 Roomba 执行器进行评论。还有其他电机,用于清洁,其他LED用于时间表,按钮,传感器等。
我在程序中创建的几个函数基于 Dom Amato 开发的 Create 2 库。您可以在以下位置下载完整的库:https://github.com/brinnLabs/Create2 .
我的目的是保持简单,并为您提供一个开始使用 Roomba 的入门平台。以后,我假装发布其他教程,使用树莓派,将 Roomba 连接到互联网,读取其传感器等。
一如既往,我希望这个项目可以帮助其他人在激动人心的电子和机器人世界中找到自己的方向!
更多项目请访问我的博客(葡萄牙语):
MJRoBot.org
来自世界南方的问候!
我们下个教程见!
谢谢
马塞洛
代码
Github
https://github.com/Mjrovai/Roomba_BT_Ctrl制造工艺
- 使用真实传感器控制效果
- 用三星 SAMIIO、Arduino UNO 和 Raspberry Pi 在几分钟内制作一个火灾探测器
- 使用 Arduino 和 Raspberry Pi 构建您的 Internet 控制的视频流机器人
- 使用 Arduino、1Sheeld 和 Android 的通用远程控制
- 带伺服电机的机器人避障
- 带安卓设备的便携式温度计
- 使用 Arduino 和 MPU6050 控制伺服电机
- 使用 Bolt 和 Arduino 控制 LED 亮度
- u-blox LEA-6H 02 GPS 模块,带有 Arduino 和 Python
- 使用 Arduino 进行语音识别和合成
- 使用 Arduino Uno 控制 LED 矩阵
- 从 iOS 和 Android 在 Arduino 上闪烁 LED