Controle su Roomba con Arduino y Android


 

iRobot Roomba Create2 es una a  plataforma grande y muy asequible para el desarrollo de la robótica, costando alrededor de US$ 200 permitiendo  una variedad de métodos de programación. Como  comienzo mjrovi usó  un Arduino y una aplicación Android para mover el robot  por puerto serie  consiguiendo asi controlar  sus motores, LEDS y sonido.

Como uno de los ganadores de 2016 del concurso de robótica   en Instructables, mjrovi recibió como premio un iRobot Roomba Create2.

 

 

La Roomba es un robot de impulsión diferenciada, con 2 ruedas motrices y una rueda  central  guía. Su velocidad va hasta 500 mm/s y puede ser mandado a ir hacia arriba o hacia atrás.
Para señalización, contamos con cuatro 7 segmentos display y 5 LEDs :

  • Limpiar
  • Punto
  • Muelle
  • ADVERTENCIA/Check
  • Suciedad/escombros

Como sensores internos, tenemos entre otros:

  • Detector de acantilado (4 en el frente)
  • Detectores Bump (frente 2)
  • Codificadores de rueda

Para la programación, el documento: iRobot® Create® 2 abierto interfaz (OI) debe ser utilizado.El Roomba puede ser programado en 3 modos:

  1. Modo pasivo:Al enviar el comando de Start o cualquiera de los comandos de modo de limpieza (por ejemplo, punto limpio, muelle buscar), la OI entra en modo pasivo. Cuando la OI está en modo pasivo, puede solicitar y recibir datos de los sensores usando cualquiera de los comandos del sensor, pero no puede cambiar los parámetros de comando actuales para los actuadores (motores, altavoces, luces, controladores de lado de baja, salidas digitales) a otra cosa.
  2. Modo seguro :Le da un control completo de Roomba, con excepción de las siguientes condiciones relacionadas con la seguridad:
    Cargador conectado y alimentado:detección de una caída de rueda (en cualquier rueda),detección de un acantilado mientras se mueve hacia adelante (o hacia atrás con un pequeño radio de torneado, menos de un radio de robot) o si ocurre una de las condiciones relacionadas con la seguridad mientras que el OI es en modo seguro, Roomba detiene todos los motores y vuelve al modo pasivo.
  3. Modo completo:Le da un control completo sobre Roomba, todos de sus actuadores y todas las condiciones relacionadas con la seguridad que están restringidas cuando la OI en modo seguro, como el modo completo se apaga el acantilado, caída de rueda y características de seguridad cargador interno.

Comunicaciones

Para  programar la Romba  la lista de  materiales  usada es la siguiente:

  • iRobot Create2
  • Arduino UNO
  • Módulo Bluetooth HC-06
  • Pulsador

Para la comunicación entre la Roomba y Arduino, se utilizará el puerto Serial. Por defecto, Roomba comunica a 115.200 baudios, pero para comunicarse con Arduino, se cambiará a 19.200.

Hay 2 formas de establecer la tasa de baudios de Roomba:

  1. Mientras que apagar Roomba, continúan mantenga pulsado el botón de encendido o limpiar después de que la luz se ha apagado. Después de unos 10 segundos, Roomba juega una melodía descendente de las echadas. Roomba se comunicará a 19.200 baudios hasta que el procesador pierde energía de la batería o la tasa de baudios se modifica explícitamente a través de la OI.
  2. Utilizar el pin de cambio de tasa de baudios (pin 5 del conector mini-DIN) para cambiar la velocidad en baudios de Roomba. Después de encender la Roomba, esperar 2 segundos y luego pulso el cambio de la tasa de baudios baja tres veces. Cada impulso debe durar entre 50 y 500 milisegundos. Roomba se comunicará a 19200 baudios hasta que el procesador pierde energía de la batería o la tasa de baudios se modifica explícitamente a través de la OI.

 

El diagrama de arriba muestra cómo la Arduino debe conectarse al conector mini-DIN de Roomba

 

 

Lo primero creo que debe hacerse cuando un Roomba de programación es “Despertar” el robot y  Definir el modo (segura o completa)

