Emulación de Zumo32U4 con un Arduino


El Zumo 32U4 es un robot sumo compacto y altamente integrado basado en el microcontrolador Arduino compatible ATmega32U4. Mide menos de 10×10 cm y pesa alrededor de 160 gramos sin baterías, lo que le hace apto para competiciones Mini-Sumo. Está equipado con dos motores de alta potencia con reductora (modelos comunes incluyen reductoras de 50:1, 75:1 o 100:1), un controlador dual de motores, encoders para control cerrado, pantalla OLED programable y múltiples sensores (de línea, proximidad frontal y lateral, además de una unidad de medición inercial IMU con acelerómetro, giroscopio y magnetómetro).

El robot es programable directamente desde el entorno Arduino y no requiere montaje previo, solo es necesario añadir baterías y un cable USB para programarlo. Cuenta con sensores para detectar el enemigo en combates de sumo, así como opciones para personalización avanzada mediante acceso a líneas I/O y alimentación del microcontrolador. Además, tiene botones, un buzzer y LEDs para interacción y retroalimentación visual.

Como comentábamos el robot cuenta con dos motores con reductora (por ejemplo, reductoras de 75:1), sensores de proximidad y línea, encoders para el control de movimiento, y una pantalla de dos lineas LCD en su primer version y pantalla OLED en su ultima version para mostrar información. Además, incluye un conjunto variado de sensores como un arreglo frontal para detección, una unidad de medición inercial (IMU) que incorpora acelerómetro, giroscopio y magnetómetro, así como botones, LEDs y un buzzer para interacción. Se programa con facilidad a través del entorno Arduino, lo que permite desarrollar comportamientos avanzados para combate o exploración.

Es adecuado tanto para proyectos educativos como para competiciones gracias a su configuración lista para usar y su capacidad de personalización mediante programación.

Ahora vamos a ver como es posible emular este simpático robot con componentes que podemos tener en nuestro cajón: un arduino uno, teclas , leds, el controlador l29c, una pantalla LCD y dos motorzitos de 12 V.

Emulacion del Zumo

Emular el Zumo 32U4 con una placa sencilla ATmega (tipo Uno o Nano) tiene bastante sentido en varios planos: técnico, económico y docente​

En primer lugar, el coste y la disponibilidad. Un Zumo 32U4 completo con motores, encoders, sensores de línea, proximidad, IMU y pantalla OLED es una plataforma potente pero relativamente cara y no siempre accesible para cada alumno o cada experimento. Con un ATmega328P, un L298N, un par de DC pequeños, unos pulsadores, LEDs y un LCD I2C puedes replicar buena parte de la interfaz (botones, LEDs, display, buzzer y movimiento) por una fracción del coste, permitiendo tener más “robots” en el aula o en el laboratorio casero sin miedo a estropear hardware caro.​

En segundo lugar, el control total del hardware y el aprendizaje de bajo nivel. El Zumo 32U4 “real” viene muy integrado: los motores, drivers, sensores y la propia placa están ya cableados y abstraídos con la librería Zumo32U4, lo que es ideal para proyectos rápidos pero oculta parte de la electrónica y del mapeo de pines. Al emularlo con un ATmega sencillo obligas a cablear tú mismo drivers, botones, buzzer y pantalla, a elegir pines, a entender PWM, direcciones de motor y pull-ups internos. Esto encaja muy bien con objetivos formativos en electrónica, microcontroladores y arquitectura Arduino, no solo en “programación de robots”.​

En tercer lugar, la compatibilidad y la experimentación con código. La librería oficial de Pololu está pensada para ATmega32U4, pero muchos conceptos (máquinas de estados, control de motores, secuencias de LEDs, patrones de buzzer o menús de pantalla) se pueden portar y probar sobre un Uno emulando la API básica. Eso te permite desarrollar y depurar lógica de alto nivel (estrategias de sumo, sigue-líneas, evasión de obstáculos) sin tener aún el Zumo físico, o manteniendo el Zumo “real” para demostraciones mientras las iteraciones de código se prueban en clones baratos​

