Controlar Roomba Create 2 com Arduino e Android: Guia Passo a Passo
Componentes e Materiais
| Roomba Create2 | 1 |
| Arduino UNO | 1 |
| Módulo Bluetooth HC-06 | 1 |
| Chave Pushbutton SparkFun 12mm | 1 |
Aplicativos e Serviços Online
| MJRoBot BT Remote Control - App Android |
Sobre o Projeto

Como um dos vencedores do Concurso de Robótica Instructables 2016, recebi como prêmio um iRobot Roomba Create2. É uma plataforma excelente e muito acessível para desenvolvimento de robótica, custando cerca de US$200. O Create 2 permite uma variedade de métodos de programação. Como começo, usei-o com um Arduino e um APP Android para mover o robô. Neste primeiro tutorial, explorarei como conectar o Arduino com o Roomba via porta serial e como comandar seus motores, LEDs e som. Em projetos futuros, explorarei seus sensores e também usarei um Raspberry Pi para conectar o Roomba à internet.
Abaixo, um vídeo mostrando meus primeiros resultados programando um robô Roomba:
Passo 1: Lista de Materiais

- iRobot Create2
- Arduino UNO
- Módulo Bluetooth HC-06
- Botão Push-button
Passo 2: O Roomba Create2

O Roomba é um robô de tração diferencial, com 2 rodas e uma roda dianteira livre. Sua velocidade vai até 500 mm/s e pode ser comandado para ir para frente ou para trás.
Para sinalização, contamos com quatro displays de 7 segmentos e 5 LEDs:
- Clean (Limpar)
- Spot (Ponto)
- Dock (Base)
- Warning/Check (Aviso/Verificar)
- Dirt/Debris (Sujeira/Detritos)
Como sensores internos, temos entre outros:
- Detector de penhasco (4 na frente)
- Detectores de colisão (2 na frente)
- Encoders de roda
Para programação, o documento iRobot® Create® 2 Open Interface (OI) deve ser usado. O Roomba pode ser programado em 3 modos:
Modo Passivo:
- Ao enviar o comando Start ou qualquer um dos comandos de modo de limpeza (ex: Spot, Clean, Seek Dock), o OI entra no modo Passivo. Quando o OI está no modo Passivo, você pode solicitar e receber dados dos sensores usando qualquer um dos comandos de sensor, mas não pode alterar os parâmetros de comando atuais para os atuadores (motores, alto-falante, luzes, drivers de lado baixo, saídas digitais) para outra coisa.
Modo Seguro (Safe Mode):
Dá controle total do Roomba, com exceção das seguintes condições relacionadas à segurança:
- Carregador conectado e energizado.
- Detecção de queda de roda (em qualquer roda).
- Detecção de penhasco enquanto move para frente (ou movendo para trás com raio de giro pequeno, menor que um raio do robô).
- Se uma das condições acima ocorrer enquanto o OI está no modo Seguro, o Roomba para todos os motores e reverte para o modo Passivo.
Modo Completo (Full Mode):
- Dá controle completo sobre o Roomba, todos os seus atuadores e todas as condições relacionadas à segurança que são restritas quando o OI está no modo Seguro, pois o modo Completo desliga as funções de segurança de penhasco, queda de roda e carregador interno.
Passo 3: A Conexão Serial

Para comunicação entre o Roomba e Arduino, a Porta Serial será usada. Por padrão, o Roomba comunica a 115.200 baud, mas para comunicar com Arduino, vamos mudá-lo para 19.200.
Existem 2 maneiras de definir a taxa de baud do Roomba:
- Enquanto desliga o Roomba, continue segurando o botão Clean/Power após a luz apagar. Após cerca de 10 segundos, o Roomba toca uma melodia de tons descendentes. O Roomba comunicará a 19.200 baud até que o processador perca a energia da bateria ou a taxa de baud seja explicitamente alterada via OI.
- Use o pino de Mudança de Taxa de Baud (pino 5 no conector Mini-DIN) para alterar a taxa de baud do Roomba. Após ligar o Roomba, espere 2 segundos e então dê 3 pulsos baixos no pino de Mudança de Taxa de Baud. Cada pulso deve durar entre 50 e 500 milissegundos. O Roomba comunicará a 19200 baud até que o processador perca a energia da bateria ou a taxa de baud seja explicitamente alterada via OI.
O diagrama acima mostra como o Arduino deve ser conectado ao conector Mini-DIN do Roomba.
Passo 4: Iniciando o Roomba
A primeira coisa que deve ser feita ao programar um Roomba é:
- "Acordar" o robô
- Definir o modo (Seguro ou Completo)
Podemos "acordá-lo" enviando um pulso baixo para o pino 5 do Mini-DIN (entrada de detecção de dispositivo) como mostrado na função abaixo:
void wakeUp(void) {
setWarningLED(ON);
digitalWrite(ddPin, HIGH);
delay(100);
digitalWrite(ddPin, LOW);
delay(500);
digitalWrite(ddPin, HIGH);
delay(2000);
}
Para iniciar o Roomba, sempre 2 códigos devem ser enviados: "START" [128] e o modo, no nosso caso "SAFE MODE" [131]. Se você quiser "FULL MODE", o código [132] deve ser enviado em vez disso.
void startSafe() {
Roomba.write(128); //Start
Roomba.write(131); //Modo seguro
delay(1000);
}
Passo 5: Ligando os LEDs e Display