Nosotros podemos  hacer  un “wake-up”, enviar un poco de pulso al pin mini-DIN 5 (detección de dispositivo de entrada) como se muestra en la siguiente función:
void wakeUp (void)
{
setWarningLED(ON);
digitalWrite(ddPin, HIGH);
delay(100);
digitalWrite(ddPin, LOW);
delay(500);
digitalWrite(ddPin, HIGH);
delay(2000);
}

Para empezar a Roomba deberán enviarse 2 códigos de siempre: «START» [128] y el modo, en nuestro caso “Modo seguro” [131]. Si usted quiere un “modo completo”, debe enviarse en su lugar el código [132].
void startSafe()
{
Roomba.write(128); //Start
Roomba.write(131); //Safe mode
delay(1000);
}

 

Como se describe en la introducción, el Roomba tiene 5 LEDs:

  • Energía/limpiar (bicolor rojo/verde e intensidad controladas)
  • Punto (verde, intensidad fija)
  • Muelle (verde, intensidad fija)
  • ADVERTENCIA/Check (naranja, intensidad fija)
  • Suciedad/escombros (azul, fija la intensidad)

 

Control de leds

Todos los LEDs pueden ser ordenados mediante código [139]
Para controlar el LED de encendido, debe enviar dos bytes de datos a Roomba: “color” y la “intensidad”.
Color:

  • Verde = 0
  • Naranja = 128
  • rojo = 255

Intensidad:

  • Bajo = 0
  • Max = 255

La función setPowerLED (colores bytes, setIntensity bytes) lo hace:

void setPowerLED(byte setColor, byte setIntensity)
{
color = setColor;
intensity = setIntensity;
Roomba.write(139);
Roomba.write((byte)0x00);
Roomba.write((byte)color);
Roomba.write((byte)intensity);
}

Por ejemplo, para encender el LED de POWER de color naranja en la mitad de su intensidad, usted puede llamar a la función como bramido:setPowerLED (128, 128);

Encender los 4 LEDs restantes, deberán utilizarse las siguientes funciones:
setDebrisLED(ON);
setDockLED(ON);
setSpotLED(ON);
setWarningLED(ON);

Todas las funciones anteriores tiene un código similar 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);
}

Básicamente, la diferencia será la línea: debrisLED = habilitar;  debe modificarse permitiendo a cada uno de los otros LEDs (spotLED, dockLED, warningLED).

 

Envío de mensajes

Roomba tiene cuatro 4 displays de 7 segmentos que puede utilizar para enviar mensajes de dos maneras::
[163] código: Dígitos LED crudo (numérico)
[164] código: Dígitos LED de ASCII (aproximación de letras y códigos especiales)
Para mostrar números  debe enviar el código [163], siguiendo las 4 digitas a mostrar. La función: setDigitLEDs (bytes digit1 digit2 bytes, digit3 bytes, digit4 bytes) lo hace para usted:

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 ejemplo, para mostrar “1, 2, 3, 4”, debe llamar a la función: setDigitLEDs (1, 2, 3, 4);

Con el código [164], es posible enviar aproximación de ASCII.

La función setDigitLEDFromASCII (dígitos de byte, char letra) hace esto para nosotros:
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, crear una nueva función para enviar los 4 dígitos al mismo tiempo:
void writeLEDs (char a, char b, char c, char d)
{
setDigitLEDFromASCII(1, a);
setDigitLEDFromASCII(2, b);
setDigitLEDFromASCII(3, c);
setDigitLEDFromASCII(4, d);
}

Por ejemplo, para mostrar “STOP”, usted debe llamar a la función: writeLEDs (‘s’, ‘ t ‘, ‘ o ‘, ‘p’);

Mover la  Roomba

Para la movilidad, Roomba tiene 2 motores independientes que pueden programarse para ejecutar 500mm/s. Hay varios comandos que pueden utilizarse para controlar el robot. Los principales son:

  • Código [137]: Unidad == > debe enviar +-velocidad en mm/s y +-radio en mm
  • Codigo [145] de código: Impulsión directa == > debe enviar izquierda velocidad en mm/s (+ para adelante y para atrás)
  • Código [146]: Unidad PWM == > debe enviar +-datos PWM para la izquierda y derecha las ruedas

 