Por último, está la robustez y el enfoque de investigación/experimentación. Con una plataforma emulada puedes introducir fallos controlados (desconectar un encoder, simular un motor más lento, cambiar relaciones de transmisión, probar distintos drivers H-bridge) sin riesgo para un robot cerrado y más delicado. Para clases, TFG/TFM o artículos que comparan arquitecturas, tener una versión “abierta” con ATmega sencillo te da más libertad de instrumentación, medición y modificación hardware que el Zumo comercial, manteniendo al mismo tiempo la referencia funcional de lo que hace el modelo original.​

Veamos ya sin mas dilaciones la emulación del Zumo que proponemos desde este blog , la cual como podemos ver en el siguinte video es totalmente funcional y ha sido probada exhaustivamente

Conexiones de los Pulsadores

Los tres pulsadores del Zumo 32U4 están conectados a pines específicos del ATmega32U4 para entrada digital: Button A en el pin Arduino 14 (PB3/MISO), Button B en el pin PD5 (Green LED/TXL, compartido), y Button C en el pin 17 (PB0/SS, también Red LED/RXL). Estos pines permiten detectar pulsaciones mediante lectura digital y soportan interrupciones de cambio de pin (PCINT).

Conexiones de los Motores

Los dos motores se controlan mediante drivers H-bridge en el montaje se ha usado un L298C) con pines PWM y dirección: el motor izquierdo usa PWM en pin Arduino 10 (PB6/OC1B), dirección en pin 16 (PB2/MOSI); el motor derecho usa PWM en pin 9 (PB5/OC1A), dirección en pin 15 (PB1/SCK). Estos pines admiten salidas PWM para control de velocidad y lógica de dirección para giro.

Conexión del Buzzer

El buzzer está conectado al pin Arduino 6 (PD7/OC4D), que proporciona salida PWM de hardware para generar tonos y música alternando alto/bajo a frecuencias específicas. Puede desconectarse cortando un jumper superficial si se necesita el pin para otro uso.

Pines para Pulsadores

Para simular los tres pulsadores (A, B, C) en Arduino Uno, conectamos pulsadores normalmente abiertos reciclados de otros circuitos. Al ser entradas con pull-up interno no se necesitan resistencias externas (10kΩ a 5V):

  • Pulsador A: Pin digital 14 (equivalente a PB3/MISO en 32U4) → usa pin 8 en Uno.
  • Pulsador B: Pin digital PD5 (Green LED/TX) → usa pin 7 en Uno.
  • Pulsador C: Pin digital 17 (PB0/SS, Red LED/RX) → usa pin 2 en Uno.

Lee con digitalRead() y debounce en software, similar a la librería Zumo32U4.

Pines para Motores

Controla los motores con drivers H-bridge (ej. L298N o TB6612) replicando PWM y dirección:

  • Motor izquierdo: PWM pin 10 (PB6) → pin 9 en Uno; Dirección pin 16 (PB2) → pin 6 en Uno.
  • Motor derecho: PWM pin 9 (PB5) → pin 10 en Uno; Dirección pin 15 (PB1) → pin 5 en Uno.

Avanzado: se puede usar analogWrite() para PWM y digitalWrite() para dirección; adaptando encoders a pines interrupción como 2/3 si los incluyes.

Pin para Buzzer

Conecta el buzzer (positivo a pin, negativo a GND) al pin 6 (PD7/OC4D) del 32U4 → pin 11 en Uno.

Genera tonos con tone(11, frecuencia) o PWM manual para música, replicando la librería ZumoBuzzer ( lo veremos mas adelante).

Notas: Arduino Uno (ATmega328P) no tiene ATmega32U4 nativo, así que ajusta código (sin USB nativo, librerías Zumo32U4 no son compatibles directamente). Usa pines libres para sensores adicionales; prueba con sketch básico de motores/botones primero.

Confirmación de Placa

La Arduino Uno R3 con ATmega328P es perfecta para simular el Zumo 32U4, ya que tiene suficientes pines digitales PWM (6), analógicos y interrupciones para replicar motores, pulsadores y buzzer. Cuenta con 14 pines digitales (0-13), 6 PWM (3,5,6,9,10,11) y memoria suficiente para código Zumo adaptado.

Pines Recomendados (Actualizados para Uno R3)

