Control de robots móviles con el MCU Dual One

EN143 - Control de robots móviles con la Dual One - Banner s letras

En este tutorial se desarrollará un controlador para un robot móvil tipo tanque utilizando la MCU Dual One de Unit Electronics. El objetivo es implementar un sistema de control basado en un control remoto tipo PS2, permitiendo manejar el movimiento del robot de forma intuitiva y precisa.

Para ello, se utilizará la base móvil del Kit Robot Móvil con Garra G8 + Control Joystick, junto con la tarjeta UNIT DualMCU ONE (ESP32 + RP2040). Este kit ya incluye los elementos necesarios para comenzar, integrando motores, estructura mecánica y los módulos de control requeridos para el desarrollo.

A lo largo del artículo, se mostrará cómo estructurar el código en CircuitPython para abstraer el control del hardware en una clase, facilitando la lectura del control remoto y el manejo de los motores. De esta forma, se podrá construir un sistema de control reutilizable y fácil de adaptar para otros proyectos de robótica móvil.

Material

EN143 - Control de robots móviles con la Dual One - StarterPack

Introducción

El control de un robot móvil, incluso en su forma más básica, implica una cadena clara de procesamiento de información: una entrada del usuario, una interpretación de esa entrada y una acción física ejecutada por el sistema. En este tutorial se abordará precisamente ese flujo, utilizando un control remoto tipo PS2 como interfaz de entrada para gobernar un robot móvil tipo tanque.

El punto de partida es el mando PS2, que actúa como el dispositivo de interacción. A través de sus joysticks y botones, se generan señales que representan la intención del usuario: avanzar, retroceder, girar o detenerse. Estas señales no se utilizan directamente, sino que deben ser leídas e interpretadas por la unidad de procesamiento.

Aquí es donde entra la MCU Dual One, la cual se encarga de recibir estos datos, procesarlos y transformarlos en comandos de control. Este proceso implica mapear las entradas del control (valores analógicos y digitales) a salidas concretas para los motores, considerando aspectos como dirección, velocidad y tipo de movimiento.

Finalmente, estos comandos se traducen en señales eléctricas que accionan los motores del robot, permitiendo un movimiento diferencial característico de plataformas tipo tanque. De esta manera, se completa el ciclo: desde la intención del usuario hasta la respuesta física del sistema.

EN143 - Control de robots móviles con la Dual One - Diagrama 01

A lo largo del artículo, este flujo se implementará utilizando CircuitPython, organizando el código de tal forma que el manejo del control y del hardware quede encapsulado en una estructura clara y reutilizable. Esto no solo facilita el desarrollo, sino que permite escalar el sistema hacia aplicaciones más complejas en robótica móvil.

EN143 - Control de robots móviles con la Dual One - CircuitPython

Desarrollo

1. Instalación del entorno de programación

Para comenzar con el desarrollo de la aplicación, es necesario instalar CircuitPython en la tarjeta. Dado que la DualMCU ONE integra un RP2040 para el manejo de los GPIOs, se utilizará la imagen .UF2 correspondiente a la Raspberry Pi Pico, disponible en:

https://circuitpython.org/board/raspberry_pi_pico

Una vez descargado el archivo, es necesario colocar el microcontrolador en modo de programación. Para ello, se debe mantener presionado el botón BOOT mientras se conecta la tarjeta al puerto USB. Esto hará que el dispositivo entre en modo bootloader y sea reconocido por la computadora como una unidad de almacenamiento externa con el nombre RPI-RP2.

EN143 - Control de robots móviles con la Dual One - RP2040 bootloader

En este punto, el proceso es directo: basta con copiar el archivo .uf2 descargado dentro de esta unidad. Al hacerlo, el microcontrolador se reiniciará automáticamente y montará una nueva unidad de almacenamiento, que corresponde al entorno de CircuitPython.

EN143 - Control de robots móviles con la Dual One - Arrasrar archvio

A partir de este momento, el dispositivo estará listo para programarse en Python, permitiendo editar y ejecutar código directamente desde los archivos contenidos en esta unidad. Nosotros utilizaremos Visual Studio Code para programar la aplicación.

EN143 - Control de robots móviles con la Dual One - VSCode Tree

2. Recepción de señales del control PS2

