Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

Indicador de batimento cardíaco usando ECG

Componentes e suprimentos

dispositivo uECG
× 1
Arduino Nano R3
× 1
Anel Adafruit NeoPixel:WS2812 5050 RGB LED
× 1
Bateria Li-Ion 1000mAh
× 1

Ferramentas e máquinas necessárias

Ferro de soldar (genérico)

Sobre este projeto


Por muitos anos, eu só queria fazer algo com LEDs que piscassem no ritmo dos meus batimentos cardíacos (e não apenas quando estou perfeitamente imóvel, mas ainda pulando uma batida aqui e ali). Isso acabou sendo surpreendentemente difícil, tentei e falhei por anos. Mas não mais!

Na verdade, todo o levantamento de peso é feito por uECG - um pequeno dispositivo de ECG vestível que é de código aberto e tem um pino de saída compatível com o Arduino (esse pino fica alto / baixo a cada batimento cardíaco). Processar esses estados de pinos é muito mais fácil do que processar o sinal de ECG, e eu tentei tirar o máximo proveito disso.
UPD:você pode querer verificar a 2ª iteração deste projeto, que recebe dados via link de rádio.

1. Esquemas
Como trabalhamos aqui apenas com sinais digitais, é muito simples. Mas, como um wearable, seria muito mais confiável (e menor) se a maioria das conexões fossem soldadas - para um teste rápido não é necessário, mas se você for usá-lo durante alguma atividade pesada, eu recomendo fortemente.
Os esquemas são assim:
  • O pino DI do anel de LED vai para o pino D11 (configurável no código)
  • O pino DRV do dispositivo uECG vai para o pino D3 (também configurável)
  • O + da bateria vai para as entradas Arduino 5V e anel LED 5V
  • Bateria - vai para Arduino GND, liga para GND e uECG para GND

Eu usei a bateria LiPo diretamente como uma entrada de 5V - não há engano, se você conectá-la ao Vin - ela não funcionará de forma confiável (o regulador de voltagem no Vin apresenta queda de voltagem e absolutamente não podemos pagar por um aqui). O fato é que o Arduino é estável desde que a tensão de entrada não fique abaixo de 3,4 volts. A bateria LiPo começa com 4,2 volts quando totalmente carregada e chega a 3,4 volts apenas quando sobra menos de 15% da carga. Portanto, com qualquer bateria maior que ~ 200 mAh, você pode obter um tempo de operação decente. Fora isso, lembre-se de que a bateria deve ser conectada por meio de algum, bem, conector :) Porque você deseja desconectá-la do esquema e carregá-la de vez em quando.

2. Código
O programa funciona de uma maneira simples:ele lê constantemente o pino D3 e, quando uma mudança é detectada, empurra o tempo dessa mudança para um array de 20 elementos. A diferença entre o primeiro e o último elemento, dividido por 20, é o tempo médio por batimento (em milissegundos). Portanto, dividir 1 minuto (60.000 milissegundos) por esse número nos dá o valor BPM. Você pode ajustar o número de elementos na matriz. Um número menor de elementos levaria a uma resposta mais rápida, mas resultados menos estáveis ​​(qualquer problema na detecção de batimento levaria a um grande salto no BPM calculado). Um número maior de elementos forneceria dados mais estáveis, mas uma resposta mais lenta quando o BPM muda rapidamente.

Em seguida, o BPM é mapeado em cores (azul-> verde-> amarelo-> rosa-> vermelho quando o BPM vai de baixo para alto) e em número de LEDs:para 80 BPM oito segmentos estão ligados, para 110 - onze e assim por diante (escala também ajustável no código).
  #include  