Usa esta asignación optimizada para ATmega328P, priorizando PWM e interrupciones:

Pulsadores (con pull-up interno via INPUT_PULLUP):

  • Pulsador A: Pin A0
  • Pulsador B: Pin d4
  • Pulsador C: Pin d3 (interrupción INT0)

Motores (con driver H-bridge como L298N/TB6612FNG):

  • Motor Izq. PWM: Pin d9
  • Motor Izq. Dirección: Pin A2
  • Motor Der. PWM: Pin D10
  • Motor Der. Dirección: Pin A1

Display LCD (dirección 0X3F):

  • SDA: Pin A4
  • SCL: Pin A5

Buzzer: Pin D6 (PWM para tone())

Extras útiles:

  • Encoders: Pines 2 y 3 (interrupciones)
  • Sensores línea: Pines analógicos A0-A5.

Código Base de Ejemplo

A continuación vamos a ver un ejemplo algo mas elaborado del tipico led parpadeante usando los pulsadores. el lcd y los leds que hemos conectado a la placa Atmega con las conexiones apuntadas anteriormente:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

//El LED amarillo debe:
//Pulsar A → ENCENDER (permanece encendido aunque sueltes)
//Pulsar B → APAGAR (permanece apagado hasta nuevo A)

LiquidCrystal_I2C lcd(0x3F, 16, 2);

#define BUTTON_A_PIN A0
#define BUTTON_B_PIN 4
#define BUTTON_C_PIN A3
#define LED_YELLOW_PIN 13
#define LED_RED_PIN 12

bool ledYellowState = false; // Estado RECORDADO del LED amarillo
bool lastBtnA = false; // Estado anterior botón A (anti-rebote)
bool lastBtnB = false; // Estado anterior botón B (anti-rebote)

void setup() {
Wire.begin();
lcd.init(); lcd.backlight(); lcd.clear();
lcd.setCursor(0,0); lcd.print("Zumo32U4 Toggle");
delay(1500);

pinMode(BUTTON_A_PIN, INPUT_PULLUP);
pinMode(BUTTON_B_PIN, INPUT_PULLUP);
pinMode(BUTTON_C_PIN, INPUT_PULLUP);
pinMode(LED_YELLOW_PIN, OUTPUT);
pinMode(LED_RED_PIN, OUTPUT);
}

void loop() {
bool btnA = digitalRead(BUTTON_A_PIN) == LOW;
bool btnB = digitalRead(BUTTON_B_PIN) == LOW;
bool btnC = digitalRead(BUTTON_C_PIN) == LOW;

// DETECTAR FLANCO ↓ (pulsación, no mantener)
bool btnA_pressed = btnA && !lastBtnA; // Solo en el momento de pulsar
bool btnB_pressed = btnB && !lastBtnB;

// TOGGLE LED AMARILLO
if (btnA_pressed) {
ledYellowState = true; // ← ENCIENDE (latch)
}
if (btnB_pressed) {
ledYellowState = false; // ← APAGA (latch)
}

// Aplicar estado al LED
digitalWrite(LED_YELLOW_PIN, ledYellowState);

// LED ROJO: ON cuando botón A NO está pulsado (comportamiento anterior)
digitalWrite(LED_RED_PIN, !btnA);

// Actualizar display
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("A:"); lcd.print(btnA ? "ON " : "OFF");
lcd.print("B:"); lcd.print(btnB ? "ON " : "OFF");
lcd.print("C:"); lcd.print(btnC ? "ON" : "OFF");

lcd.setCursor(0, 1);
lcd.print("Yel:"); lcd.print(ledYellowState ? "ON " : "OFF");
lcd.print("Red:"); lcd.print(digitalRead(LED_RED_PIN) ? "ON" : "OFF");

// Guardar estados anteriores (anti-rebote)
lastBtnA = btnA;
lastBtnB = btnB;

delay(50);
}

Este programa controla dos LEDs (amarillo y rojo) y muestra el estado de tres pulsadores en un LCD I2C de 16×2, emulando parte de la interfaz de un Zumo32U4 con un ATmega328P. En setup() inicializa el bus I2C, el display (dirección 0x3F), enciende la retroiluminación y configura los pines de los botones con INPUT_PULLUP (reposo en HIGH, pulsado en LOW) y los LEDs como salidas. El comentario inicial indica la intención: el LED amarillo debe encenderse al pulsar A y permanecer encendido aunque se suelte, y apagarse al pulsar B y permanecer apagado hasta una nueva pulsación de A.​