Ligando os LEDs
Conforme descrito na introdução, o Roomba tem 5 LEDs:
- Power/Clean (bi-color vermelho/verde e intensidade controlada)
- Spot (Verde, intensidade fixa)
- Dock (Verde, intensidade fixa)
- Warning/Check (Laranja, intensidade fixa)
- Dirt/Debris (Azul, intensidade fixa)
Todos os LEDs podem ser comandados usando o código [139]. Para controlar o LED Power, você deve enviar dois bytes de dados para o Roomba: "cor" e "intensidade".
Cor:
- Verde = 0
- Laranja = 128
- Vermelho = 255
Intensidade:
- Baixa = 0
- Máxima = 255
A função setPowerLED(byte setColor, byte setIntensity) faz isso:
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);
}
Por exemplo, para ligar o LED POWER com cor laranja na metade da intensidade, você pode chamar a função como abaixo:
setPowerLED(128, 128);
Para ligar os 4 LEDs restantes, as funções abaixo devem ser usadas:
setDebrisLED(ON);
setDockLED(ON);
setSpotLED(ON);
setWarningLED(ON);
Todas as funções acima têm código semelhante a este:
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);
}
Basicamente a diferença será a linha:
debrisLED = enable;
que deve ser alterada habilitando cada um dos outros LEDs (spotLED, dockLED, warningLED).
Enviando Mensagens para o Display
O Roomba tem quatro displays de 7 segmentos que você pode usar para enviar mensagens de duas formas diferentes:
- Código [163]: Digit LEDs Raw (Numérico)
- Código [164]: Digit LEDs ASCII (Aproximação de letras e códigos especiais)
Para exibir números é muito fácil. Você deve enviar o código [163], seguido dos 4 dígitos a serem exibidos. A função setDigitLEDs(byte digit1, byte digit2, byte digit3, byte digit4) faz isso para você:
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);
}
Por exemplo, para exibir "1, 2, 3, 4", você deve chamar a função:
setDigitLEDs(1, 2, 3, 4);
Com o código [164], é possível enviar aproximação de ASCII. A função setDigitLEDFromASCII(byte digit, char letter) faz isso para nós:
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);
}
Para simplificar, criei uma nova função para enviar os 4 dígitos de uma vez:
void writeLEDs(char a, char b, char c, char d) {
setDigitLEDFromASCII(1, a);
setDigitLEDFromASCII(2, b);
setDigitLEDFromASCII(3, c);
setDigitLEDFromASCII(4, d);
}
Por exemplo, para exibir "STOP", você deve chamar a função:
writeLEDs('s', 't', 'o', 'p');
Passo 6: Movendo o Roomba

Para mobilidade, o Roomba tem 2 motores DC independentes que podem ser programados para rodar até 500mm/s. Existem vários comandos que podem ser usados para dirigir o robô. Os principais são:
- Código [137]: Drive ==> Deve enviar +/- Velocidade em mm/s e +/- Raio em mm
- Código [145]: Drive Direct ==> Deve enviar Velocidade Esquerda/Direita em mm/s (+ para Frente e - para Trás)
- Código [146]: Drive PWM ==> Deve enviar +/- dados PWM para rodas Esquerda e Direita
Abaixo está o código para essas 3 opções:
void drive(int velocity, int radius) {
clamp(velocity, -500, 500); //define max e min velocidade em mm/s
clamp(radius, -2000, 2000); //define max e min raio em 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);
}
Note que a função "clamp" define os valores máximo e mínimo permitidos para entrada. Esta função é definida no arquivo rombaDefines.h:
#define clamp(value, min, max) (value < min ? min : value > max ? max : value)
Usando o código acima, funções mais simples podem ser criadas para dirigir o 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);
}
Note que para girar em ângulo, o argumento "delay" deve ser calculado especificamente para uma determinada velocidade. Abaixo alguns exemplos que podem ser usados para testar os motores:
turnCW(40, 180); // girar no sentido horário 180 graus e parar
driveWheels(20, -20); // girar
driveLeft(20); // virar à esquerda
Para testar os motores, é bom adicionar um botão push externo (no meu caso conectado ao pino 12 do Arduino), para que você possa carregar o código no Arduino, iniciar o Roomba, mas parar a execução até que o botão seja pressionado. Geralmente, para testes de motores, você pode fazer isso na parte setup do código.
Como exemplo, veja o código Arduino simples abaixo (note que o código usa funções e definições desenvolvidas antes):
#include "roombaDefines.h"
#include <SoftwareSerial.h>
// Conexão Roomba Create2
int rxPin = 10;
int txPin = 11;
SoftwareSerial Roomba(rxPin, txPin);
//---------------------------------------------
void setup() {
Roomba.begin(19200);
pinMode(ddPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP); // conectado ao pino 12 do Arduino e usado para "iniciar"
delay(2000);
wakeUp(); // Acordar Roomba
startSafe(); // Iniciar Roomba no Modo Seguro
while (digitalRead(buttonPin)) {
} // esperar botão ser pressionado para continuar execução
turnCW(40, 180); // testar Roomba girar horário 180 graus e parar
}
//---------------------------------------------
void loop() {
}
Passo 7: Controlando Roomba via Bluetooth

