¿Cómo hace un monitor de signos vitales para dibujar el latido y, al mismo tiempo, contar cuántas veces respiras, usando los mismos tres parches pegados al pecho? La respuesta está en un solo chip: el ADS1292R de Texas Instruments. En este proyecto se combina con un ESP32 y una pantalla TFT ILI9488 de 4 pulgadas para armar un monitor de banco que muestra la curva del electrocardiograma en movimiento, la frecuencia cardíaca, la frecuencia respiratoria, el intervalo RR y el estado de contacto de los electrodos.
Al terminar vas a entender cómo se mide una señal de microvoltios sin que la ahogue el ruido de la red eléctrica, cómo se obtiene la respiración midiendo impedancia y cómo se organiza un programa que lee datos a 500 muestras por segundo sin que la pantalla lo frene. Y, sobre todo, vas a saber por qué este prototipo se prueba con un simulador antes de tocar a una persona.

Antes de empezar: seguridad eléctrica
Esto es un prototipo educativo, no un equipo médico certificado, y no sirve para diagnosticar nada. Un electrocardiógrafo clínico tiene una barrera de aislamiento entre la parte que toca al paciente y todo lo demás, limita la corriente que puede circular por los electrodos y pasa por ensayos de seguridad. Este montaje no tiene nada de eso.
El riesgo concreto es este: si el ESP32 está conectado al computador por USB, la persona con los electrodos queda conectada, a través del circuito, a la tierra del computador y de la red eléctrica. Una falla en la fuente del computador, o en el cargador del notebook, puede hacer circular corriente por el pecho, justo donde más daño hace. Que el montaje funcione con batería ayuda, pero no basta por sí solo para garantizar que es seguro.
Por eso el orden de trabajo es:
- Toda la puesta a punto se hace con un simulador de ECG y respiración, un aparato que genera señales cardíacas y de impedancia conocidas. Así verificas filtros, detección de latidos y pantalla sin riesgo.
- Si algún día quieres medirte a ti mismo, el circuito tiene que funcionar solo con batería, sin USB, sin cargador ni depurador conectados, y con aislamiento y limitación de corriente revisados por alguien calificado.
Arquitectura: tres bloques y dos buses SPI

El sistema se divide en tres partes: la interfaz de electrodos (el ADS1292R), el procesamiento (el ESP32) y la visualización (la TFT). La decisión de diseño más importante es que el ADS1292R y la pantalla usan buses SPI separados, y que la adquisición corre en una tarea distinta del dibujo.
¿Por qué? Dibujar una curva en una pantalla de 480 × 320 toma milisegundos. El ADS1292R entrega una muestra cada 2 ms (500 muestras por segundo). Si ambos compartieran bus y tarea, cada refresco de pantalla haría perder muestras, y una muestra perdida deforma la curva y falsea el conteo de latidos. Con buses y tareas separadas, el ESP32 clásico usa sus dos núcleos para que la lectura nunca espere al dibujo. Aun así, el programa vigila si se pierde alguna muestra y lo informa.
El ADS1292R por dentro