En el loop(), el código lee el estado actual de los tres botones y calcula dos señales de flanco descendente (btnA_pressed y btnB_pressed): solo se ponen a true cuando se detecta un cambio de no pulsado a pulsado, usando las variables lastBtnA y lastBtnB como memoria simple de anti-rebote. Si se detecta una pulsación de A, la variable ledYellowState pasa a true y el LED amarillo se enciende; si se detecta una pulsación de B, ledYellowState pasa a false y el LED se apaga, de modo que el LED amarillo queda “latched” hasta la siguiente orden, no depende de mantener el botón. El LED rojo se enciende siempre que el botón A no esté pulsado (!btnA), de forma directamente ligada al estado instantáneo del botón.​

Finalmente, el programa actualiza el LCD en cada pasada borrando la pantalla y escribiendo en la primera línea el estado ON/OFF de los botones A, B y C, y en la segunda línea el estado de los LEDs amarillo y rojo, lo que permite ver en tiempo real tanto las lecturas de los pulsadores (con lógica de INPUT_PULLUP) como el estado memorizado del LED amarillo. Tras actualizar el display, guarda los estados actuales de A y B en lastBtnA y lastBtnB para la siguiente detección de flancos, y añade un delay(50) que ayuda a estabilizar lecturas y reducir rebotes sin bloquear en exceso el sistema.​

Como obtener el numero llamante con Arduino


CLI, también conocido como Identificador de llamadas y entrega de números de llamada (CND), es un servicio ofrecido por el proveedor de servicios telefónicos a los clientes para obtener el número de parte que llama y la fecha / hora de la llamada. La activación del servicio y el formato de información de la CLI son diferentes de un operador de red telefónica a otro.

Para decodificar la modulación FSK del número llamante (Caller ID) de forma sencilla con Arduino, la forma más práctica es usar un módulo decodificador dedicado como el HT9032D que soporta la decodificación FSK Bell 202, que es el estándar usado para enviar la información del número llamante en sistemas analógicos telefónicos. Este módulo se conecta entre la línea telefónica (RJ11) y el Arduino, que recibe los datos ya demodulados en forma digital serial para procesarlos y mostrar el número en una pantalla LCD o enviar la información por puerto serie.

Hardware mínimo

  • Arduino (cualquier modelo básico como Arduino Uno o Nano es suficiente).
  • Módulo demodulador FSK Bell 202, típicamente el HT9032D:
    • Este módulo convierte la señal FSK analógica de la línea telefónica en una señal digital serial que el Arduino puede leer.
  • Aislamiento y acoplamiento a línea telefónica:
    • Un adaptador o un transformador de audio para aislar eléctricamente la línea telefónica del Arduino y proteger el equipo.
    • Resistencias y condensadores para el acoplamiento y filtrado según el esquema del módulo HT9032D.
  • Fuente de alimentación estable para Arduino y el módulo.

Opcionales (pero recomendados)

  • Pantalla LCD o display serial para mostrar el número llamante.
  • Cables y conectores RJ11 para conectar la línea telefónica al módulo demodulador.

Resumen de los componentes:

ComponenteFunción
Arduino Uno/NanoProcesa la señal digital decodificada
Módulo HT9032DDemodula la señal FSK analógica
Aislamiento (transformador)Protección y acoplamiento a la línea telefónica
Cables RJ11Conexión con línea telefónica

Este conjunto es el hardware mínimo básico para un sistema funcional de decodificación de Caller ID FSK con Arduino sin desarrollar desde cero la parte de demodulación FSK, lo que implicaría más componentes analógicos y circuitos complejos.

