Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Visualizador LED de Latidos en Tiempo Real con ECG

Componentes y suministros

ComponenteCantidad
Dispositivo uECG1
Arduino Nano R31
Anillo Adafruit NeoPixel: WS2812 5050 RGB LED1
Batería Li-Ion 1000mAh1

Herramientas y máquinas necesarias

Sobre el proyecto

Durante años quise hacer algo con LEDs que parpadeara al ritmo de mis latidos (y no solo cuando estoy perfectamente quieto, saltándome un latido aquí y allá). Resultó sorprendentemente difícil, lo intenté y fallé durante años. ¡Pero ya no!

En realidad, todo el trabajo pesado lo hace uECG, un pequeño dispositivo ECG vestible de código abierto que tiene un pin de salida compatible con Arduino (ese pin va high/low con cada latido). Procesar estos estados de pin es mucho más fácil que procesar la señal ECG, y he intentado sacarle el máximo partido.
Actualización: puede que quieras ver la 2ª iteración de este proyecto, que recibe datos por enlace de radio.

1. Esquemático

Como solo trabajamos con señales digitales, es muy simple. Pero como dispositivo vestible sería mucho más fiable (y pequeño) si la mayoría de conexiones van soldadas; para una prueba rápida no es necesario, pero si vas a usarlo durante actividad intensa, recomiendo encarecidamente soldar.

Visualizador LED de Latidos en Tiempo Real con ECG

He usado batería LiPo directamente como entrada 5V; no es error, si la conectas a Vin no funcionará de forma fiable (el regulador de Vin introduce caída de tensión y no nos la podemos permitir). Arduino es estable mientras la tensión de entrada no baje de 3.4 voltios. LiPo empieza a 4.2V cargada y llega a 3.4V solo cuando queda menos del 15% de carga. Así que con cualquier batería >200 mAh tienes tiempo de operación decente. Además, la batería debe conectarse vía algún conector, ¡porque querrás desconectarla para cargarla!

2. Código

El programa funciona así: lee constantemente pin D3 y cuando detecta cambio, guarda el tiempo en un array de 20 elementos. La diferencia entre el primer y último elemento, dividida por 20, es el tiempo medio por latido (ms). Dividiendo 60000 ms (1 min) por ese número obtenemos BPM. Puedes ajustar el número de elementos del array. Menos elementos = respuesta más rápida pero resultados menos estables (cualquier problema en detección causa gran salto en BPM calculado). Más elementos = datos más estables, pero respuesta más lenta cuando BPM cambia rápido.

Luego el BPM se mapea a color (azul→verde→amarillo→rosa→rojo cuando BPM sube) y a número de LEDs: 80 BPM = 8 segmentos encendidos, 110 = 11, etc. (escala ajustable en código).

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 11
#define NUMPIXELS 16
int in_pin = 3;
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  pixels.begin();
  pinMode(in_pin, INPUT);
  digitalWrite(in_pin, 1); // Pull-up crítico, uECG no tiene pull-up interno
}

#define BEAT_HIST 20
long beats[BEAT_HIST];

void push_beat(long ms) {
  for(int x = 0; x < BEAT_HIST-1; x++) beats[x] = beats[x+1];
  beats[BEAT_HIST-1] = ms;
}

int get_bpm() {
  long dt = beats[BEAT_HIST-1] - beats[0];
  long bpm = BEAT_HIST * 60000 / dt;
  return bpm;
}

long last_pix_upd = 0;
int prev_in_state = 0;

void loop() {
  long ms = millis();
  int in_state = digitalRead(in_pin); // 1 = sin latido, 0 = latido
  if(in_state == 1 && prev_in_state == 0) {
    push_beat(ms);
  }
  prev_in_state = in_state;
  if(ms - last_pix_upd > 10) {
    int r, g, b;
    last_pix_upd = ms;
    int bpm = get_bpm();
    int max_bright = 120;
    float dd = 20;
    float t1 = 90, t2, t3, t4;
    t2 = t1 + dd; t3 = t2 + dd; t4 = t3 + dd;
    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; }
    if(in_state) { r *= 0.25; g *= 0.25; b *= 0.25; }
    int on_pixels = (bpm+5)/10;
    for(int i=0;i

3. Montaje como vestible

Es conveniente colocar el Arduino dentro del anillo; encaja casi perfecto. La batería cabe al lado. No olvides que uECG va en el pecho, así que necesitas un cable con conectores: primero colocas el sensor, luego te pones la camisa con los demás componentes, y entonces enchufas el conector. De lo contrario es muy incómodo ponérselo, ¡creeme, lo intenté!))

