Meça a Frequência Cardíaca com Sensor KY-039 e Arduino
Componentes e Materiais
| Componente | Quantidade |
|---|---|
| Arduino UNO | 1 |
| Sensor de Batimento Cardíaco KY-039 | 1 |
| Jumpers (genéricos) | 1 |
Sobre o Projeto
No kit de 37 sensores para Arduino, existe um sensor de batimento cardíaco. O nome promete demais: as pessoas acham que ele fornece um número digital via I2C com a frequência cardíaca. Na verdade, ele apenas fornece um valor analógico de 0 a 1023, indicando quanta luz infravermelha o fototransistor recebe (ou seja, quanto o dedo está sombreando o sensor). Quanto maior o valor, menos luz IR.
Resumindo: coloque o dedo entre o LED IR e o fototransistor. A dilatação dos vasos sanguíneos a cada batida filtra a luz IR, criando um sinal pulsante.
Este projeto mostra como converter esse sinal em uma taxa de batimentos por minuto (BPM), como 66 BPM.
Passos Simples
Se você apenas ler e plotar os valores brutos do KY-039, obtém um gráfico ruidoso (valores inteiros entre ~360-383).
Calculando a média de várias leituras (ex: 20), o sinal fica mais suave e já é possível ver os picos do batimento.
O pequeno padrão zig-zag residual é causado por luz artificial (50 Hz). Para eliminá-lo, faça a média das leituras durante janelas de 20 ms (período de 50 Hz). Em países com 60 Hz, use 16.67 ms.
Explicação dos Passos
Leitura Bruta
int sensorPin = A0;
void setup() { Serial.begin(9600); }
void loop() {
while(1) { Serial.println(analogRead(sensorPin)); }
}
Suavização com Média Móvel (Array Circular)
#define samp_siz 20
int reads[samp_siz];
int ptr = 0;
long sum = 0;
void loop() {
int reader = analogRead(sensorPin);
sum -= reads[ptr];
sum += reader;
reads[ptr] = reader;
float last = (float)sum / samp_siz;
ptr = (ptr + 1) % samp_siz;
// use 'last' para detecção de pico
}
Eliminação do Ruído de 50 Hz (Média em Janela de 20 ms)
int n = 0;
unsigned long start = millis();
float reader = 0;
do {
reader += analogRead(sensorPin);
n++;
} while (millis() < start + 20);
reader /= n; // média das leituras nos 20 ms
Detecção do Batimento (Derivada Positiva)
Como os valores absolutos variam, detectamos n leituras consecutivas crescentes (ex: rise_threshold = 5). Ao detectar a subida, registramos o tempo (millis()) e calculamos o BPM baseado nos três últimos intervalos (média ponderada: 40% último, 30% penúltimo, 30% antepenúltimo).
Código Final Completo
#define samp_siz 4
#define rise_threshold 5
int sensorPin = A0;
void setup() { Serial.begin(9600); }
void loop() {
float reads[samp_siz], sum = 0;
long int now, ptr = 0;
float last, reader, start;
float first = 0, second = 0, third = 0, before = 0, print_value = 0;
bool rising = false;
int rise_count = 0;
int n;
long int last_beat = 0;
for (int i = 0; i < samp_siz; i++) reads[i] = 0;
while (1) {
// Média em 20 ms (elimina 50 Hz)
n = 0; start = millis(); reader = 0;
do {
reader += analogRead(sensorPin);
n++;
now = millis();
} while (now < start + 20);
reader /= n;
// Atualiza array circular e média
sum -= reads[ptr];
sum += reader;
reads[ptr] = reader;
last = sum / samp_siz;
// Detecção de curva ascendente (batimento)
if (last > before) {
rise_count++;
if (!rising && rise_count > rise_threshold) {
rising = true;
first = millis() - last_beat;
last_beat = millis();
// Média ponderada dos 3 últimos intervalos
print_value = 60000.0 / (0.4 * first + 0.3 * second + 0.3 * third);
Serial.println(print_value);
third = second;
second = first;
}
} else {
rising = false;
rise_count = 0;
}
before = last;
ptr = (ptr + 1) % samp_siz;
}
}
Funciona bem. O pequeno LED RX no Arduino pisca sincronizado com o batimento (pois envia dado pela serial). Movimentos do dedo causam leituras errôneas.
Desenvolvimentos Futuros
Poderia calcular a média em uma janela de 15 segundos, descartar outliers e recalcular para medição mais estável. Testes apenas em duas pessoas; curvas diferentes podem exigir ajustes (detectar queda, topo, ou batimentos muito rápidos >180 BPM).
Esquemático
Conexão simples: pino S do KY-039 no A0, VCC no 5V, GND no GND.
Processo de manufatura
- Sensores de Cor: Como Funcionam e Principais Aplicações
- OPT3007 Sensor de Luz Ambiente Ultra-Fino – Medição Precisa de Luz para Dispositivos Inteligentes
- Transmissão de Dados de Temperatura em Tempo Real do ppDAQC Pi-Plate para InitialState com Raspberry Pi Headless
- Construa um Sistema de Monitoramento de Temperatura e Luz Multi-Sensor com Raspberry Pi e DS18B20
- De Luz Solar de $4 a Nó de Sensor Sem Fio Inteligente: MSP430 + nRF24L01+ para Monitoramento de Jardim
- Sensor de Ocupação de Banheiro com Raspberry Pi: Alertas por Voz e SMS via Twilio
- Leia Pulso de Frequência Cardíaca com Windows 10 IoT Core no Raspberry Pi – Guia Passo a Passo
- Tutorial de Sensor de Luz no Raspberry Pi – Ligue um LDR e Leia Níveis de Luz com Python
- Sensor de Luz Digital – Acione um LED com Luz Ambiente Usando Windows 10 IoT Core
- Sistema Remoto de Monitoramento de Frequência Cardíaca com Alertas AWS IoT