Bailando la roomba - I

"¡¡¡¡Si es que los de la roomba son tontos!!!!" es la frase que más se ha repetido en mi cabeza cada vez que he visto una roomba dándose golpes aleatorios por toda la casa hasta que vuelve a la base después de dejar media casa sin limpiar y haber pasado 5 veces por el mismo sitio.

Y tu también lo has pensado ¿verdad?

Pues me he propuesto mejorar esa programación y ... spoiler ... es matemáticamente imposible mejorar eso con los sensores que tenemos ... o yo también soy tonto. Ha sido mi lección de humildad del mes.

Este post va sobre como conectar una esp32-wroom a la roomba y el código con micropython que uso para navegar y que empiece a limpiar en la zona de la casa que yo quiero. Al final del post la demostración de porqué no se puede hacer bien no me ha dado tiempo a más hoy.

esp32-wroom vs arduino

Arduino está muy bien, yo tengo uno de cada y los he usado para trastear más que nada. Pero si quieres comunicación inhalámbrica es una lata tener que agregar modulitos wifi o bluetooth.

Además, a estas alturas tener que reservar memoria con c++ ... que no lo veo. Yo personalmente soy de la vieja escuela y no tengo un gran problema, pero es que no tiene sentido. Es como volver a los coches con starter para regular la mezcla.

En python el programa para sumar uno mas uno se escribe exactamente así: 1 + 1. No se porqué tenemos que agregar complejidad y menos todavía para gente que está empezando.

Arduino tiene la nano esp32 por 20€ que si te permite usar micropython: https://store.arduino.cc/en-es/products/nano-esp32

Sin embargo te puedes comprar en los chinos una esp32-wroom por 3€, que es la que voy a usar en este artículo.

La única pega que tiene es que los pines funcionan a 3.3v en vez de a 5v y para ciertas cosas necesitaremos un conversor de voltaje, pero ya lo veremos más adelante.

Conectando la esp32 a la roomba

Las roomba traen un puerto sci que tienen:

  • positivo y negativo entre 12v y 24v
  • puerto serie a 5v
  • pin para cambiar la velocidad del puerto serie

Antiguamente había un pin llamado DD para encender la roomba pero lo quitaron así que tendremos que hacer una ñapa para pulsar el botón sin pasar por el puerto serie.

Sacar 5v

La tierra o GND o negativo o negro o azul es común así que no tengas miedo de conectar la de la roomba directamente a la placa. Tienes que andarte con cuidado con la otra.

Yo he usado este módulo random al que le metes por la izquierda los pines de la roomba y te saca por la derecha 5 voltios. Puedes encontrar sucedáneos por menos de 1€ en los chinos buscando "Regulador de voltaje de 5V/1A".


roomba --12v--> reductor voltaje

reductor voltaje --5v--> level converter

Y ya tenemos nuestros 5 voltios para conectar cosicas a partir de la batería de la roomba.

¡¡CUIDADO!! 12 voltios en principio no son peligrosos para un ser humano, pero hablamos de un buen chispazo si te equivocas.

Comunicación

Usa un puerto serie a 5 voltios que tenemos que pasar a 3.3v.

Hay un modulo que hace exactamente eso, también por menos de 1€ en los chinos buscando "Convertidor de nivel lógico IIC I2C bidireccional". Por un lado metemos el positivo y negativo a 5v con los dos cables serial de la roomba a 5v.

CUIDADO: en HV1 y HV2 van los pines serial de la roomba. Se conectan y si no funcionan se les da la vuelta. ;-)

Por el otro metemos positivo y negativo de la esp32 con los cables serial de la roomba a 3.3v.

CUIDADO: no tengo a mano la esp32-wroom que recomiendo así que el pinout variará un poco, pero la idea se entiende. Busca los pines GND, 5V, RX y TX.

Por último tenemos el pin de BRC (Baud Change Rate), que no nos hace falta porque la roomba al arrancar va a 115200 baudios y el serie de esp32 soporta esa velocidad. Si usaras arduino SI te haría falta porque tendrías que bajar la velocidad. Otro punto más para esp32.

Al final mostraré la madeja de cables, porque para que no se vean y poder cerrar la tapa hay que aplastarlos, pasarlos por debajo de la placa, pegarlos ... un follón. Pero al final del día es hacer lo de arriba y si no funciona darle la vuelta a los cables serie. No tiene pérdida.

Encender y apagar la roomba

Yo al principio me volvía loco porque hacía todo bien pero la roomba no se daba por aludida hasta que un buen día se me ocurrió darle al botón de limpiar, que si le das una vez la enciende y si le das dos limpia, y la roomba empezó a hacerme caso.

¡¡Recuerda encenderla siempre!!

Al final del artículo agrego como hacer que la roomba se encienda desde python pero es algo opcional.

Manejando la roomba

DISCLAIMER: la documentación está mal

Toda la documentación que hay es para los modelos 600 pero tu tienes un modelo 800 ¿verdad? Pues se parecen como un huevo a una castaña.

La 600 devuelve distancias en milímetros, la 800 en algo parecido a centímetros, la 800 tiene luces que la 600 no tiene, ... y no existe documentación de estas diferencias en internet así que toca ir probando cosas.