Para empezar a programar, comenzaremos con la lectura de las señales del control remoto mediante un HAT de comunicación diseñado para Arduino, el cual se encarga de gestionar la interfaz con el mando tipo PS2. Una ventaja importante de la UNIT DualMCU ONE es que mantiene el mismo formato físico que un Arduino, por lo que este tipo de módulos se puede montar directamente sin necesidad de adaptaciones adicionales.

EN143 - Control de robots móviles con la Dual One - DualOne
Dual One Pinout

En esta etapa, el objetivo es únicamente recibir y visualizar la información del control. Para ello, se implementa una lectura periódica del estado del mando, identificando qué botones están siendo presionados y cuáles son los valores analógicos de los joysticks.

Configuración

Antes de poder utilizar el control PS2 como interfaz de entrada, es necesario inicializar correctamente la comunicación con el dispositivo. Esta configuración se realiza dentro de la función setup(), donde se establece la conexión entre el microcontrolador y el mando.

EN143 - Control de robots móviles con la Dual One - Code v06 - setup function

En esta etapa, se utiliza la función config_gamepad(), la cual recibe los pines definidos para la comunicación (CLK, CMD, SEL y DAT), así como parámetros adicionales como la lectura de presión en botones y la activación de vibración. Esta función devuelve un código de estado que permite identificar si la configuración fue exitosa o si existe algún problema en la conexión.

Para facilitar la depuración, se asocia este código con una serie de mensajes descriptivos que se imprimen en la terminal. Esto permite saber rápidamente si el control fue detectado correctamente, si responde a comandos o si existe algún error en el cableado.

Adicionalmente, se consulta el tipo de controlador mediante readType(), lo cual resulta útil para verificar que el dispositivo conectado corresponde a un control compatible, como un DualShock.

Lectura de datos

Una vez inicializada la comunicación, el siguiente paso consiste en leer continuamente el estado del control. Esta tarea se encapsula en la función getControllerStatus(), la cual centraliza la obtención de toda la información relevante del mando.

EN143 - Control de robots móviles con la Dual One - Code v07 - Controller update function

Internamente, esta función actualiza el estado del control mediante read_gamepad(), y posteriormente construye dos estructuras principales: una lista con los botones presionados y un arreglo con los valores analógicos de los joysticks.

Para los botones, se realiza una iteración sobre todos los posibles inputs, verificando cuáles se encuentran activos en ese instante. En caso de detectar una pulsación, se traduce a un código más manejable y se almacena en una lista. Esto permite trabajar con eventos discretos de forma sencilla.

Por otro lado, los joysticks se leen como valores analógicos, representando la posición de cada eje. Estos valores son fundamentales para el control del robot, ya que permiten definir tanto la velocidad como la dirección del movimiento.

Finalmente, la función devuelve ambos elementos: los botones presionados y el estado de los joysticks. Esta información es utilizada dentro del ciclo principal del programa, donde se consulta continuamente el estado del control para tomar decisiones en tiempo real.

De esta manera, se establece una base sólida para el sistema de control, separando claramente la lectura del hardware de la lógica de movimiento del robot.

EN143 - Control de robots móviles con la Dual One - Control Response

3. Diagrama de conexión (para motores) y programación de los motores.

Una vez que se cuenta con la lectura de las señales del control PS2, el siguiente paso es interpretar esta información para generar movimiento en el robot. Para ello, es necesario establecer la conexión entre el HAT y los motores, donde las salidas de potencia permiten controlar cada motor de forma independiente.

EN143 - Control de robots móviles con la Dual One - Diagrama conexion
Diagrama conexion

Para poder controlar el robot de forma ordenada, primero se desarrolló una clase dedicada exclusivamente al manejo del hardware. Esta clase encapsula toda la lógica necesaria para controlar los motores, evitando tener que trabajar directamente con señales PWM desde el programa principal.

De esta forma, en lugar de manipular pines o cálculos de bajo nivel, el control del robot se reduce a utilizar funciones bien definidas que reciben parámetros de alto nivel, como dirección y sentido de movimiento.

EN143 - Control de robots móviles con la Dual One - Code v01 - Tank class

Dentro del constructor de la clase se realiza la inicialización de los motores. Se configuran cuatro pines como salidas PWM, dos por cada motor, lo que permite controlar tanto la dirección como la velocidad de giro. Cada motor se define con una estructura de tipo diccionario que separa las señales positivas y negativas, lo cual facilita invertir el sentido de giro sin necesidad de lógica adicional externa.