El ADS1292R es un front end analógico: reúne en un chip todo lo que va entre el electrodo y el número digital.
- Dos convertidores delta sigma de 24 bits que muestrean a la vez, de 125 a 8000 muestras por segundo.
- Amplificadores de ganancia programable (1, 2, 3, 4, 6, 8 o 12) de bajo ruido.
- Rechazo de modo común de hasta 120 dB. Tu cuerpo actúa como antena y capta los 50 Hz de la instalación eléctrica con una amplitud mucho mayor que la del corazón. Como esa interferencia aparece igual en ambos electrodos y la señal cardíaca es la diferencia entre ellos, el amplificador diferencial la cancela casi por completo.
- Amplificador de pierna derecha (RLD). Mide el voltaje común que queda y lo devuelve invertido al cuerpo por el tercer electrodo, empujándolo hacia cero. Es la otra mitad del truco contra el ruido de la red.
- Detección de electrodo suelto (lead off), referencia y oscilador internos.
La diferencia con el ADS1292 sin "R" es la medición de respiración por impedancia.
Cómo se mide la respiración
La técnica se llama neumografía de impedancia. El chip inyecta por los electrodos una corriente alterna muy pequeña de alta frecuencia (32 kHz en esta configuración) y mide el voltaje que produce. Cuando inspiras, el tórax se llena de aire, que conduce peor que el tejido, y la impedancia sube un poco; cuando espiras, baja. El chip demodula esa señal y separa la variación lenta de la respiración (una vez cada pocos segundos) de la actividad eléctrica del corazón, que es mucho más rápida.
La calidad depende de la posición de los electrodos, del contacto con la piel y de la fase de demodulación, un ajuste que en el programa es RESP_PHASE_CODE. No es una calibración universal: depende del módulo.
En este programa, el canal 2 lleva el ECG y el canal 1 la respiración demodulada. Esa asignación tiene que coincidir con el circuito real de tu módulo.
Dónde van los electrodos
Para una derivación simple con tres electrodos:
- RA (brazo derecho): parte alta derecha del pecho.
- LA (brazo izquierdo): parte alta izquierda del pecho.
- RL (pierna derecha, referencia): parte baja derecha del abdomen.

La piel tiene que estar limpia y seca, y los parches bien adheridos. Un mal contacto es la causa más común de una curva llena de ruido.
La pantalla ILI9488

La ILI9488 de 4 pulgadas tiene 480 × 320 píxeles a color y se comunica por SPI. En este proyecto muestra la curva sobre un panel verde azulado oscuro, con tarjetas grandes para el pulso y la respiración, y filas más pequeñas para el intervalo RR y el estado de los electrodos.
Conexiones

ADS1292R al ESP32 (SPI a 500 kHz, modo 1):
| Señal del módulo | GPIO del ESP32 | Función |
|---|---|---|
| SCLK | 14 | Reloj SPI |
| DIN (MOSI) | 13 | Comandos y configuración |
| DOUT (MISO) | 35 | Datos de conversión |
| CS | 27 | Selección de chip |
| DRDY | 34 | Aviso de dato listo |
| START | 25 | Control de conversión |
| PWDN/RESET | 26 | Reinicio y apagado |
| GND | GND | Referencia común |
ILI9488 al ESP32:
| Pin de la pantalla | GPIO del ESP32 |
|---|---|
| SCK | 18 |
| SDI (MOSI) | 23 |
| SDO (MISO) | 19 |
| CS | 33 |
| DC/RS | 32 |
| RESET | 4 |
| GND | GND |
La alimentación (VCC) y la retroiluminación (LED) dependen del módulo de pantalla que tengas: revisa su serigrafía antes de conectar. Los GPIO 34 y 35 del ESP32 son solo de entrada, y por eso se usan para DRDY y DOUT, que son señales que el ESP32 solo lee.
El original usa una PCB con resistencias de 22 Ω en serie en las líneas SPI (amortiguan los rebotes de señal en los flancos), condensadores de desacoplo de 10 µF y 0,1 µF y zócalos hembra para poder sacar los módulos.

Dos puentes de soldadura que no puedes olvidar
- LOGIC SEL: une el pad central con el lado de +3,3 V. El ESP32 trabaja con lógica de 3,3 V y la parte digital del ADS1292R acepta de 1,7 a 3,6 V. Nunca unas los lados de 3,3 V y 5 V al mismo tiempo.
- CLKSEL: déjalo en reloj interno. Con CLKSEL en alto, el chip usa su propio oscilador de 512 kHz y no hace falta generar un reloj externo.

