M5Unit-HEART 0.2.1 git rev:e0975a4
Loading...
Searching...
No Matches
unit_MAX30100.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD
3 *
4 * SPDX-License-Identifier: MIT
5 */
10#ifndef M5_UNIT_HEART_UNIT_MAX30100_HPP
11#define M5_UNIT_HEART_UNIT_MAX30100_HPP
12
13#include <M5UnitComponent.hpp>
14#include <m5_utility/stl/extension.hpp>
15#include <m5_utility/container/circular_buffer.hpp>
16#include <limits> // NaN
17
18namespace m5 {
19namespace unit {
24namespace max30100 {
29enum class Mode : uint8_t {
30 None,
31 HROnly = 0x02,
32 SpO2,
33};
34
40enum class Sampling : uint8_t {
41 Rate50,
42 Rate100,
43 Rate167,
44 Rate200,
45 Rate400,
46 Rate600,
47 Rate800,
48 Rate1000,
49};
50
55enum class LEDPulse : uint8_t {
56 Width200,
57 Width400,
58 Width800,
59 Width1600,
60};
61
84
85constexpr uint8_t MAX_FIFO_DEPTH{16};
86
91struct Data {
92 std::array<uint8_t, 4> raw{};
94 inline uint16_t ir() const
95 {
96 return m5::types::big_uint16_t(raw[0], raw[1]).get();
97 }
99 inline uint16_t red() const
100 {
101 return m5::types::big_uint16_t(raw[2], raw[3]).get();
102 }
103};
104
110 std::array<uint8_t, 2> raw{0x80, 0x00}; // [0]:integer [1]:fraction sentinel:0x80(-128) is outside operating range
112 inline float temperature() const
113 {
114 return celsius();
115 }
117 inline float celsius() const
118 {
119 return (raw[0] != 0x80) ? static_cast<int8_t>(raw[0]) + raw[1] * 0.0625f
120 : std::numeric_limits<float>::quiet_NaN();
121 }
123 inline float fahrenheit() const
124 {
125 return celsius() * 9.0f / 5.0f + 32.f;
126 }
127};
128
130namespace command {
131// STATUS
132constexpr uint8_t READ_INTERRUPT_STATUS{0x00};
133constexpr uint8_t INTERRUPT_ENABLE{0x01};
134// FIFO
135constexpr uint8_t FIFO_WRITE_POINTER{0x02};
136constexpr uint8_t FIFO_OVERFLOW_COUNTER{0x03};
137constexpr uint8_t FIFO_READ_POINTER{0x04};
138constexpr uint8_t FIFO_DATA_REGISTER{0x05};
139// CONFIGURATION
140constexpr uint8_t MODE_CONFIGURATION{0x06};
141constexpr uint8_t SPO2_CONFIGURATION{0x07};
142constexpr uint8_t LED_CONFIGURATION{0x09};
143// TEMPERATURE
144constexpr uint8_t TEMP_INTEGER{0x16};
145constexpr uint8_t TEMP_FRACTION{0x17};
146// PART ID
147constexpr uint8_t READ_REVISION_ID{0xFE};
148constexpr uint8_t READ_PART_ID{0xFF};
149
150} // namespace command
151
152struct SpO2Configuration;
154
155} // namespace max30100
156
162class UnitMAX30100 : public Component, public PeriodicMeasurementAdapter<UnitMAX30100, max30100::Data> {
163 M5_UNIT_COMPONENT_HPP_BUILDER(UnitMAX30100, 0x57);
164
165public:
171 struct config_t {
173 bool start_periodic{true};
175 max30100::Mode mode{max30100::Mode::SpO2};
177 max30100::Sampling rate{max30100::Sampling::Rate100};
179 max30100::LEDPulse width{max30100::LEDPulse::Width1600};
181 m5::unit::max30100::LED ir_current{max30100::LED::Current27_1};
183 bool high_resolution{true};
185 m5::unit::max30100::LED red_current{max30100::LED::Current27_1};
186 };
187
190 explicit UnitMAX30100(const uint8_t addr = DEFAULT_ADDRESS)
191 : Component(addr), _data{new m5::container::CircularBuffer<max30100::Data>(max30100::MAX_FIFO_DEPTH)}
192 {
193 auto ccfg = component_config();
194 ccfg.clock = 400 * 1000U;
195 ccfg.stored_size = max30100::MAX_FIFO_DEPTH;
196 component_config(ccfg);
197 }
198 virtual ~UnitMAX30100()
199 {
200 }
201
203 virtual bool begin() override;
205 virtual void update(const bool force = false) override;
206
209
211 {
212 return _cfg;
213 }
215 inline void config(const config_t& cfg)
216 {
217 _cfg = cfg;
218 }
220
224 inline uint16_t ir() const
225 {
226 return !empty() ? oldest().ir() : 0;
227 }
229 inline uint16_t red() const
230 {
231 return !empty() ? oldest().red() : 0;
232 }
239 inline uint8_t retrieved() const
240 {
241 return _retrieved;
242 }
247 [[deprecated("Please use retrieved()")]] inline uint8_t retrived() const
248 {
249 return retrieved();
250 }
255 inline uint8_t overflow() const
256 {
257 return _overflow;
258 }
260
266 uint32_t calculateSamplingRate();
271 [[deprecated("Please use calculateSamplingRate()")]] inline uint32_t caluculateSamplingRate()
272 {
273 return calculateSamplingRate();
274 }
275
278
283 {
284 return PeriodicMeasurementAdapter<UnitMAX30100, max30100::Data>::startPeriodicMeasurement();
285 }
298 const max30100::LEDPulse width, const max30100::LED ir_current,
299 const bool high_resolution = false,
300 const max30100::LED red_current = max30100::LED::Current0_0)
301 {
302 return PeriodicMeasurementAdapter<UnitMAX30100, max30100::Data>::startPeriodicMeasurement(
303 mode, rate, width, ir_current, high_resolution, red_current);
304 }
310 {
311 return PeriodicMeasurementAdapter<UnitMAX30100, max30100::Data>::stopPeriodicMeasurement();
312 }
314
317
322 bool readMode(max30100::Mode& mode);
329 bool writeMode(const max30100::Mode mode);
335 bool readShutdownControl(bool& shdn);
342 bool writeShutdownControl(const bool shdn);
344
372
379 bool readSpO2Configuration(bool& resolution, max30100::Sampling& rate, max30100::LEDPulse& width);
387 bool writeSpO2Configuration(const bool resolution, const max30100::Sampling rate, const max30100::LEDPulse width);
388
390 inline bool readSpO2HighResolution(bool& enabled)
391 {
392 max30100::Sampling rate{};
393 max30100::LEDPulse width{};
394 return readSpO2Configuration(enabled, rate, width);
395 }
397 bool writeSpO2HighResolution(const bool enabled);
400 {
401 return writeSpO2HighResolution(true);
402 }
405 {
406 return writeSpO2HighResolution(false);
407 }
410 {
411 bool enabled{};
412 max30100::LEDPulse width{};
413 return readSpO2Configuration(enabled, rate, width);
414 }
419 {
420 bool enabled{};
421 max30100::Sampling rate{};
422 return readSpO2Configuration(enabled, rate, width);
423 }
427
432
438 bool readLEDCurrent(max30100::LED& ir_current, max30100::LED& red_current);
445 bool writeLEDCurrent(const max30100::LED ir_current, const max30100::LED red_current);
447
450
460
464 inline bool readFIFOReadPointer(uint8_t& rptr)
465 {
466 rptr = 0xFF;
467 return read_register8(max30100::command::FIFO_READ_POINTER, rptr);
468 }
470 inline bool writeFIFOReadPointer(const uint8_t rptr)
471 {
472 return writeRegister8(max30100::command::FIFO_READ_POINTER, rptr);
473 }
475 inline bool readFIFOWritePointer(uint8_t& wptr)
476 {
477 wptr = 0xFF;
478 return read_register8(max30100::command::FIFO_WRITE_POINTER, wptr);
479 }
481 inline bool writeFIFOWritePointer(const uint8_t wptr)
482 {
483 return writeRegister8(max30100::command::FIFO_WRITE_POINTER, wptr);
484 }
486 inline bool readFIFOOverflowCounter(uint8_t& cnt)
487 {
488 cnt = 0xFF;
489 return read_register8(max30100::command::FIFO_OVERFLOW_COUNTER, cnt);
490 }
492 inline bool writeFIFOOverflowCounter(const uint8_t cnt)
493 {
494 return writeRegister8(max30100::command::FIFO_OVERFLOW_COUNTER, cnt);
495 }
497 bool resetFIFO();
499
505 bool reset();
506
514 bool readRevisionID(uint8_t& rev);
515
516protected:
517 bool read_register(const uint8_t reg, uint8_t* buf, const size_t len);
518 bool read_register8(const uint8_t reg, uint8_t& v);
519
520 bool start_periodic_measurement();
521 bool start_periodic_measurement(const max30100::Mode mode, const max30100::Sampling rate,
522 const max30100::LEDPulse width, const max30100::LED ir_current,
523 const bool resolution, const max30100::LED red_current);
524 bool stop_periodic_measurement();
525
526 bool read_FIFO();
527 bool read_measurement_temperature(max30100::TemperatureData& td);
528
529 bool write_spo2_configuration(const max30100::SpO2Configuration& sc);
530
531 M5_UNIT_COMPONENT_PERIODIC_MEASUREMENT_ADAPTER_HPP_BUILDER(UnitMAX30100, max30100::Data);
532
533protected:
534 max30100::Mode _mode{max30100::Mode::None};
535 uint8_t _retrieved{}, _overflow{};
536 std::unique_ptr<m5::container::CircularBuffer<max30100::Data>> _data{};
537
538 config_t _cfg{};
539};
540
541} // namespace unit
542} // namespace m5
543
544#endif
Pulse oximetry and heart-rate sensor.
void config(const config_t &cfg)
Set the configuration.
Definition unit_MAX30100.hpp:215
bool readSpO2Configuration(bool &resolution, max30100::Sampling &rate, max30100::LEDPulse &width)
Read the SpO2 configuration.
Definition unit_MAX30100.cpp:305
uint8_t overflow() const
The number of samples lost.
Definition unit_MAX30100.hpp:255
bool readFIFOWritePointer(uint8_t &wptr)
Read the FIFO write pointer.
Definition unit_MAX30100.hpp:475
bool writeSpO2HighResolutionDisable()
Write the SpO2 high resolution mode to disable.
Definition unit_MAX30100.hpp:404
bool writeFIFOReadPointer(const uint8_t rptr)
Write the FIFO read pointer.
Definition unit_MAX30100.hpp:470
bool readRevisionID(uint8_t &rev)
Read the revision ID.
Definition unit_MAX30100.cpp:501
bool writeSpO2HighResolutionEnable()
Write the SpO2 high resolution mode to enable.
Definition unit_MAX30100.hpp:399
bool readShutdownControl(bool &shdn)
Read the shutdown control.
Definition unit_MAX30100.cpp:279
virtual bool begin() override
Begin the unit.
Definition unit_MAX30100.cpp:163
bool measureTemperatureSingleshot(max30100::TemperatureData &td)
Measure temperature single shot.
Definition unit_MAX30100.cpp:402
uint32_t calculateSamplingRate()
Calculate the sampling rate from the current settings.
Definition unit_MAX30100.cpp:507
bool writeFIFOWritePointer(const uint8_t wptr)
Write the FIFO write pointer.
Definition unit_MAX30100.hpp:481
uint32_t caluculateSamplingRate()
Deprecated alias of calculateSamplingRate()
Definition unit_MAX30100.hpp:271
bool startPeriodicMeasurement()
Start periodic measurement in the current settings.
Definition unit_MAX30100.hpp:282
bool writeSpO2HighResolution(const bool enabled)
Write the SpO2 resolution mode.
Definition unit_MAX30100.cpp:355
bool writeSpO2LEDPulseWidth(const max30100::LEDPulse width)
Write LED pulse width.
Definition unit_MAX30100.cpp:365
bool writeMode(const max30100::Mode mode)
Write the operation mode.
Definition unit_MAX30100.cpp:261
uint8_t retrived() const
Deprecated alias of retrieved()
Definition unit_MAX30100.hpp:247
config_t config()
Gets the configuration.
Definition unit_MAX30100.hpp:210
bool readFIFOOverflowCounter(uint8_t &cnt)
Read the FIFO overflow counter.
Definition unit_MAX30100.hpp:486
bool writeFIFOOverflowCounter(const uint8_t cnt)
Write the FIFO overflow counter.
Definition unit_MAX30100.hpp:492
virtual void update(const bool force=false) override
Update the unit.
Definition unit_MAX30100.cpp:192
uint8_t retrieved() const
Number of data last retrieved.
Definition unit_MAX30100.hpp:239
bool writeSpO2Configuration(const bool resolution, const max30100::Sampling rate, const max30100::LEDPulse width)
Write the SpO2 configuration.
Definition unit_MAX30100.cpp:321
bool readMode(max30100::Mode &mode)
Read the operation mode.
Definition unit_MAX30100.cpp:250
bool writeSpO2SamplingRate(const max30100::Sampling rate)
Write the sampling rate.
Definition unit_MAX30100.cpp:345
bool writeShutdownControl(const bool shdn)
Write the shutdown control.
Definition unit_MAX30100.cpp:290
bool stopPeriodicMeasurement()
Stop periodic measurement.
Definition unit_MAX30100.hpp:309
bool writeLEDCurrent(const max30100::LED ir_current, const max30100::LED red_current)
Write the LED current.
Definition unit_MAX30100.cpp:388
bool startPeriodicMeasurement(const max30100::Mode mode, const max30100::Sampling rate, const max30100::LEDPulse width, const max30100::LED ir_current, const bool high_resolution=false, const max30100::LED red_current=max30100::LED::Current0_0)
Start periodic measurement.
Definition unit_MAX30100.hpp:297
bool readSpO2HighResolution(bool &enabled)
Read the SpO2 resolution mode.
Definition unit_MAX30100.hpp:390
bool readSpO2SamplingRate(max30100::Sampling &rate)
Read the sampling rate.
Definition unit_MAX30100.hpp:409
bool reset()
Reset.
Definition unit_MAX30100.cpp:423
UnitMAX30100(const uint8_t addr=DEFAULT_ADDRESS)
Constructor.
Definition unit_MAX30100.hpp:190
bool resetFIFO()
Reset FIFO pointer and counter.
Definition unit_MAX30100.cpp:396
bool readSpO2LEDPulseWidth(max30100::LEDPulse &width)
Read LED pulse width.
Definition unit_MAX30100.hpp:418
uint16_t red() const
Oldest Red.
Definition unit_MAX30100.hpp:229
uint16_t ir() const
Oldest IR.
Definition unit_MAX30100.hpp:224
bool readFIFOReadPointer(uint8_t &rptr)
Read the FIFO read pointer.
Definition unit_MAX30100.hpp:464
bool readLEDCurrent(max30100::LED &ir_current, max30100::LED &red_current)
Read the LED current.
Definition unit_MAX30100.cpp:375
Top level namespace of M5Stack.
For MAX30100.
Unit-related namespace.
Settings for begin.
Definition unit_MAX30100.hpp:171
m5::unit::max30100::LED red_current
Led current for Red if start on begin (only SpO2)
Definition unit_MAX30100.hpp:185
m5::unit::max30100::LED ir_current
Led current for IR if start on begin.
Definition unit_MAX30100.hpp:181
max30100::Sampling rate
Sampling rate if start on begin.
Definition unit_MAX30100.hpp:177
max30100::LEDPulse width
Led pulse width if start on begin.
Definition unit_MAX30100.hpp:179
bool start_periodic
Start periodic measurement on begin?
Definition unit_MAX30100.hpp:173
max30100::Mode mode
Operating mode if start on begin.
Definition unit_MAX30100.hpp:175
bool high_resolution
The SpO2 ADC resolution if start on begin.
Definition unit_MAX30100.hpp:183
Measurement data group.
Definition unit_MAX30100.hpp:91
std::array< uint8_t, 4 > raw
Definition unit_MAX30100.hpp:92
uint16_t red() const
Gets the Red value.
Definition unit_MAX30100.hpp:99
uint16_t ir() const
Gets the IR value.
Definition unit_MAX30100.hpp:94
Measurement data group for temperature.
Definition unit_MAX30100.hpp:109
float fahrenheit() const
Temperature (Fahrenheit)
Definition unit_MAX30100.hpp:123
float celsius() const
Temperature (Celsius)
Definition unit_MAX30100.hpp:117
float temperature() const
Temperature (Celsius)
Definition unit_MAX30100.hpp:112
Mode
Operation mode.
Definition unit_MAX30100.hpp:29
@ HROnly
HR only enabled.
@ SpO2
SPO2 and HR enabled.
LEDPulse
LED pulse width (the IR and RED have the same pulse width)
Definition unit_MAX30100.hpp:55
@ Width200
200 us (ADC 13 bits)
@ Width1600
1600 us (ADC 16 bits)
@ Width400
400 us (ADC 14 bits)
@ Width800
800 us (ADC 15 bits)
constexpr uint8_t MAX_FIFO_DEPTH
FIFO depth.
Definition unit_MAX30100.hpp:85
Sampling
Sampling rate for pulse/conversion.
Definition unit_MAX30100.hpp:40
LED
LED current control.
Definition unit_MAX30100.hpp:66