#ifdef __AVR__
#include
#endif
// Pino DI do anel LED
#define PIN 11
// número de pixels no anel
#define NUMPIXELS 16
// pino de entrada para conectar uECG
int in_pin =3;
Adafruit_NeoPixel pixels =Adafruit_NeoPixel (NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
configuração vazia () {
pixels.begin (); // Isso inicializa a biblioteca NeoPixel.
pinMode (in_pin, INPUT); // define o pino para o modo de entrada
digitalWrite (in_pin, 1); // habilitar PULLUP:isso é crítico, uECG não tem pull-up interno
}
// nós armazenamos os últimos 20 batimentos cardíacos para calcular a média do BPM sobre eles
// com um valor mais alto, se tornará mais confiável,
// mas levará mais tempo para ver a alteração do resultado quando o BPM for alterado
#define BEAT_HIST 20
batimentos longos [BEAT_HIST];
void push_beat (longo ms) // desloca todos os batimentos na matriz e insere o atual
{
para (int x =0; x {
batimentos [x] =batidas [x + 1];
}
batidas [BEAT_HIST-1] =ms;
}
int get_bpm () // usando a diferença de tempo entre a primeira e a última batidas
{
long dt =bpm [BEAT_HIST-1] - bpm [0];
long bpm =BEAT_HIST * 60000 / dt;
return bpm;
}
last_pix_upd longo =0; // para acompanhar quando atualizamos os pixels na vez anterior
int prev_in_state =0; // estado anterior do pino de entrada:queremos processar apenas as mudanças de estado
void loop ()
{
longo ms =millis ();
int in_state =digitalRead (in_pin ); // 1 quando nenhum batimento detectado, 0 no batimento
if (in_state ==1 &&prev_in_state ==0) // reage apenas à mudança
{
push_beat (ms);
}
prev_in_state =in_state;
if (ms - last_pix_upd> 10) // não atualiza pixels com muita frequência
{
int r, g, b;
last_pix_upd =ms;
int bpm =get_bpm ();
int max_bright =120; // valor do brilho máximo, máximo 255. Mas você nem sempre quer no máximo :)
float dd =20; // mudança no BPM entre os tons de cor (azul-> verde-> amarelo-> rosa-> vermelho)
float t1 =90, t2, t3, t4; // t1 - BPM "base", menor que t1 seria azul
t2 =t1 + dd;
t3 =t2 + dd;
t4 =t3 + dd;
/ / código para mudar a cor dependendo em qual intervalo t1 ... t4 estamos agora
if (bpm else if (bpm else if (bpm else if (bpm else {r =max_bright; g =0; b =0; }
if (in_state) // quando não está na batida, intensidade de 1/4, então apenas as batidas são destacadas
{
r * =0,25;
g * =0,25;
b * =0,25;
}
int on_pixels =(bpm + 5) / 10; // número de LEDs usados:para 60 BPM, 6 LEDs estarão ligados, para 120 - 12 etc
for (int i =0; i {
if ( i else pixels.setPixelColor (i, pixels.Color (0,0,0)); // desligar todos os outros LEDs
}
pixels.show ();
}
}

3. Montagem como vestível
É conveniente colocar o Arduino dentro do anel - ele corresponde ao tamanho quase perfeitamente. A bateria também cabe nas proximidades. Não se esqueça de que o uECG é colocado em um baú - então você precisa de um fio com conectores, primeiro você o coloca, depois coloca uma camisa com outros componentes e, em seguida, conecta o conector. Caso contrário, seria muito inconveniente colocá-lo - acredite, eu tentei))

É basicamente isso - se tudo foi feito corretamente, em 30 segundos após você conectar todos os conectores, ele começará a piscar e indicará BPM.

4. Teste de campo
Eu testei enquanto caminhava e corria - e descobri que durante a corrida, a bateria salta sobre o sensor de ECG, distorcendo suas leituras. Quando mudei tudo um pouco, descobri que o fio que conecta o uECG ao Arduino é muito curto e puxa o sensor de ECG a cada etapa, distorcendo as leituras novamente. No geral, obtive batidas confiáveis ​​apenas ao andar e ficar em pé, mas não ao correr - mas acho que irei melhorar isso. O próprio sensor, quando o usei com outra camisa, exibia o BPM corretamente durante a corrida também (verificado por meio de seu aplicativo).

Além disso, descobriu-se que os LEDs em um baú podem parecer legais, mas são praticamente inúteis. É realmente inconveniente olhar para baixo para verificar seu pulso. Acho que na próxima iteração farei algum tipo de pulseira que indicará as batidas.

P.S. Se você está interessado no projeto uECG - você pode verificar sua página hackaday, há muitos detalhes técnicos, designs de PCB, discussões e logs de projeto

Código

  • uECG_pixel_ring.ino
uECG_pixel_ring.ino Arduino
 #include  #ifdef __AVR__ #include  # endif // pino DI do anel LED # define o PIN 11 // número de pixels no anel # define NUMPIXELS 16 // entrada pino para conectar uECGint in_pin =3; Adafruit_NeoPixel pixels =Adafruit_NeoPixel (NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); configuração vazia () {pixels.begin (); // Isso inicializa a biblioteca NeoPixel. pinMode (in_pin, INPUT); // define o pino para o modo de entrada digitalWrite (in_pin, 1); // habilitar PULLUP:isso é crítico, uECG não tem pull-up interno} // nós armazenamos os últimos 20 batimentos cardíacos para calcular a média do BPM sobre eles // com um valor mais alto, se tornará mais confiável, // mas levará mais tempo para ver a mudança de saída quando o BPM muda # define BEAT_HIST 20 batidas longas [BEAT_HIST]; void push_beat (ms longas) // desloca todas as batidas na matriz e insere a atual {for (int x =0; x  10) // não atualiza pixels com muita freqüência {int r, g, b; last_pix_upd =ms; int bpm =get_bpm (); int max_bright =120; // valor do brilho máximo, máximo 255. Mas você nem sempre quer no máximo :) float dd =20; // mudança no BPM entre os tons de cor (azul-> verde-> amarelo-> rosa-> vermelho) float t1 =90, t2, t3, t4; // t1 - BPM "base", menor que t1 seria azul t2 =t1 + dd; t3 =t2 + dd; t4 =t3 + dd; // código para mudar a cor dependendo em qual intervalo t1 ... t4 estamos agora if (bpm  

Esquemas


Processo de manufatura

  1. Desfibrilador externo
  2. Rolling Pin
  3. Coração Artificial
  4. Válvula cardíaca artificial
  5. Sensor de movimento usando Raspberry Pi
  6. Monitore a temperatura de sua casa usando o Raspberry Pi
  7. Monitor de frequência cardíaca remoto
  8. Sistema permite monitoramento sem contato do ritmo cardíaco usando alto-falantes inteligentes
  9. Tatuagem eletrônica permite monitoramento cardíaco ininterrupto por períodos prolongados
  10. Entendendo a Articulação