Измерение пульса датчиком KY-039 на Arduino
Компоненты и материалы
| Компонент | Количество |
|---|---|
| Arduino UNO | 1 |
| Датчик пульса KY-039 | 1 |
| Перемычки (набор) | 1 |
О проекте
В наборе из 37 датчиков для Arduino есть датчик пульса. Название обещает слишком много: многие думают, что он выдаёт цифровое значение BPM по I2C. На самом деле он выдаёт только «аналоговое» значение 0–1023 — уровень ИК-света на фототранзисторе. Чем выше значение, тем меньше света.
Принцип: палец между ИК-светодиодом и фототранзистором. Пульсация расширяет сосуды, модулируя пропускание ИК-излучения. Получаем пульсирующий сигнал.
В проекте описано, как превратить этот сигнал в частоту сердечных сокращений (например, 66 уд/мин).
Простые шаги
Сырые показания датчика очень зашумлены (целочисленные, скачут).
Если усреднить группу измерений — пульс становится виден:
Мелкий зигзаг — помехи от сети 50 Гц (ИК-мерцание ламп). Нужно убрать и это.
Алгоритм сглаживания
- Усреднение за 20 мс — убирает 50 Гц (период 20 мс). Для 60 Гц используйте 16,67 мс.
- Скользящее окно из 4–5 значений — убирает остаточный шум.
- Детекция подъёма — ищем N подряд возрастающих значений (N=4–5). Это фронт пульсовой волны.
- Расчёт BPM — взвешенное среднее по последним 3 интервалам:
60000 / (0.4·T1 + 0.3·T2 + 0.3·T3).
Финальный код
#define samp_siz 4
#define rise_threshold 4
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) {
// Усреднение за 20 мс (убирает 50 Гц)
n = 0;
start = millis();
reader = 0;
do {
reader += analogRead(sensorPin);
n++;
now = millis();
} while (now < start + 20);
reader /= n;
// Скользящее окно
sum -= reads[ptr];
sum += reader;
reads[ptr] = reader;
last = sum / samp_siz;
// Детекция подъёма
if (last > before) {
rise_count++;
if (!rising && rise_count > rise_threshold) {
rising = true;
first = millis() - last_beat;
last_beat = millis();
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 %= samp_siz;
}
}
Код работает стабильно. На видео видно, как мигает RX-LED в такт пульсу.
Дальнейшее развитие
- Усреднение по окну 15 секунд с отбрасыванием выбросов.
- Адаптация под разные формы пульсовой волны (спад, пик).
- Работа при высоком пульсе (180–200 уд/мин).
Схема подключения
Производственный процесс
- Цветовые датчики: принцип работы и ключевые применения
- OPT3007 — ультратонкий датчик освещенности: точное измерение света для умных устройств
- Потоковая передача данных температуры с ppDAQC Pi-Plate в InitialState на headless Raspberry Pi
- Создание многодатчиковой системы мониторинга температуры и света с Raspberry Pi и DS18B20
- От $4 солнечного фонаря к умному беспроводному сенсорному узлу: MSP430 + nRF24L01+ для мониторинга сада
- Датчик занятости ванной комнаты на Raspberry Pi с голосовыми и SMS-уведомлениями через Twilio
- Считывание пульса сердечного ритма на Windows 10 IoT Core на Raspberry Pi — пошаговое руководство
- Учебник по датчику света на Raspberry Pi: подключение фоторезистора и чтение уровня освещенности на Python
- Цифровой датчик света — управление светодиодом по освещённости на Windows 10 IoT Core
- Система удалённого мониторинга сердечного ритма с алертами AWS IoT