Además, se inicializan variables internas que almacenan el estado actual de cada motor. Esto es importante porque posteriormente se utilizarán para implementar un control de aceleración, evitando cambios bruscos en la velocidad.

Una vez definida la clase encargada del hardware, el siguiente paso consiste en procesar las señales que provienen del control. Los joysticks entregan valores analógicos en un rango de 0 a 255, por lo que es necesario transformarlos a un formato más útil para el control del robot.

EN143 - Control de robots móviles con la Dual One - Code v03 - Loop functions

En esta parte del código, los valores crudos de los joysticks se convierten a un rango de -100 a 100. Esto permite interpretar fácilmente el movimiento: valores positivos representan avance o giro en un sentido, mientras que los negativos indican retroceso o giro contrario.

Adicionalmente, se invierte uno de los ejes para que el comportamiento del control sea más natural al momento de operar el robot. Con esta transformación, el sistema deja de depender de valores específicos del hardware y pasa a trabajar con porcentajes de movimiento, lo cual simplifica mucho la lógica de control.

Una vez que las señales están procesadas, se envían a la función encargada de controlar el movimiento del robot. Esta función es el núcleo del sistema, ya que traduce comandos de alto nivel en señales reales para los motores.

EN143 - Control de robots móviles con la Dual One - Code v05 - method class control motor

La función control_analogico() recibe dos parámetros: uno para el sentido de avance y otro para la dirección. A partir de estos valores, calcula la velocidad individual de cada motor utilizando un esquema de control diferencial, típico en robots tipo tanque.

Esto permite que el robot no solo avance y retroceda, sino que también pueda girar suavemente o incluso sobre su propio eje, dependiendo de la combinación de señales.

Un detalle importante es que no se aplican directamente los cambios de velocidad. En su lugar, se calcula la diferencia entre el valor actual y el nuevo valor deseado, y se limita cuánto puede cambiar en cada ciclo. Este mecanismo actúa como un control de aceleración, reduciendo picos de corriente y haciendo que el movimiento del robot sea mucho más suave.

Finalmente, los valores calculados se convierten en señales PWM que se envían a los pines correspondientes de cada motor, definiendo tanto la velocidad como el sentido de giro.

Este enfoque permite separar completamente la lógica de control del hardware físico. Desde el programa principal únicamente se envían comandos simples, mientras que toda la complejidad queda contenida dentro de la clase. Esto no solo facilita el desarrollo, sino que también hace que el código sea reutilizable para otros proyectos de robótica móvil.

EN143 - Control de robots móviles con la Dual One - Control motores v02
EN143 - Control de robots móviles con la Dual One - Control motores v01

4. Repositorio

El código completo de esta implementación se encuentra disponible en el repositorio de GitHub de Unit Electronics, donde es posible revisar tanto el ejemplo principal como la librería desarrollada para el control del robot: https://github.com/UNIT-Electronics-MX/unit_mobile_platform_ps2x_controller_firmware

Para descargarlo, basta con clonar el repositorio:

git clone https://github.com/UNIT-Electronics-MX/unit_mobile_platform_ps2x_controller_firmware

El código de ejemplo se encuentra en la ruta software/examples/code.py, mientras que la implementación de la clase encargada del control del robot está ubicada en software/unit_elec/tank.py.

A partir de este punto, se puede modificar, extender o reutilizar la lógica presentada para desarrollar nuevas aplicaciones sobre la plataforma.

EN143 - Control de robots móviles con la Dual One - Robot final

Conclusiones

El desarrollo de este proyecto permitió implementar un sistema completo de control para un robot móvil tipo tanque utilizando la UNIT DualMCU ONE y un mando PS2 como interfaz de entrada. A lo largo del tutorial se mostró cómo recibir señales del controlador, procesarlas y transformarlas en comandos de movimiento para los motores mediante CircuitPython. Además, se desarrolló una clase dedicada al control del hardware, permitiendo encapsular toda la lógica de manejo de motores y facilitando la reutilización del código en otros proyectos de robótica móvil. También se implementó un control de aceleración progresiva para obtener movimientos más suaves y reducir picos de corriente en los motores. Este tipo de arquitectura no solo simplifica el desarrollo de aplicaciones embebidas, sino que establece una base sólida para futuros proyectos más avanzados, como robots autónomos, sistemas de navegación o integración de sensores y comunicación inalámbrica. Muchas gracias por leer. Nos vemos pronto. 👋

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *