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

De KY-039 à freqüência cardíaca

Componentes e suprimentos

Arduino UNO
× 1
Sensor de pulsação KY-039
× 1
Fios de jumpers (genérico)
× 1

Sobre este projeto


No conjunto de 37 sensores para Arduino , há um sensor de batimento cardíaco. O nome promete muito. As pessoas tendem a pensar que fornece um número digital por meio de I2C ou algo semelhante, um número que é a taxa de batimentos cardíacos. O que o sensor fornece é apenas um valor "analógico" de 0 a 1023, informando quanta luz infravermelha o sensor de luz recebe, ou realmente quanto algo está sombreando o sensor de luz . Quanto maior o valor, menos luz infravermelha.

Resumindo:coloque o dedo entre o led IR e o transistor de luz do sensor. O batimento cardíaco dilata os vasos sanguíneos do dedo, o que filtrará o IR. Isso cria um sinal pulsante.

Neste projeto, descrevo como esse sinal é convertido em uma taxa de batimentos cardíacos como 66 BPM (batimentos por minuto).





Os passos simples


Se você acabou de ler e plotar os valores do sensor KY-039, você obterá algo assim:

Os valores são valores inteiros. Não é muito preciso. Em vez disso, calcule a média de um grupo deles e plote a média. Você consegue isso:

Aqui você já pode ver a pulsação do coração. Obtenha a diferença de tempo entre cada aumento significativo do pulso. A partir daí, você pode calcular a frequência cardíaca em BPM.

(O pequeno padrão de ziguezague na imagem acima é devido à luz artificial, 50 Hz, outra coisa com a qual temos que lidar.)





Etapas explicadas


Aqui está um código simples para imprimir tudo o que você lê do sensor KY-039:
  // Scriptint de teste do monitor de pulso sensorPin =0; void setup () {Serial.begin (9600);} void loop () {while (1) {Serial.print (analogRead (sensorPin)); Serial.print ('\ n'); }}  

O que você pode obter é algo assim:

Como esta é uma legenda da janela do monitor serial lendo a saída serial do seu Arduino a 9600 baud, todo o processo é cronometrado pelo Serial.print () função, que definirá uma taxa para leitura e plotagem dos valores. De qualquer forma, a curva é muito recortada, pois varia entre 360 ​​e 383 e possui apenas valores inteiros.





Suavização


Para obter uma saída mais uniforme, faça uma média das 20 últimas leituras do sensor. É assim que eu faço. Eu defino uma constante dizendo quantas leituras eu quero:
  #define samp_siz 20  

Então eu tenho uma matriz contendo esse número de leituras:
  int lê [samp_siz];  

Para cada nova leitura, subtraio a leitura mais antiga de uma soma e adiciono a leitura mais recente à soma. Na matriz, substituo a leitura mais antiga pela leitura mais recente.
leitor
  =analogRead (sensorPin); // lê a soma do sensor - =lê [ptr]; // subtrai a leitura mais antiga da soma soma + =leitor; // adiciona a leitura mais recente à soma das leituras [ptr] =leitor; // salva a leitura mais recente no array last =float (sum) / samp_siz; // calcule a média agora ptr ++; // atualiza o índice do array, tem ptr% =samp_siz; // reinicie em 0 quando necessário  

Com um tamanho de matriz de 20 e uma taxa de transmissão de 9600 no monitor serial, posso obter uma plotagem como esta:

Aqui você vê os batimentos cardíacos reais como uma curva ascendente íngreme. Mas você vê também um pequeno padrão de ziguezague. O zigue-zague menor vem da luz da minha cozinha, três lâmpadas LED iluminando a sala. A rede elétrica da minha casa é 240 V, 50 Hz CA. Então, 50 vezes por segundo, há um aumento da intensidade da luz, aparentemente também na faixa de infravermelho. Eu gostaria de suavizar esse ruído de 50 Hz. Deve funcionar, se eu ler os valores do sensor durante um período de 20 ms e tirar uma média de todos os valores. Vamos ver...
  n =0; início =milis (); leitor =0 .; faça {leitor + =leitura analógica (sensorPin); // ler e adicionar valores ... n ++; agora =milis (); } enquanto (agora  

Com esse snippet, eu faço as leituras do sensor em blocos de 20 ms, o que uniformizará a oscilação de 50 Hz causada pela luz artificial. Se você mora em um país com 60 Hz, use blocos de 16,67 ms. Ou 16667µs.

Como já suavizei a curva em seções de 20 ms, na verdade não preciso do array que usei antes, mas como está lá e é facilmente redimensionável, deixo-o lá. E usar um tamanho de array de 5 parece equilibrar o último ruído irritante. Isso é o que eu tenho agora:

A última coisa que preciso fazer é reconhecer qualquer parte do padrão de repetição. Como a inclinação ascendente é mais regular, eu vou em frente. Observe como os valores do eixo y são muito diferentes em todos os gráficos. Eu realmente não posso confiar apenas em valores absolutos. Só posso contar com a subida e descida da curva. Os matemáticos falariam sobre a derivada. Fico satisfeito se encontro n valores crescentes consecutivos, onde n pode ser um valor ajustável útil. Começo com 5. Para isso, tenho o rise_threshold constante definida no código. Quando encontro 5 valores crescentes consecutivos, sei que estou na parte inferior da curva rumo a cima. Eu levo tempo. Eu espero por uma curva decrescente, então espero pelos próximos 5 valores crescentes e anoto o tempo. Em seguida, imprimo o BPM correspondente.

Eu fiz um teste e contado como muitos consecutivo aumentando valores são em o curva e encontrado fora eram entre 10 e 15. Então se eu contagem para 5, eu irá mais certeza saber eu encontrado o começar de o batimento cardíaco.

Como imprimo apenas após cada batimento cardíaco, não haverá muitas impressões. Haverá mais tempo para leitura do sensor. Posso captar um ruído mais frequente, o que não verei, porque o plotter não está ligado. Vamos ver como isso funciona.





O código final

  #define samp_siz 4 # define rise_threshold 5 // Scriptint de teste do monitor de pulso sensorPin =0; void setup () {Serial.begin (9600);} void loop () {float lê [samp_siz], sum; long int agora, ptr; flutue por último, leitor, comece; flutuar primeiro, segundo, terceiro, antes de print_value; bool crescente; int rise_count; int n; long int last_beat; para (int i =0; i  before) {rise_count ++; if (! crescente &&rise_count> rise_threshold) {// Ok, detectamos uma curva crescente, o que implica um batimento cardíaco. // Registre o tempo desde a última batida, acompanhe as duas // vezes anteriores (primeiro, segundo, terceiro) para obter uma média ponderada. // A bandeira crescente nos impede de detectar o mesmo aumento // mais do que uma vez. subindo =verdadeiro; primeiro =milis () - last_beat; last_beat =milis (); // Calcular a média ponderada da taxa de batimentos cardíacos // de acordo com os três últimos batimentos print_value =60000. / (0,4 * primeiro + 0,3 * segundo + 0,3 * terceiro); Serial.print (print_value); Serial.print ('\ n'); terceiro =segundo; segundo =primeiro; }} else {// Ok, a curva está caindo e subindo =false; ascensão_contagem =0; } antes =último; ptr ++; ptr% =samp_siz; }}  

Funciona muito bem. Aqui está um vídeo.

Observe que o minúsculo led RX pisca no Arduino em sincronia com meu coração. Simplesmente porque quando há um batimento cardíaco, a taxa é calculada e impressa no serial, que pisca o led. Quando o dedo se move um pouco, haverá leituras de erro.





Desenvolvimento adicional


No momento, a taxa impressa é calculada com base nas últimas três batidas. Mas poderia ser mais apropriado calculá-lo com base em um período de, digamos, 15 s. Eu poderia salvar 15 valores de taxa consecutivos, calcular a média e, em seguida, deixar de fora os cinco valores mais distantes da média e calcular uma nova média. Isso forneceria uma medição confiável e estável da freqüência cardíaca.

Eu apenas testei o sensor em minha esposa e em mim. Cada etapa para aumentar o sinal que fiz com base nas leituras anteriores. Outra pessoa pode ter outro tipo de batimento cardíaco, causando uma curva de formato diferente, que precisa de outra abordagem para encontrar o batimento. Talvez seja a curva descendente que é mais fácil de reconhecer. Ou o topo. E o que acontece se o pulso for 180 - 200 BPM? Encontrar a curva ascendente pode ser mais complicado.

Código

  • Versão final
Versão final C / C ++
O programa lê a pulsação e imprime a taxa na janela serial.
 #define samp_siz 4 # define rise_threshold 4 // Script de teste do monitor de pulso sensorPin =0; void setup () {Serial.begin (9600);} void loop () {leituras flutuantes [samp_siz], soma; long int agora, ptr; flutue por último, leitor, comece; flutuar primeiro, segundo, terceiro, antes de print_value; bool crescente; int rise_count; int n; long int last_beat; para (int i =0; i  before) {rise_count ++; if (! crescente &&rise_count> rise_threshold) {// Ok, detectamos uma curva crescente, o que implica uma pulsação. // Registre o tempo desde a última batida, acompanhe as duas // vezes anteriores (primeira, segunda, terceira) para obter uma média ponderada. // A bandeira crescente nos impede de detectar a mesma elevação mais de uma vez. crescente =verdadeiro; primeiro =milis () - last_beat; last_beat =milis (); // Calcular a média ponderada da taxa de batimentos cardíacos // de acordo com os três últimos batimentos print_value =60000. / (0,4 * primeiro + 0,3 * segundo + 0,3 * terceiro); Serial.print (print_value); Serial.print ('\ n'); terceiro =segundo; segundo =primeiro; }} else {// Ok, a curva está caindo e subindo =false; ascensão_contagem =0; } antes =último; ptr ++; ptr% =samp_siz; }} 

Esquemas


Processo de manufatura

  1. Sensor de cor - Trabalho e aplicações
  2. OPT3007 Sensor de luz ambiente ultrafino
  3. Transmissão de dados do sensor de uma placa ppDAQC Pi usando InitialState
  4. Temperatura do Raspberry Pi e sensor de luz
  5. Luz solar da garagem para o nó do sensor sem fio MSP430
  6. Sensor de luz ativado por voz e SMS usando Raspberry Pi e Twilio
  7. Windows 10 IoT Core - Leitura dos pulsos de frequência cardíaca
  8. Sensor de luz Raspberry Pi:um tutorial LDR simples
  9. Sensor de luz digital
  10. Monitor de frequência cardíaca remoto