El programa
Son tres archivos, que tienen que quedar juntos en una carpeta llamada main: main.ino, tft_setup.h y ADS1292.h. Usa la librería TFT_eSPI para la pantalla; no hace falta ninguna librería para el ADS1292R porque el controlador está escrito dentro del proyecto.
main.ino es mínimo a propósito: solo llama a las funciones de inicio y del ciclo principal.
/*
ESP32 DevKit + ILI9488 + ADS1292R - real-data monitor.
Keep main.ino, tft_setup.h and ADS1292.h together in the folder named main.
Open main.ino in the Arduino IDE. Keep the working TFT setup unchanged.
All configuration, UI, acquisition and error handling are in ADS1292.h.
Serial Monitor: 115200 baud. R = restart/self-test; S = stop acquisition.
Prototype firmware. Use a simulator for initial testing, not a person.
*/
#include <SPI.h>
#include <TFT_eSPI.h>
#include "ADS1292.h"
void setup()
{
monitorBegin();
}
void loop()
{
monitorLoop();
}
tft_setup.h define el controlador de la pantalla, sus pines, las fuentes y una velocidad SPI conservadora de 10 MHz. TFT_eSPI busca este archivo junto al programa; si tu versión de la librería no lo hace, revisa cómo carga su configuración.
#ifndef TFT_SETUP_H
#define TFT_SETUP_H
#define USER_SETUP_ID 100
#define ILI9488_DRIVER
#define TFT_MISO 19
#define TFT_MOSI 23
#define TFT_SCLK 18
#define TFT_CS 33
#define TFT_DC 32
#define TFT_RST 4
#define LOAD_GLCD
#define LOAD_FONT2
#define LOAD_FONT4
#define LOAD_FONT6
#define LOAD_FONT7
#define LOAD_FONT8
#define LOAD_GFXFF
#define SMOOTH_FONT
// Use slow SPI first for debugging
#define SPI_FREQUENCY 10000000
#define SPI_READ_FREQUENCY 10000000
#endif
ADS1292.h contiene todo lo demás: el controlador del chip, los filtros, los detectores, la tarea de adquisición, la interfaz y el manejo de errores. Su primera sección es la configuración:
// ============================================================================
// 1. USER CONFIGURATION - PINS, TIMING, FILTERS, DISPLAY
// Original section: MonitorConfig.h
// ============================================================================
// BEGIN PRESERVED SECTION: MonitorConfig.h
#include <stdint.h>
// Classic dual-core ESP32 DevKit only. Keep the proven TFT setup unchanged.
namespace cfg {
constexpr int ADS_SCLK = 14, ADS_MOSI = 13, ADS_MISO = 35;
constexpr int ADS_CS = 27, ADS_DRDY = 34, ADS_START = 25, ADS_RESET = 26;
constexpr uint32_t ADS_SPI_HZ = 500000; // Register access <= 2*fCLK; fCLK=512 kHz.
constexpr uint32_t SPI_MARGIN_US = 20; // Exceeds 4*tCLK at the specified internal clock.
constexpr uint32_t SAMPLE_HZ = 500;
constexpr uint32_t PERIOD_US = 1000000 / SAMPLE_HZ;
constexpr uint32_t MAX_READ_LATENCY_US = 1000;
constexpr uint32_t NO_FRAME_TIMEOUT_US = 250000;
constexpr uint32_t REG_AUDIT_INTERVAL_US = 2000000;
constexpr uint8_t MAX_AUTO_RECOVERIES = 3; // Total per boot/manual R, not endless retries.
constexpr bool START_BY_OPCODE = false; // false: physical START high; true: opcode, pin low.
constexpr bool STARTUP_SELF_TEST = true; // Internal square-wave test; no displayed patient values.
constexpr uint32_t SELF_TEST_MS = 4000;
// Board-dependent analog settings: verify against your actual CJMCU circuitry.
constexpr bool RESP_ENABLED = true;
constexpr uint8_t RESP_PHASE_CODE = 12; // 135 degrees at 32 kHz; not universal calibration.
constexpr uint8_t CH1SET = 0x00; // CH1 normal inputs, gain 6.
constexpr uint8_t CH2SET = 0x00; // CH2 normal inputs, gain 6.
constexpr float VREF_V = 2.42f;
constexpr float GAIN1 = 6.0f, GAIN2 = 6.0f;
constexpr float UV_PER_COUNT1 = VREF_V * 1.0e6f / (GAIN1 * 8388608.0f);
constexpr float UV_PER_COUNT2 = VREF_V * 1.0e6f / (GAIN2 * 8388608.0f);
constexpr uint8_t ECG_LEAD_MASK = 0x0C; // CH2P + CH2N only. Not RLD/CH1 continuity.
constexpr float NOTCH_HZ = 60.0f; // Set 50.0f for a 50-Hz environment; 0 disables.
// Engineering heuristics, NOT medical alarm thresholds. Validate on a simulator.
constexpr float ECG_MIN_PP_UV = 100.0f;
constexpr float ECG_MAX_PP_UV = 6000.0f;
constexpr float ECG_MAX_HF_RMS_UV = 120.0f;
constexpr float QRS_MIN_PEAK_UV = 60.0f;
constexpr float RESP_MIN_RMS_UV = 5.0f;
constexpr float RESP_MAX_RMS_UV = 20000.0f;
constexpr uint64_t ECG_WARMUP_US = 3000000;
constexpr uint64_t RESP_WARMUP_US = 8000000;
constexpr int32_t CLIP_CODE = 0x780000;
// Preserve the finalized ILI9488 layout and display bus speed.
constexpr int SCREEN_W = 480, SCREEN_H = 320;
constexpr int PLOT_X = 15, PLOT_Y = 80, PLOT_W = 300, PLOT_H = 170;
constexpr int SIDE_X = 330, SIDE_W = 142;
constexpr int HEART_Y = 48, RESP_Y = 132, VITAL_H = 80;
constexpr int RR_Y = 216, LEAD_Y = 243, SMALL_H = 23;
constexpr float ECG_PIXELS_PER_UV = 0.070f;
constexpr float ECG_POLARITY = 1.0f;
constexpr uint32_t PLOT_DECIMATION = 4; // 125 points/s; chart advances by received points.
constexpr uint32_t RENDER_INTERVAL_MS = 96;
constexpr int16_t PLOT_GAP = INT16_MIN;
constexpr uint16_t PLOT_QUEUE_SIZE = 512;
constexpr uint8_t VITAL_FONT = 7;
static_assert(CH1SET == 0x00 && CH2SET == 0x00 && GAIN1 == 6.0f && GAIN2 == 6.0f,
"This audited profile requires gain 6 on both channels; update scaling/calibration together.");
static_assert(NOTCH_HZ == 0.0f || NOTCH_HZ == 50.0f || NOTCH_HZ == 60.0f, "Notch: choose 0, 50 or 60 Hz");
static_assert(RESP_PHASE_CODE <= 15, "Invalid respiration phase code");
static_assert(ADS_SPI_HZ <= 1000000, "Keep ADS register SPI within the internal-clock limit");
static_assert(PLOT_DECIMATION > 0 && SAMPLE_HZ % PLOT_DECIMATION == 0, "Invalid plot decimation");
}
// END PRESERVED SECTION: MonitorConfig.h
El cambio que necesitas en Chile: el filtro de 50 Hz
El programa trae NOTCH_HZ = 60.0f porque el original se escribió para una red de 60 Hz. En Chile la red eléctrica es de 50 Hz, así que cambia esa línea a 50.0f. Un filtro notch elimina una franja muy angosta de frecuencias; si lo dejas en 60 Hz, la interferencia de 50 Hz pasa intacta y vas a ver la curva "peluda", con una ondulación fina encima de cada latido.
Lo que hace el procesamiento
- Escala: cada cuenta del convertidor equivale a
VREF / (ganancia × 2²³)microvoltios. Con 2,42 V de referencia y ganancia 6, son unos 0,048 µV por cuenta. Si cambias la ganancia, el programa obliga a revisar toda la escala (por eso elstatic_assert). - Filtros: un pasa altos quita la deriva lenta de la línea base (la que produce la respiración y el movimiento), un pasa bajos limita el ruido muscular y el notch elimina la red.
- Detección de latidos: busca los complejos QRS con un umbral que se adapta a la amplitud de la señal y al ruido, y calcula el pulso con la mediana de los últimos intervalos. La mediana ignora un latido mal detectado aislado; un promedio se dejaría arrastrar.
- Validación: los umbrales de calidad (
ECG_MIN_PP_UV,ECG_MAX_HF_RMS_UVy compañía) son heurísticas de ingeniería, no umbrales de alarma médica. Sirven para que la pantalla diga "artefacto" o "electrodo suelto" en vez de mostrar un número inventado.
Al encender, el programa hace una autoprueba con la onda cuadrada interna del chip durante 4 segundos. Desde el monitor serie a 115200 baudios, la tecla R reinicia y repite la autoprueba, y S detiene la adquisición.
Prueba con simulador, paso a paso
- Conecta el cable de electrodos al simulador, no a una persona.
- Elige en el simulador un ritmo conocido, por ejemplo 60 latidos por minuto, y verifica que la pantalla muestre 60.
- Cambia a 120 y luego a 40. El pulso debería seguir el cambio en pocos segundos.
- Desconecta un electrodo: la pantalla tiene que avisar contacto perdido y dejar de mostrar el pulso.
- Activa la señal de respiración del simulador y ajusta
RESP_PHASE_CODEsi la curva respiratoria sale demasiado débil. - Si la curva sale invertida, cambia
ECG_POLARITYa-1.0f.
Si no tienes simulador, puedes revisar la cadena digital con la autoprueba interna, pero eso no valida la parte analógica.
Variantes y mejoras
- Registrar en una microSD. Agrega un módulo microSD por SPI y guarda las muestras crudas; así puedes analizar después la variabilidad del ritmo cardíaco en un computador.
- Empezar con algo más simple. Si es tu primer proyecto de biopotenciales, el módulo AD8232 entrega una sola señal analógica de ECG y se lee con el ADC del ESP32; no mide respiración, pero te enseña los mismos conceptos con menos configuración.
- Enviar los datos por Bluetooth. El ESP32 trae BLE; puedes mandar el pulso y la respiración a una aplicación del celular, siempre con el prototipo funcionando a batería.
Personalización para Chile
En Chile consigues buena parte de los componentes en MechatronicStore:
- ESP32 con Wifi y Bluetooth ESP 32 ESP WROOM-32 ESP32S Tipo C (SKU X2-10V2): el ESP32 clásico de doble núcleo que pide el programa. Revisa que la separación entre filas de pines calce con la PCB si la mandas a fabricar.
- Resistencias 1/4W 1 unidad 22Ω (SKU GK5-20): las resistencias en serie de las líneas SPI.
- Resistencias 1/4W 1 unidad 10kΩ (SKU GK2-15) y Resistencias 1/4W 1 unidad 1kΩ (SKU GK3-17): las de polarización de la placa.
- Capacitor condensador electrolítico por unidad 10uf 25V (SKU GF2-7): desacoplo de la alimentación.
El módulo ADS1292R y la pantalla ILI9488 de 4 pulgadas no están en el catálogo. Si quieres partir con un ECG más sencillo, el Sensor de monitoreo cardíaco y ECG AD8232 (SKU G-208) es la alternativa de una sola derivación, sin respiración.
Recursos
- Tutorial original (inglés): DIY ECG Monitor with ADS1292R & ESP32 TFT Display, en el que se basa esta guía.
- Esquemático en PDF: descarga
- Archivos Gerber de la PCB: descarga
- Librería de la pantalla: TFT_eSPI
- Hoja de datos del chip: ADS1292R de Texas Instruments
Versión chilena con componentes en stock local en MechatronicStore.







