MaryJD edited this page Feb 18, 2016 · 1 revision

Planteamiento de hackeo de un robot aspirador Roomba

[Atención, artículo en estado de borrador]



Llegados a este punto, damos por supuesto que cualquier lector sabe qué es un Roomba. En caso de no ser así, o de no conocer toda la gama de modelos, recomendamos la lectura de este artículo con todos los modelos de Roomba: robotsaspirador.es/comparativa-roomba/.

Tal y como muestran nuestros compañeros, con un poco de conocimiento electrónico, un módulo bluetooth y algún elemento más han conseguido dotar de una mayor inteligencia a uno de los modelos de iRobot. ¿El fin? Que detecte cuando estamos o no en casa. De este modo si algún día coincide que estamos en casa en las horas que tenemos programada la Roomba para que trabaje ésta no lo hará. Sencillamente para evitar que el ruido del aspirador pueda molestarnos.

¿Cómo se consigue? n hack que nos permitirá ganar un mayor control pues podremos gestionar cuando limpiar, que vuelva a la base, movimientos de ruedas, giros, estado de la batería y más, mucho más. Si tenéis una Roomba, ganas de "jugar" con ella y la electrónica se os da bien, estáis a un paso de conseguirlo.

Seguimos, con información sacada de SecurityByDefault (http://www.securitybydefault.com/2011/01/hacking-roomba.html):

Para meterle mano a la Roomba via Bluetooth, esto es lo que debéis hacer:

Enchufar el dispositivo bluetooth a la Roomba. Consejo: sujetad con cinta aislante el cable y el conector, porque dado el movimiento de la roomba, puede sufrir daños. Al principio lo tenía como la foto que se puede ver en el avatar del post. En mi caso he utilizado Linux con un adaptador Bluetooth para poder conectarnos al Rootooth. Mediante hcitool buscamos el nuevo dispositivo Bluetooth y nos apuntamos la MAC.

_[root@Carmen ~]# hcitool scan _ Scanning ... 00:06:66:ZZ:XX:YY FireFly-XXYY

3.-) Probamos a establecer una conexión mediante "rfcomm" que, una vez hecha la conexión, nos dejará un puerto en /dev/rfcommN al cuál podremos hablar como si de un puerto serie se tratara.

[root@Carmen ~]# rfcomm connect 2 00:06:66:ZZ:XX:YY Connected /dev/rfcomm2 to 00:06:66:ZZ:XX:YY on channel 1 Press CTRL-C for hangup

4.-) Lo siguiente es comprobar que el modem que incluye Rootooth funciona correctamente a 115200 bps, para no tener errores en la comunicación. Para ello accedemos mediante "minicom" y comprobamos que todo está correcto:

Welcome to minicom 2.00.0

_OPCIONES: History Buffer, F-key Macros, Search History Buffer, I18n _ Compilado en Feb 21 2005, 19:32:30.

Presione CTRL-A Z para obtener ayuda sobre teclas especiales

_CMD _ _? _ _Settings _ _BTA=000666ZZXXYY _ BTName=FireFly-XXYY Baudrt=115K Parity=None Mode =Slav Authen=0 Encryp=0 PinCod=1234 Bonded=0 Rem=NONE SET _END _

Una vez que conecta, enviamos los caracteres "$$$"(3 símbolos del dólar, sin las comillas) para entrar en modo Comando al modem Bluetooth. Nos contestará con CMD si todo es correcto. Pulsando D y Enter, nos dará la info que se puede ver más arriba. Importante que esté a 115K, y Parity None. Si algo no está como debe, con la tecla H se accede a la ayuda y se configura para que quede así. _Una vez todo está correcto, pulsamos "---" (tres guiones seguidos, sin comillas) y devolverá END… Ya estamos fuera del modo command. _

5.-) Después de probar diversos programas (RoombaCom, Roomba-tilt.pl, Roomba Status) rebuscando en Internet, que prometían controlar la Roomba en remoto, y ver que estaban todos obsoletos, decidí buscar documentación actualizada de la API de la Roomba para poder hablarle.

El documento actualizado para las especificaciones Open Interface de la serie 500 se puede descargar de aquí.

6.-) Manos a la obra… Bajo estas líneas pongo un script (por supuesto en Perl) que recibe como parámetro "clean" o "dock" y hacen que la roomba se ponga a limpiar o se ponga en modo Dock (o, ir a su base de carga)

Incluyo además el código necesario para que cada vez que lo ejecutemos, cree una conexión nueva contra Rootooth, no teniendo que mantener el rfcomm abierto todo el tiempo.

_[root@Carmen tmp]# more /usr/local/bin/roomba.pl _ #!/usr/bin/perl