El HT9032D es un circuito integrado específicamente diseñado para la decodificación de señales FSK Bell 202, que es el esquema de modulación utilizado en las señales de Caller ID en líneas telefónicas analógicas. Funciones principales del HT9032D:

  • Demodula la señal FSK recibida desde la línea telefónica, convirtiendo las variaciones de frecuencia en datos digitales seriales.
  • Soporta la decodificación del protocolo estándar Bell 202 para Caller ID.
  • Proporciona una salida digital compatible con microcontroladores como Arduino para facilitar la lectura de los datos.
  • Incluye control y filtrado interno para separar la información útil relacionada con el número llamante (MDMF).

Desde la hoja de características del fabricante Holtek podemos ver un ejemplo típico de aplicación:

Vemos en el circuito como la señal de la línea telefònica en lugar de usar un transformador usa dos condensadores de 0.2microFaradios cuyos extremos van acoplados a un puente de diodos y su salida mediante un divisor de tensión es la que usaremos en el microcontrolador como RING-SENSE. Además de la línea telefónica también directamente van sendas resistencias de 200k y condensadores de 0.01microFaradios hacia los pines TIP y RING del. Respecto a la parte superior derecha, es solo opcional y es la parte de alimentación de 5V DC pues HT1050 es simplemente un regulador de 5v del propio fabricante.

Ojo porque el esquema entregado por el fabricante anterior presenta varias imprecisiones respecto al terminal X2 y las conexiones del microcontrolador, por lo que es mejor usar el siguiente esquema:

Es interesante destacar como la señal de la línea telefònica en lugar de usar un transformador usa dos condensadores de 0.2microFaradios cuyos extremos van acoplados a un puente de diodos y su salida mediante un divisor de tensión es la que usaremos en el microcontrolador como RING-SENSE.

Asimismo de la línea telefónica directamente también mediante sendas resistencias de 200k y condensadores de 0.01microFaradios son las señales de TIP y RING que van conectados directamente al chip.

El circuito se complementa con un circuito resonante conectados a los terminales X1 y X2 (ojo porque en el esquema del fabricante han obviado el terminal X2). Este circuito esta conectado al chip por un cristal del cuarzo de 3.58Mhz, una resistencia de 10M en paralelo y dos pequeños condensadores de 33pF conectados a masa. Por cierto, la señal PDWN se obtiene del chip derivándola también a masa con una resistencia de 22k

Por ultimo la salida de DATA del chip corresponde a la salida DOUT que usaremos en el microcontrolador.

En la imagen podemos ver el circuito montado, aunque si lo deseamos dado el numero reducido de componentes ( 7 resistencia s y 7 condensadores , el puente, el cristal y el chip HT9032D) también podemos montar en una placa de prototipos.

Este es el detalle de los componentes:

  • C1, C3 : 0.01μF / 400V Mylar Capacitor
  • C2 : 0.1μF / 50V Mylar Capacitor
  • C4, C5 : 33pF Ceramic Capacitor
  • C6, C7 : 0.22μF / 400V Mylar Capacitor
  • D1 : 2W10 Bridge rectifier
  • R1, R2 : 200KΩ
  • R3 : 22KΩ
  • R4 : 10MΩ
  • R5 : 470KΩ
  • R6 : 18KΩ
  • R7 : 15KΩ
  • U1 : HT9032D (DIP-8)
  • Y1 : 3.58MHz (HC49) Crystal
  • J1 : Molex 52018-6616 or equivalent RJ11 / 6P6C PCB socket
  • J2 : 5-pin 2.54mm Pin header

Como vemos pues en resumen , estas son las fases para obtener el numero llamante:

  • Utilizar un módulo HT9032D (o similar) para demodular la señal FSK de la línea telefónica.
  • Conectar el pin de salida digital (DATA OUT) del módulo HT9032D a una entrada RX del Arduino.
  • El Arduino lee la señal digital, que sigue el protocolo Bell 202 (1200 baud, mark 1200Hz, space 2200Hz).
  • Procesar la trama de datos MDMF (Multiple Data Message Format) para extraer el número llamante, fecha y hora.
  • Opcionalmente mostrar esos datos en un display LCD o enviarlos a un ordenador.

Ventajas de esta configuración:

  • No se requiere implementar desde cero la demodulación FSK (que es compleja).
  • El HT9032D está específicamente diseñado para este propósito.
  • Hay ejemplos de códigos para Arduino que leen los datos y los decodifican fácilmente.