Visualizador LED de Latidos en Tiempo Real con ECG
Visualizador LED de Latidos en Tiempo Real con ECG
Visualizador LED de Latidos en Tiempo Real con ECG

Básicamente eso es todo; si todo está bien, dentro de 30 segundos tras conectar todo empezará a parpadear indicando BPM.

4. Pruebas de campo

Lo probé caminando y corriendo; durante la carrera, la batería rebota sobre el sensor ECG distorsionando lecturas. Al moverlo, el cable que une uECG con Arduino es demasiado corto y tira del sensor ECG a cada paso, distorsionando otra vez. En general, obtuve latidos fiables solo caminando y quieto, no corriendo; pero creo que lo mejoraré. El sensor en sí, con otra camiseta, mostraba BPM correctamente durante la carrera (comprobado vía su app).

También resulta que LEDs en el pecho pueden verse chulos pero son prácticamente inútiles. Es muy incómodo mirar hacia abajo para ver tu pulso. Creo que en la próxima iteración haré una pulsera de muñeca que indique los latidos.

P.D. Si te interesa el proyecto uECG, mira su página en hackaday, hay muchos detalles técnicos, diseños PCB, discusión y logs del proyecto.

Código

  • uECG_pixel_ring.ino

uECG_pixel_ring.ino (Arduino)

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 11
#define NUMPIXELS 16
int in_pin = 3;
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  pixels.begin();
  pinMode(in_pin, INPUT);
  digitalWrite(in_pin, 1);
}

#define BEAT_HIST 20
long beats[BEAT_HIST];

void push_beat(long ms) {
  for(int x = 0; x < BEAT_HIST-1; x++) beats[x] = beats[x+1];
  beats[BEAT_HIST-1] = ms;
}

int get_bpm() {
  long dt = beats[BEAT_HIST-1] - beats[0];
  long bpm = BEAT_HIST * 60000 / dt;
  return bpm;
}

long last_pix_upd = 0;
int prev_in_state = 0;

void loop() {
  long ms = millis();
  int in_state = digitalRead(in_pin);
  if(in_state == 1 && prev_in_state == 0) push_beat(ms);
  prev_in_state = in_state;
  if(ms - last_pix_upd > 10) {
    int r, g, b;
    last_pix_upd = ms;
    int bpm = get_bpm();
    int max_bright = 120;
    float dd = 20;
    float t1 = 90, t2, t3, t4;
    t2 = t1 + dd; t3 = t2 + dd; t4 = t3 + dd;
    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; }
    if(in_state) { r *= 0.25; g *= 0.25; b *= 0.25; }
    int on_pixels = (bpm+5)/10;
    for(int i=0;i

Esquemáticos

Visualizador LED de Latidos en Tiempo Real con ECG

Proceso de manufactura

  1. Desfibrilador externo: Historia, diseño y fabricación
  2. El rodillo de cocina: de los orígenes etruscos a la artesanía moderna
  3. Corazón artificial: Tecnología, historia y perspectivas futuras
  4. Válvulas cardíacas artificiales: Tipos, historia e innovaciones futuras
  5. La Evolución y la Artesanía de los Bolos de Bolera Modernos
  6. Controle un LED con Sensor PIR de Movimiento en Raspberry Pi
  7. Monitoriza la temperatura de tu casa con un panel Raspberry Pi
  8. Sistema de Monitorización Remota de Frecuencia Cardíaca con Alertas AWS IoT
  9. Articulación de Nudillo Explicada: Diseño, Aplicaciones y Características Clave
  10. Monitoreo de Latidos Cardíacos sin Contacto vía Altavoces Inteligentes: Un Sistema Revolucionario
  11. Tatuaje Electrónico de Grafeno Ofrece Monitorización Cardíaca Continua y Precisa por Períodos Prolongados