A continuación el código para estas 3 opciones:

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);
}

Tenga en cuenta que la función de “fijar” define los valores máximos y mínimos que se permitieron la entrada. Esta función se define en el archivo rombaDefines.h:

#define abrazadera (valor, min, max) (valor < min? min: valor > max? max: valor)
Utilizando el código anterior, se pueden crear funciones más simples para Roomba alrededor de:
/—————————————————————
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);
}

Tenga en cuenta que para girar en ángulo, debe calcularse el argumento de “retraso” específicamente para una velocidad dada

A continuación algunos ejemplos que pueden utilizar para probar los motores:

turnCW (40, 180); girar 180 grados hacia la derecha y parada
driveWheels (20, -20); vuelta
driveLeft(20); girar a la izquierda

Para las pruebas de los motores, es bueno añadir un pulsador externo (en mi caso conectado al Arduino pin 12), para que puedan descargar el código de Arduino, a partir de la Roomba, pero parando la ejecución hasta que se pulsa la tecla. Generalmente, para los motores de prueba lo puedes hacer en la parte de configuración del código.

Como ejemplo, consulte el código de Arduino simple abajo (nota que el código usa funciones y definiciones desarrollaron antes):

#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()
{

}

 

Controlar la Roomba a través de Bluetooth

Para controlar  Roomba de modo inalambrico   vamos a instalar un módulo Bluetooth (HC-06) a nuestro Arduino. El diagrama de arriba muestra cómo hacerlo. Suele ser el HC-06 settle up de fábrica con una velocidad de 9.600. Es importante cambiarlo a 19.200 para ser compatible con la velocidad de la comunicación de Arduino-Roomba. Usted puede hacer que el envío un comando AT para el módulo (AT + BAUD5 donde “5” es el código de 19.200).

Para controlar la Roomba, utilizaremos una aplicación genérica que fue desarrollada por jrovai   para el control de robots móviles, con el MIT AppInventor 2: “MJRoBot BT Remote Control”. La aplicación puede descargarse gratuitamente de la tienda de Google a través del enlace: aplicación: MJRoBot BT Remote Control.

La aplicación tiene una interfaz sencilla, lo que le permite enviar comandos al módulo de BT en ambos, modo de texto o directamente a través de botones preprogramados (cada vez que se pulsa un botón, un carácter se envía):

  • w: hacia adeñante
  • S: hacia atras
  • d: derecho
  • a: izquierda
  • f: parada
  • p: ON / OFF (no usado en esta primera parte)
  • m: manual / automático (se utiliza para reiniciar Roomba si un obstáculo como un acantilado se encuentra en modo seguro)
  • +: Velocidad +
  • -: Velocidad –

También puede enviar otros comandos como texto si es necesario. También hay una ventana de texto para los mensajes recibidos desde el módulo de BT. Esta característica es muy importante durante la fase de prueba, puede ser utilizado en la misma forma que el “Serial Monitor”.

El loop() parte del código será “escuchando” el dispositivo bluetooth y dependiendo del comando recibido, tomar una acción:

void loop()
{
checkBTcmd(); // verify if a comand is received from BT remote control
manualCmd ();
}
La función checkBTcmd() se muestra a continuación:

void checkBTcmd() // verify if a command is received from BT remote control
{
if (BT1.available())
{
command = BT1.read();
BT1.flush();
}
}
Una vez que se recibe un comando, la función manualCmd() tomará la acción apropiada:
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; } }

 

 

 

El código de Arduino completo utilizado en documentos aquí relacionados se puede encontrar en GITHUB en https://github.com/Mjrovai/Roomba_BT_Ctrl

Varias de las funciones que   el autor  ha creado en su  programa se basaron en la biblioteca de crear 2 desarrollada por Dom Amato. Puede descargar la librería completa en‎: https://github.com/brinnLabs/Create2.

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.