Ejemplo de uso

Se pueden encontrar esquemas y código Arduino en proyectos como «Arduino Telephone Caller ID Unit» con HT9032D, donde se conecta la línea telefónica al módulo y éste al Arduino, y el código lee la información serial codificada en FSK ya demodulada por el módulo.

Esta solución es sencilla para un usuario Arduino que desea mostrar el número llamante sin tener que desarrollar un demodulador FSK desde cero, que sería bastante más complejo.

Circuito auxiliar

Este seria el montaje final:

Por tanto, para un método sencillo de decodificar la modulación FSK del número llamante con Arduino, se recomienda usar un módulo HT9032D con Arduino para recibir datos seriales decodificados y procesar la trama Caller ID. Para decodificar FSK Caller ID con Arduino, el hardware mínimo que se recomienda es el siguiente:

Aplicación típica

En proyectos con Arduino para decodificar el número llamante, el HT9032D se conecta directamente a la línea telefónica (con el debido aislamiento), y su salida digital se conecta a una entrada del Arduino. El Arduino luego interpreta los datos seriales para extraer y mostrar el número.

Codigo arduino con comentarios

/*****************************************************************************
 Copyright 2021 Dilshan R Jayakody.
 
*/

#include <SoftwareSerial.h>
#include <LiquidCrystal.h>
#include <EEPROM.h>

// Crear interfaz serial para callerID en el pin 10 (RX) y 11 (TX).
#define CALLER_ID_RX  10
#define CaLLER_ID_TX  11

#define LCD_RS      2
#define LCD_EN      3
#define LCD_DATA4   4
#define LCD_DATA5   5
#define LCD_DATA6   6
#define LCD_DATA7   7

#define LCD_BACKLED         12
#define LCD_CALL_ALERT_LED  13

#define RING_DET_PIN  8
#define CLI_PWDN_PIN  9

#define MDMF_HEADER   0x80
#define MDMF_PARAM_TIME   0x01
#define MDMF_PARAM_CID    0x02
#define MDMF_PARAM_NAME   0x07 

#define EEPROM_NUM_OFFSET   1
#define EEPROM_TIME_OFFSET  20

enum CID_STATE {CID_IDLE, CID_SYNC, CID_PACKET, CID_MESSAGE, CID_END};
enum CID_MSG_STATE {CIDMSG_HEADER, CIDMSG_LEN, CIDMSG_DATA};

SoftwareSerial callerID(CALLER_ID_RX, CaLLER_ID_TX);
LiquidCrystal lcd(LCD_RS, LCD_EN, LCD_DATA4, LCD_DATA5, LCD_DATA6, LCD_DATA7);

enum CID_STATE cidState;
enum CID_MSG_STATE cidMsg;

unsigned char tempCount, cidData, packetLen, currLen;
unsigned char msgType, msgLen, msgCurrPos;
unsigned long delayStart, watchdogDelay, recallTimeout;
unsigned char lineIdleCounter, watchdogSec;
unsigned char buttonState, tempInfoPos, recall;

char msgData[16];

char tBufferNumber[16];
char tBufferDateTime[9];

void programLastNumber()
{
  unsigned char memPos;

  // Escribir la última información del identificador de llamada en el buffer temporal.
  // Este buffer temporal se usa para evitar problemas de sincronización en el flujo serial (debido a operaciones lentas de escritura en EEPROM). 
  for(memPos = 0; memPos < 16; memPos++)
  {
    tBufferNumber[memPos] = msgData[memPos];
  }
}

void programLastCallTime()
{
  unsigned char memPos;

  // Escribir fecha/hora relacionada con la última llamada en el buffer temporal

En resumen lo ideal para obtener el numero llamante es usar un circuito especializado para Caller ID FSK, evitando tener que hacer una demodulación por software compleja. Eso simplifica el diseño y reduce componentes externos. Además está ampliamente probado y documentado en proyectos de Arduino y telefonía analógica.

Por lo tanto, el HT9032D es el chip indicado para soportar la decodificación FSK Bell 202 del número llamante (Caller ID) en proyectos Arduino con línea telefónica analógica.

Fuente: https://www.instructables.com/Arduino-Telephone-Caller-ID-Unit/