Monitor ECG Inalámbrico de Frecuencia Cardíaca: Diseño Vestible con Arduino Nano y nRF24
Componentes y materiales
| Componente | Cantidad |
|---|---|
| Dispositivo uECG | 1 |
| Arduino Nano R3 | 1 |
| Módulo nRF24 (genérico) | 1 |
| Anillo NeoPixel WS2812 5050 RGB (Adafruit) | 1 |
| Batería LiPo (200+ mAh) | 1 |
Herramientas necesarias
- Soldador
Sobre el proyecto
Esta es la segunda iteración de mi monitor cardíaco. La versión anterior mostraba latidos en el pecho y se conectaba al uECG por cable: se veía bien pero no era práctico (fuera del campo visual, cable distorsionaba lecturas al correr).
Esta versión resuelve todo: se lleva en la muñeca (visible sin apartar la vista) y es inalámbrica (sin distorsión). Funciona corriendo y permite monitorizar la carga cardíaca.
1. Componentes
El uECG hace el trabajo pesado: mide y calcula BPM a bordo. En modo "enlace directo", envía datos (incluyendo ECG de alta resolución, no usado aquí) vía protocolo de radio compatible con nRF24 genérico. El nRF24 es el segundo componente crítico. El Arduino Nano tiene el tamaño justo para caber bajo el anillo LED, así que lo uso como controlador (cualquier otro serviría).
2. Esquemático
Conectar el nRF24 no es trivial: 7 hilos (SPI: MISO, MOSI, SCK, CS + CE + alimentación). Para tamaño reducido, quita headers y suelda directo a pads. 14 puntos de soldadura solo para el nRF. Lo demás es simple: anillo LED (1 dato + 2 alimentación) y batería (2 hilos).
Lista de conexiones:
- nRF24 pin 1 (GND) → GND Arduino
- nRF24 pin 2 (Vcc) → 3.3V Arduino
- nRF24 pin 3 (CE) → D9 Arduino
- nRF24 pin 4 (CS) → D8 Arduino
- nRF24 pin 5 (SCK) → D13 Arduino
- nRF24 pin 6 (MOSI) → D11 Arduino
- nRF24 pin 7 (MISO) → D12 Arduino
- Anillo LED Power → 5V Arduino
- Anillo LED GND → GND Arduino
- Anillo LED DI → D5 Arduino
- Batería + → 5V Arduino
- Batería - → GND Arduino
- (La batería necesita conector para desconectar/cargar)
Importante: MOSI, MISO, SCK deben ir a D11, D12, D13 (hardware SPI). Otros pines pueden cambiarse modificando el código.
3. Programa
Lo único complejo es la configuración del canal RF. Pasé tiempo hasta darme cuenta que uECG y nRF24 usan orden de bits distinto para la dirección del pipe. Al corregirlo, funcionó al instante. Básicamente: leemos paquetes entrantes, usamos el 5º byte como BPM, y filtramos (canal ruidoso, valores aleatorios ocasionales, CRC hardware deshabilitado por compatibilidad). Luego convertimos BPM a color y número de píxeles activos.
Código principal (bpm_watch.ino)
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#include <SPI.h>
#include <RF24.h>
#include <RF24_config.h>
#include <nRF24L01.h>
int rf_cen = 9; int rf_cs = 8;
RF24 rf(rf_cen, rf_cs);
// Dirección pipe - hardcoded en uECG
uint8_t pipe_rx[8] = {0x0E, 0xE6, 0x0D, 0xA7, 0, 0, 0, 0};
#define PIN 5
#define NUMPIXELS 16
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
uint8_t swapbits(uint8_t a) { // uECG usa orden de bits invertido
uint8_t v = 0;
if(a & 0x80) v |= 0x01; if(a & 0x40) v |= 0x02; if(a & 0x20) v |= 0x04;
if(a & 0x10) v |= 0x08; if(a & 0x08) v |= 0x10; if(a & 0x04) v |= 0x20;
if(a & 0x02) v |= 0x40; if(a & 0x01) v |= 0x80;
return v;
}
void setup() {
pixels.begin();
for(int i=0;i 0) rf_bpm = bb;
}
long ms = millis();
if(ms - last_pix_upd > 10) { // No actualizar píxeles demasiado seguido
int r, g, b; last_pix_upd = ms;
int bpm = rf_bpm;
int max_bright = 160; // Brillo máx (máx 255)
float dd = 25; // Cambio BPM entre tonos (azul→verde→amarillo→rosa→rojo)
float t1 = 90, t2, t3, t4; // t1 = BPM base (< t1 = azul)
t2 = t1 + dd; t3 = t2 + dd; t4 = t3 + dd;
// Color según rango BPM
if(bpm < t1) { r=0; g=0; b=max_bright; }
else if(bpm < t2) { r=0; g=max_bright*(bpm-t1)/dd; b=max_bright-g; }
else if(bpm < t3) { r=max_bright*(bpm-t2)/dd; g=max_bright-r; b=r/4; }
else if(bpm < t4) { r=max_bright; g=0; b=max_bright/2 - max_bright*(bpm-t3)/(2*dd); }
else { r=max_bright; g=0; b=0; }
int on_pixels = (bpm-80)/8; // Solo muestra >80 BPM (más sensible en zona alta)
for(int i=0;i
4. Montaje de la pulsera
Con todo soldado y probado, uso pegamento térmico para unir todo: Nano encaja en anillo exterior, nRF24 en interior, batería se pega donde cabe. Luego coso a una pulsera (sobra de pulsera antiestática de estación de soldar).
5. Pruebas
Salí a correr y funcionó bien, salvo una sorpresa: configuré 192 BPM = todos LEDs encendidos (límite recomendado para mis parámetros). Lo superé en pocos minutos sin notarlo. Al parar, no bajó de golpe sino con relajación lenta (sensor 100% fiable sin mucho movimiento). Resulta que entreno por encima de mi umbral "saludable" estándar. Curiosamente, tuve problemas cardíacos en la adolescencia que parecieron desaparecer, pero cualquier esfuerzo mayor que caminar rápido me costaba; seguí entrenando y aumenté mi límite. Ahora me pregunto: ¿mi BPM es alto por aquel historial o me estoy exigiendo demasiado sin darme cuenta? Tendré que ajustar el máximo en el monitor o entrenar menos intensamente.
PD: Sorprendentemente, uECG funciona bien como sensor EMG (ver mi proyecto Control de Mano Robótica).
Esquemáticos
Archivo Fritzing: nrf24_led_ring_o2Gij5oigT.fzz
Proceso de manufactura
- Construya una estación meteorológica y de calidad del aire con Raspberry Pi, InfluxDB y Grafana
- Construya un sensor de temperatura remoto con Raspberry Pi y Python – Guía paso a paso
- Monitoriza la temperatura de tu casa con un panel Raspberry Pi
- Sistema de Monitorización Remota de Frecuencia Cardíaca con Alertas AWS IoT
- Crea un Impresionante Sistema Ambilight para Monitor con Arduino
- Construye un Voltímetro Inteligente con Arduino y Smartphone – Proyecto DIY Fácil
- Monitor de Frecuencia Cardíaca IoT en Tiempo Real con Arduino y MAX30100
- Construye un Monitor de Frecuencia Cardíaca Preciso con Fotoresistencia y Arduino
- Mecanizado CNC: Fabricación de Precisión de Materiales y Componentes
- Renesas y Altran Lanzan Primer Reloj UWB de Pulso de Baja Tasa para Distanciamiento Social
- Sensores de Frecuencia Cardíaca Integrados en Ropa Inteligente: Monitorización Fiable