Aquí solo voy a entrar en luces, motores y los sensores del bumper. Para el resto te las vas a tener que apañar tu.

Aquí te dejo enlaces a los tres documentos que hay:

Instalando micropython

Lo normal con Arduino sería que tienes tu programa, lo compilas, lo envías al microcontrolador y se ejecuta.

Con micropython tu programa se va a tratar como si fueran datos del verdadero programa, que es micropython. Hay que flashear micropython en el microcontrolador y micropython ya sabe que cuando arranque tiene que buscar un archivo llamado main.py y ejecutar lo que haya en él.

Hay muuuuchas guías en internet para hacerlo tanto en línea de comandos como con Thonny así que no voy a perder el tiempo explicándolo.

En Linux, recuerda agregar tu usuario en el grupo dialout si no lo está.

Visual Studio Code

Programar con Thonny, por lo menos para mi, es un horror.

Prefiero usar un IDE que pueda conectar a una IA usando continue.dev y escriba el código por mi.

Hay un addon que funciona tanto en vscode como en vscodium llamado MicroPico.

Si lo instalas correctamente, conectas el dispositivo con micropython y pulsas abajo donde pone Toggle Pico-W-FS, verás que a la izquierda te aparecen los archivos main.py y boot.py. Esos archivos están dentro de tu esp32, los podrás editar al vuelo, almacenarlos en la placa y si le das a Run, ejecutarlos. Ya iremos más al lío luego.

Probando la roomba

Abre main.py y escribe esto:

import time
from machine import UART

# Hace que el puerto acepte comandos
START = bytes([128])
# Si ocurre alguna colisión, ¡¡detente!!
# No tengo claro que esté funcionando este modo en las series 800 porque cuando se choca las ruedas siguen girando.
SAFE_MODE = bytes([131])
# Gira a la derecha
DRIVE_RIGHT = bytes([137]) + bytes([0, 100, 255, 255])
# Gira a la izquierda
DRIVE_LEFT = bytes([137]) + bytes([0, 100, 0, 1])
# Ruedas quietas
STOP = bytes([137, 0, 0, 0, 0])  # velocidad 0, radio 0

# Yo usé los pines 16 y 17. No se porqué no usé los RX y TX. :-D
uart = UART(1, baudrate=115200, tx=17, rx=16)

# Initialize Roomba sci port
uart.write(START)
time.sleep(0.2)
uart.write(SAFE_MODE)
time.sleep(0.2)

uart.write(DRIVE_LEFT)
time.sleep((1.65 * angle)/90)
uart.write(STOP)

uart.write(DRIVE_RIGHT)
time.sleep((1.65 * angle)/90)
uart.write(STOP)

main_loop():
    time.sleep(10000)

main_loop()

Si la roomba gira a la izquierda 90 grados y a la derecha otros 90 grados ¡¡felicidades, ya puedes empezar!!

Si no funciona, intercambia los pines rx y tx y vuelve a probar.

Si tampoco funciona no se que decirte ¿te acordaste de darle al botón de clean para encenderla?

Si sigue sin funcionar ... comprueba los cables.

Ahora si: encender la roomba desde python

Tienes que elegir un pin de la esp32, en mi caso elegí el 32, y en ese pin conectas un relé de los que van a 3.3v. Son bastante caros para mi gusto, unos 2€ o 3€, pero es la solución más correcta que se me ocurre. Busca "rele 3.3v" y te saldrán unos cuantos.

Aquí no queda más remedio que sacar el soldador y una lupa ... o un móvil con macro como tengo yo. Si sigues las pistas del interruptor verás que llegan a dos componentes ... pues ahí es donde tienes que soldar los dos cables para llevarlos al relé.

Por el lado del esp32, sacar dos cables, positivo del pin 32 y negativo de GND.

Encender la roomba es tan fácil como ejecutar esto:

import time
from machine import Pin

power_button = Pin(32, Pin.OUT)
power_button.value(1)
time.sleep(0.2)
power_button.value(0)
time.sleep(1)
print("powered on")

main_loop():
    time.sleep(10000)

main_loop()

En mi caso yo no tenía un relé a mano y no me apetecía esperar a que llegara de los chinos así que me busqué un transistor reciclado de una televisión rota para hacer de interruptor, pero lo suyo es usar un relé:

Fotos de mi montaje

Por si te sirven de algo:

Detalle de las conexiones en la esp32. Fíjate que la mayor parte son conexiones a GND por aprovechar los pines. Realmente ahí hay solo 5 cables:

  • rojo a 3.3v
  • rojo a 5v
  • todos los azules que podrían ser uno solo
  • serie TX amarillo
  • serie RX verde

Fíjate en que he tenido que romper algunos plásticos para que entre la placa:

La roomba se mueve y eso puede hacer que se rompa el conector micro-usb así que tengo un cable con imán:

Al final debería quedar esto:

Hasta aquí los cables, que es lo menos importante

Lo importante es la navegación y eso no lo he tocado pero este post me ha quedado un poco largo así que lo vemos en el siguiente.