10#ifndef M5_UNIT_HEART_UTILITY_PULSE_MONITOR_HPP
11#define M5_UNIT_HEART_UTILITY_PULSE_MONITOR_HPP
17#include <m5_utility/log/library_log.hpp>
34 explicit EMA(
float factor) : _alpha(factor)
41 _ema_value = std::numeric_limits<float>::quiet_NaN();
49 if (!std::isnan(_ema_value)) {
50 _ema_value = _alpha * new_value + (1.0f - _alpha) * _ema_value;
52 _ema_value = new_value;
58 float _alpha{}, _ema_value{std::numeric_limits<float>::quiet_NaN()};
70 Filter(
const float cutoff,
const float sampling_rate)
80 constexpr float pi{3.14159265358979323846f};
82 _samplingRate = sampling_rate;
83 _prevIn = _prevOut = 0.0f;
84 auto dt = 1.0f / _samplingRate;
85 auto RC = 1.0f / (2.0f * pi * _cutoff);
86 _alpha = RC / (RC + dt);
95 float out = _ema.
update(_alpha * (_prevOut + value - _prevIn));
103 float _cutoff{}, _samplingRate{};
104 float _prevIn{}, _prevOut{};
119 explicit PulseMonitor(
const uint32_t samplingRate = 100,
const uint32_t sec = 5)
121 _sampling_rate{(float)samplingRate},
122 _max_samples{static_cast<size_t>(samplingRate) * sec},
123 _filterIR(5.0f, samplingRate)
125 assert(sec >= 1 &&
"sec must be greater or equal than 1");
126 assert(samplingRate >= 1.0f &&
"SamplingRate must be greater or equal than 1.0f");
166 void push_back(
const float ir,
const float red);
180 return !_dataIR.empty() ? _dataIR.back() : std::numeric_limits<float>::quiet_NaN();
184 float calculate_bpm();
188 float _sampling_rate{};
189 size_t _max_samples{};
191 Filter _filterIR{0.5f, 100.f};
192 std::deque<float> _dataIR;
199 float _avered{}, _aveir{};
200 float _sumredrms{}, _sumirrms{};
Exponential Moving Average.
Definition pulse_monitor.hpp:30
EMA(float factor)
Constructor.
Definition pulse_monitor.hpp:34
float update(float new_value)
Update with a new value and return the smoothed result.
Definition pulse_monitor.hpp:47
void clear()
Clear the stored value.
Definition pulse_monitor.hpp:39
Apply a high-pass filter and invert polarity.
Definition pulse_monitor.hpp:65
float process(const float value)
Process a sample through the filter.
Definition pulse_monitor.hpp:93
void setSamplingRate(const float cutoff, const float sampling_rate)
Set the sampling rate and reset filter state.
Definition pulse_monitor.hpp:78
Filter(const float cutoff, const float sampling_rate)
Constructor.
Definition pulse_monitor.hpp:70
Calculate BPM and SpO2, and detect the pulse beat.
Definition pulse_monitor.hpp:112
bool isBeat() const
Detect beat?
Definition pulse_monitor.hpp:130
void push_back(const float ir)
Push back IR.
Definition pulse_monitor.cpp:39
PulseMonitor(const uint32_t samplingRate=100, const uint32_t sec=5)
Constructor.
Definition pulse_monitor.hpp:119
void clear()
Clear inner data.
Definition pulse_monitor.cpp:29
float SpO2() const
Gets the SpO2.
Definition pulse_monitor.hpp:143
void setSamplingRate(const uint32_t samplingRate)
Set the sampling rate.
Definition pulse_monitor.cpp:16
float latestIR() const
Filtered latest ir value.
Definition pulse_monitor.hpp:178
void update()
Update status.
Definition pulse_monitor.cpp:72
float bpm() const
Gets the BPM.
Definition pulse_monitor.hpp:135
Top level namespace of M5Stack.