Para completar nossa primeira parte do projeto, vamos instalar um módulo Bluetooth (HC-06) no nosso Arduino. O diagrama acima mostra como fazer. Geralmente o HC-06 vem configurado de fábrica com taxa de baud de 9.600. É importante que você mude para 19.200 para ser compatível com a velocidade de comunicação Arduino-Roomba. Você pode fazer isso enviando um comando AT para o módulo (AT+BAUD5 onde "5" é o código para 19.200).
Se você tiver dúvidas sobre como o HC-06 funciona, dê uma olhada no meu tutorial: Conectando "coisas" via Bluetooth / Android / Arduino.
Para controlar o Roomba, usaremos um App genérico desenvolvido por mim para controlar robôs móveis, usando o MIT AppInventor 2: "MJRoBot BT Remote Control". O app pode ser baixado gratuitamente na Google Play Store via link: App: MJRoBot BT Remote Control.
O app tem uma interface simples, permitindo enviar comandos ao módulo BT em ambos os modos, TEXTO ou diretamente via botões pré-programados (cada vez que um botão é pressionado, um caractere é enviado):
- w: Frente
- s: Trás
- d: Direita
- a: Esquerda
- f: Parar
- p: LIGAR/DESLIGAR (não usado nesta primeira parte)
- m: Manual/Automático (Usado para reiniciar Roomba se um obstáculo como penhasco for encontrado no Modo Seguro)
- +: Velocidade +
- -: Velocidade -
Você também pode enviar outros comandos como texto se necessário. Há também uma janela de texto para mensagens recebidas do módulo BT. Este recurso é muito importante durante a fase de teste, pode ser usado da mesma forma que o "Monitor Serial".
A parte loop() do código estará "ouvindo" o dispositivo bluetooth e dependendo do comando recebido, tomará uma ação:
void loop() {
checkBTcmd(); // verificar se um comando é recebido do controle remoto BT
manualCmd();
}
A função checkBTcmd() é mostrada abaixo:
void checkBTcmd() // verificar se um comando é recebido do controle remoto BT
{
if (BT1.available()) {
command = BT1.read();
BT1.flush();
}
}
Uma vez que um comando é recebido, a função manualCmd() tomará a ação apropriada:
void manualCmd() {
switch (command) {
case 'm':
startSafe();
Serial.print("Roomba no modo seguro");
BT1.print("Roomba BT Ctrl OK - Modo seguro");
BT1.println('\n');
command = 'f';
playSound(3);
break;
case 'f':
driveStop(); // desliga ambos motores
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;
}
}
Passo 8: Conclusão

O código Arduino completo usado aqui e documentos relacionados podem ser encontrados no meu GITHUB: Roomba_BT_Ctrl.
Observe que nem todos os atuadores do Roomba foram comentados neste tutorial. Existem outros motores, usados para limpeza, outros LEDs usados para agendamento, botões, sensores, etc.
Várias das funções que criei no meu programa foram baseadas na biblioteca Create 2 desenvolvida por Dom Amato. Você pode baixar a biblioteca completa em: https://github.com/brinnLabs/Create2.
Minha intenção aqui foi manter simples e dar a você uma plataforma inicial para começar a brincar com o Roomba. No futuro, pretendo publicar outros tutoriais, usando um Raspberry-Pi, conectar o Roomba com a internet, ler seus sensores, etc.
Como sempre, espero que este projeto possa ajudar outros a encontrar seu caminho no emocionante mundo da eletrônica e robótica!
Para mais projetos, visite meu blog (em português):
MJRoBot.org
Saudações do sul do mundo!
Até o próximo tutorial!
Obrigado
Marcelo
Código
GitHub
https://github.com/Mjrovai/Roomba_BT_Ctrl
Processo de manufatura
- Crie Efeitos de Áudio Controlados por Sensores com o Kit Satellite CCRMA
- Construa um Sistema Rápido e Confiável de Detecção de Incêndio com Samsung SAMI, Arduino UNO e Raspberry Pi
- Construa um Robô de Streaming de Vídeo Controlado por Internet com Arduino e Raspberry Pi
- Controle Remoto Universal Android com Arduino, 1Sheeld e IR
- Robô Desviador de Obstáculos com Servo: Construa com Arduino e HC-SR04
- Termômetro Portátil DIY de Baixo Custo com Integração Android
- Arduino e MPU6050: Controle Preciso de Servomotores SG90 e MG996R
- Controle Suave de Brilho de LED com Bolt IoT e Arduino UNO
- Módulo GPS u-blox LEA‑6H 02: Guia de Integração com Arduino e Python
- Dominando Reconhecimento e Síntese de Fala no Arduino Due