use IPC::Open2;

$port="/dev/rfcomm2"; #el puerto serie a crear. Importante que no esté siendo usado ya my $param=lc ($ARGV[0]); #capturo parámetro introducido y lo paso a minúsculas my $rfcomm="rfcomm connect 2 00:06:66:ZZ:XX:YY"; #comando rfcomm para crear puerto

my $value;

if ($param eq "clean") {#Si la orden es limpiar _$value=135; _ } elsif ($param eq "dock") {#Si la orden es ir a base $value=143; } else {#El resto no está aceptado _die " [CLEAN|DOCK]\n"; _ }

my $pid=open2 (*READ,*WRITE,$rfcomm); #lanzamos por un lado la conexión

sleep (10); #Le damos 10 segundos para que se establezca

system("stty -F $port 115200 raw -parenb -parodd cs8 -hupcl -cstopb clocal"); #Parámetros necesarios para configuración del puerto

my $roomba; open $roomba, "+>$port" or die "couldn't open port: $!"; #Abrimos conexión al puerto select $roomba; $| =1; #Eliminamos lo que hubiera en el buffer en la lectura

printf $roomba "%c",128; sleep 0.3; # START Necesario cada vez que le demos una orden a Roomba printf $roomba "%c",132; sleep 1; # FULL Tomamos control completo sobre ella

printf $roomba "%c",$value; sleep 1; # CLEAN OR DOCK Ejecutamos lo ordenado

kill 9,$pid; #Matamos el proceso de rfcomm

exit (0); #bye bye

Pero claro, la idea (al menos la mía) es hacer un programa que dependiendo de un montón de factores como qué horario es aceptable para pasar la aspiradora, control de presencia en casa (si estoy en casa, no la pases,… no sabéis el ruido que mete!), etc, etc,… puede ser interesante obtener información sobre los sensores de la misma. En mi caso, me interesa saber: La capacidad máxima de la batería; el modo de carga (esperando, cargando, etc,..), la carga actual de la batería, la temperatura de la batería, y si está conectada al cargador correctamente o no (si está en su base de carga o está dando vueltas por ahí). Para ello, el código se puede ver bajo estas líneas. Importante: en este caso contamos con una conexión rfcomm ya hecha en otro terminal!

_[root@Carmen tmp]# more roomba_sensors.pl _ #!/usr/bin/perl

$port="/dev/rfcomm2"; #el puerto serie a crear. Importante que no esté siendo usado ya

system("stty -F $port 115200 raw -parenb -parodd cs8 -hupcl -cstopb clocal"); #Parámetros necesarios para configuración del puerto

my $roomba;

open $roomba, "+>$port" or die "couldn't open port: $!"; select $roomba; $| =1; #Eliminamos lo que hubiera en el buffer en la lectura

printf $roomba "%c",128; sleep 1; # START Necesario cada vez que le demos una orden a Roomba

printf $roomba "%c%c%c%c%c%c%c",149,5,21,25,26,34,24; sleep 1; # Roomba requiere el envío del opcode 149 + el número de sensorIDs a solicitar + cada sensorID

#Sin embargo, devuelve byte a byte. Con esto perdí muuuucho tiempo porque no lo ví documentado en ningún sitio!!! _for ($i=0; $i<7; $i++) _ { $k=getc($roomba); $ok=ord ($k); print STDOUT "$i $ok\n"; }

Al ejecutarlo vemos algo como:

---------- 0 2 1 1 2 108 3 10 4 136 5 2 6 40 ------

La primera columna es un contador, sin más y la segunda, el valor del byte devuelto por la Roomba.

Byte Explicación

0 Estado de carga: 4 significa que está en Waiting (aunque la pongamos en su base, no cargará) y 2 es Full charge (que lo podemos poner a cargar) 1 Byte más significativo de carga actual de batería 2 Byte menos significativo de carga actual de batería 3 Byte más significativo de capacidad total de batería 4 Byte menos significativo de capacidad total de batería 5 Presencia de cargador (Fundamentalmente, si está la roomba en su base o no) Si el valor es 0 es que no (está por ahí limpiando) y 2 es que está en la base 6 Temperatura en grados celsius de la batería (Interesante por si queremos monitorizarlo)

Los bytes 1 y 2, así como el 3 y 4 indican la carga actual y la capacidad máxima de carga de la batería. El byte más significativo, en mi caso va de 0 a 10 y el menos significativo va de 0 a 255 (lógicamente es lo que cabe en un byte). Cuando se está descargando la batería, los bytes 1 y 2 van disminuyendo y al cargarse aumentando, hasta llegar a 10/136 que es la carga máxima de la batería.

Clone this wiki locally
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.