Roomba 是一款差速驱动机器人,带有 2 个轮子和一个前脚轮。它的速度高达 500 毫米/秒,并且可以被命令向上或向后移动。
对于信号化,我们可以用四个 7 段显示器和 5 个 LED 来计数(见图):
作为内部传感器,我们有:
对于编程,应使用文档:iRobot® Create® 2 Open Interface (OI) 。Roomba 可以设置为 3 种模式:
被动模式:
安全模式:让您可以完全控制 Roomba,但以下与安全相关的情况除外:
完整模式:
对于 Roomba 和 Arduino 之间的通信,将使用串行端口。默认情况下,Roomba 以 115,200 波特率进行通信,但为了与 Arduino 通信,我们将其切换为 19,200。
设置 Roomba 波特率的方法有 2 种:
上图显示了 Arduino 应如何连接到 Roomba Mini-DIN 连接器
对 Roomba 进行编程时必须做的第一件事是:
我们可以“唤醒”它,向 Mini-DIN 引脚 5(检测设备输入)发送一个低电平脉冲,如下面的函数所示:
void wakeUp (void)
{
setWarningLED(ON);
digitalWrite(ddPin, HIGH);
delay(100);
digitalWrite(ddPin, LOW);
delay(500);
digitalWrite(ddPin, HIGH);
delay(2000);
}
要启动 Roomba,必须发送 2 个代码:“START”[128] 和模式,在我们的例子中为“SAFE MODE”[131]。如果您想要“完整模式”,则应发送代码 [132]。
void startSafe()
{
Roomba.write(128); //Start
Roomba.write(131); //Safe mode
delay(1000);
}
打开 LED
如简介所述,Roomba 有 5 个 LED:
可以使用代码 [139] 命令所有 LED。要控制电源 LED,您必须向 Roomba 发送两个数据字节:“颜色”和“强度”。
颜色:
强度:
函数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)
{
debrisLED = 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 段显示器,您可以使用它们以两种不同的方式发送消息:
显示数字非常容易。您必须在要显示的 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;
break;
case 2:
digit2 = letter;
break;
case 3:
digit3 = letter;
break;
case 4:
digit4 = letter;
break;
}
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');
对于移动性,Roomba 有 2 个独立的直流电机,可通过编程以高达 500 毫米/秒的速度运行。有几个命令可用于驱动机器人。主要有:
以下是这 3 个选项的代码:
void drive(int velocity, int radius)
{
clamp(velocity, -500, 500); //def max and min velocity in mm/s
clamp(radius, -2000, 2000); //def max and min radius in mm
Roomba.write(137);
Roomba.write(velocity >> 8);
Roomba.write(velocity);
Roomba.write(radius >> 8);
Roomba.write(radius);
}
//---------------------------------------------------------------
void driveWheels(int right, int left)
{
clamp(right, -500, 500);
clamp(left, -500, 500);
Roomba.write(145);
Roomba.write(right >> 8);
Roomba.write(right);
Roomba.write(left >> 8);
Roomba.write(left);
}
//---------------------------------------------------------------
void driveWheelsPWM(int rightPWM, int leftPWM)
{
clamp(rightPWM, -255, 255);
clamp(leftPWM, -255, 255);
Roomba.write(146);
Roomba.write(rightPWM >> 8);
Roomba.write(rightPWM);
Roomba.write(leftPWM >> 8);
Roomba.write(leftPWM);
}
请注意,“clamp”功能定义了允许输入的最大值和最小值。该函数在文件rombaDefines.h 中定义:
#define clamp(value, min, max) (value < min ? min : value > max ? max : value)
使用上面的代码,可以创建更简单的函数来驱动 Roomba:
/---------------------------------------------------------------
void turnCW(unsigned short velocity, unsigned short degrees)
{
drive(velocity, -1);
clamp(velocity, 0, 500);
delay(6600);
drive(0,0);
}
//---------------------------------------------------------------
void turnCCW(unsigned short velocity, unsigned short degrees)
{
drive(velocity, 1);
clamp(velocity, 0, 500);
delay(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); // spin clockwise 180 degrees and stop
driveWheels(20, -20); // spin
driveLeft(20); // turning left
为了测试电机,最好添加一个外部按钮(在我的情况下连接到 Arduino 引脚 12),因此您可以将代码下载到 Arduino,启动 Roomba,但在按下按钮之前停止执行。通常,对于电机测试,您可以在代码的设置部分进行。
例如,请看下面的简单 Arduino 代码(注意代码使用了之前开发的函数和定义):
#include "roombaDefines.h"
#include
// Roomba Create2 connection
int rxPin=10;
int txPin=11;
SoftwareSerial Roomba(rxPin,txPin);
//---------------------------------------------
void setup()
{
Roomba.begin(19200);
pinMode(ddPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP); // connected to Arduino pin 12 and used for "starting"
delay(2000);
wakeUp (); // Wake-up Roomba
startSafe(); // Start Roomba in Safe Mode
while (digitalRead(buttonPin)) { } // wait button to be pressed to continous run code
turnCW (40, 180); //test Roomba spin clock-wise 180 degrees and stop
}
//---------------------------------------------
void loop()
{
}
为了完成项目的第一部分,让我们在我们的 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 远程控制”。该应用程序可以通过以下链接从 Google 商店免费下载:应用程序:MJRoBot BT 远程控制。
该应用程序有一个简单的界面,允许您以文本模式或直接通过预编程按钮(每次按下按钮,发送一个字符)向 BT 模块发送命令:
如有必要,您还可以将其他命令作为文本发送。还有一个文本窗口,用于显示从 BT 模块接收到的消息。此功能在测试阶段非常重要,可以像“串行监视器”一样使用。
代码的loop()部分将“监听”蓝牙设备,并根据收到的命令采取行动:
void loop()
{
checkBTcmd(); // verify if a comand is received from BT remote control
manualCmd ();
}
函数checkBTcmd()如下所示:
void checkBTcmd() // verify if a command is received from BT remote control
{
if (BT1.available())
{
command = BT1.read();
BT1.flush();
}
}
一旦收到命令,函数manualCmd()将采取适当的行动:
void manualCmd()
{
switch (command)
{
case 'm':
startSafe();
Serial.print("Roomba in Safe mode");
BT1.print("Roomba BT Ctrl OK - Safe mode");
BT1.println('\n');
command = 'f';
playSound (3);
break;
case 'f':
driveStop(); //turn off both motors
writeLEDs ('s', 't', 'o', 'p');
state = command;
break;
case 'w':
drive (motorSpeed, 0);
writeLEDs (' ', 'g', 'o', ' ');
state = command;
break;
case 'd':
driveRight(motorSpeed);
writeLEDs ('r', 'i', 'g', 'h');
break;
case 'a':
driveLeft(motorSpeed);
writeLEDs ('l', 'e', 'f', 't');
break;
case 's':
drive (-motorSpeed, 0);
writeLEDs ('b', 'a', 'c', 'k');
state = command;
break;
case '+':
if (state == 'w')
{
motorSpeed = motorSpeed + 10;
if (motorSpeed > MAX_SPEED)
{
motorSpeed = MAX_SPEED;
}
command = 'w';
} else {command = state;}
break;
case '-':
if (state == 'w')
{
motorSpeed = motorSpeed - 10;
}
if (motorSpeed < MIN_SPEED )
{
motorSpeed = MIN_SPEED;
}
Serial.println(motorSpeed);
command = state;
break;
}
}
此处使用的完整 Arduino 代码和相关文档可以在我的GITHUB:Roomba_BT_Ctrl中找到。
请注意,并非所有 Roomba 执行器都对本教程进行了评论。还有其他用于清洁的电机,用于日程安排的其他 LED、按钮、传感器等。
我在我的程序中创建的几个函数基于 Dom Amato 开发的 Create 2 库。您可以在以下位置下载完整的库:https ://github.com/brinnLabs/Create2 。
我的目的是保持简单,并为您提供一个开始使用 Roomba 的平台。将来,我会假装发布其他教程,使用 Raspberry-Pi,将 Roomba 连接到互联网,读取其传感器等。
一如既往,我希望这个项目可以帮助其他人在电子和机器人这个激动人心的世界中找到自己的道路!
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
全部0条评论
快来发表一下你的评论吧 !