Введение
Датчик пульса (finger pulse sensor, оптический датчик, измеряющий изменение светопроницаемости пальца, синхронное с сердцебиением) и микрофонный звуковой датчик — два новых сенсора, объединённых в этой статье как примеры аналоговых датчиков, требующих обработки сигнала во времени (а не простого считывания статичного значения), в отличие от большинства ранее разобранных аналоговых датчиков.
Концепция
Пульсометр (часто на базе фотоплетизмографии — измерения изменения отражённого/прошедшего света через ткань, синхронного с пульсацией крови при сердцебиении) даёт переменный аналоговый сигнал, в котором интересен не абсолютный уровень, а периодичность пиков, соответствующих отдельным ударам сердца — обработка требует обнаружения пиков сигнала и измерения интервала между ними для вычисления частоты пульса в ударах в минуту. Микрофонный звуковой датчик (обычно с встроенным компаратором, дающим и аналоговый, и цифровой пороговый выход) аналогично даёт переменный сигнал, отражающий уровень звука в реальном времени — типичное применение — обнаружение звуковых событий (хлопок, громкий звук) через цифровой пороговый выход, а не точное измерение уровня шума (для чего нужны значительно более качественные, калиброванные микрофоны).
Пример кода
// Пульсометр — обнаружение пиков сигнала для вычисления частоты пульса
const int PULSE_SENSOR_PIN = A0;
const int THRESHOLD = 550; // порог обнаружения пика — требует калибровки для конкретного пользователя
int lastBeatTime = 0;
int beatCount = 0;
unsigned long windowStartTime = 0;
bool wasAboveThreshold = false;
void setup() {
Serial.begin(9600);
windowStartTime = millis();
}
void loop() {
int signal = analogRead(PULSE_SENSOR_PIN);
bool isAboveThreshold = signal > THRESHOLD;
// Обнаружение пика — переход сигнала ИЗ "ниже порога" В "выше порога" (передний фронт)
if (isAboveThreshold && !wasAboveThreshold) {
unsigned long now = millis();
if (now - lastBeatTime > 300) { // минимум 300 мс между ударами — защита от ложных пиков (>200 уд/мин невозможно)
beatCount++;
lastBeatTime = now;
}
}
wasAboveThreshold = isAboveThreshold;
// Каждые 10 секунд — пересчёт в удары в минуту и сброс счётчика
if (millis() - windowStartTime >= 10000) {
int bpm = beatCount * 6; // количество ударов за 10 секунд * 6 = удары в минуту
Serial.print("BPM:");
Serial.println(bpm);
beatCount = 0;
windowStartTime = millis();
}
}
// Звуковой датчик — обнаружение громкого звукового события через цифровой выход
const int SOUND_DIGITAL_PIN = 3;
const int SOUND_ANALOG_PIN = A1;
void setupSoundSensor() {
pinMode(SOUND_DIGITAL_PIN, INPUT);
}
void loopSoundSensor() {
bool soundDetected = digitalRead(SOUND_DIGITAL_PIN); // обычно LOW при превышении порога — проверить датчик
int soundLevel = analogRead(SOUND_ANALOG_PIN); // относительный, не калиброванный уровень
if (soundDetected) {
Serial.println("EVENT:LOUD_SOUND");
}
}
Пояснения к коду
Защита now - lastBeatTime > 300 в обработке пульса — критично важная деталь: без неё шум или дребезг сигнала вокруг порогового значения мог бы зарегистрировать несколько ложных «ударов» за время одного реального удара сердца, что особенно вероятно для зашумлённого сигнала недорогого датчика; 300 миллисекунд соответствует физиологическому пределу — частота пульса свыше 200 ударов в минуту крайне маловероятна для большинства практических применений, что делает любой более частый «пик» с высокой вероятностью шумом, а не реальным ударом. Расчёт beatCount * 6 для перевода в удары в минуту работает из окна измерения именно в 10 секунд (10 секунд × 6 = 60 секунд = 1 минута) — изменение длительности окна измерения требует соответствующего изменения этого множителя.
Подводные камни
- Использование фиксированного, не калиброванного порога (
THRESHOLD = 550в примере) для обнаружения пульса, без учёта того, что амплитуда сигнала фотоплетизмографического датчика значительно различается между разными людьми (толщина пальца, цвет кожи, кровенаполнение в данный момент) и даже у одного человека в разных условиях — для надёжной работы порог обычно нужно либо калибровать индивидуально, либо (что более надёжно) определять адаптивно, отслеживая динамический диапазон сигнала в реальном времени, а не использовать единое статичное число. - Чрезмерное доверие точности измерения пульса дешёвым, не медицинским датчиком этого типа — подобные модули из общих наборов датчиков предназначены для образовательных/хобби-проектов, демонстрирующих принцип, но не для медицинской диагностики; точность измерения существенно зависит от качества контакта пальца с датчиком, посторонней засветки, и движения пальца во время измерения, и результат не должен восприниматься как медицински достоверное измерение.
- Игнорирование инвертированной логики цифрового выхода многих дешёвых звуковых модулей (где
LOWозначает превышение порога, а неHIGH, как могло бы интуитивно ожидаться) — конкретная полярность зависит от используемого компаратора на плате модуля, и перед использованием стоит явно протестировать реальное поведение конкретного экземпляра модуля (например, через простой Serial-вывод значения при намеренно громком звуке), а не предполагать «интуитивно ожидаемую» полярность сигнала. - Попытка использовать аналоговый выход дешёвого звукового модуля для точного измерения уровня громкости в децибелах — встроенный микрофон и схема усиления таких модулей обычно не откалиброваны и не линейны в широком диапазоне, что делает их пригодными для относительного обнаружения «тихо/громко» или конкретных звуковых событий, но не для точного, абсолютного измерения уровня шума, для чего требуется специализированное, откалиброванное измерительное оборудование.