M5Unit-ENV 1.2.1 git rev:ad1926a
Loading...
Searching...
No Matches
unit_SCD40.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_ENV_UNIT_SCD40_HPP
11#define M5_UNIT_ENV_UNIT_SCD40_HPP
12
13#include <M5UnitComponent.hpp>
14#include <m5_utility/container/circular_buffer.hpp>
15#include <limits> // NaN
16
17namespace m5 {
18namespace unit {
19
24namespace scd4x {
29enum class Mode : uint8_t {
30 Normal,
31 LowPower,
32};
33
38struct Data {
39 std::array<uint8_t, 9> raw{};
40 uint16_t co2() const;
42 inline float temperature() const
43 {
44 return celsius();
45 }
46 float celsius() const;
47 float fahrenheit() const;
48 float humidity() const;
49};
50
52// Max command duration(ms)
53// For SCD40/41
54constexpr uint16_t READ_MEASUREMENT_DURATION{1};
55constexpr uint16_t STOP_PERIODIC_MEASUREMENT_DURATION{500};
56constexpr uint16_t SET_TEMPERATURE_OFFSET_DURATION{1};
57constexpr uint16_t GET_TEMPERATURE_OFFSET_DURATION{1};
58constexpr uint16_t SET_SENSOR_ALTITUDE_DURATION{1};
59constexpr uint16_t GET_SENSOR_ALTITUDE_DURATION{1};
60constexpr uint16_t SET_AMBIENT_PRESSURE_DURATION{1};
61constexpr uint16_t GET_AMBIENT_PRESSURE_DURATION{1};
62constexpr uint16_t PERFORM_FORCED_CALIBRATION_DURATION{400};
63constexpr uint16_t SET_AUTOMATIC_SELF_CALIBRATION_ENABLED_DURATION{1};
64constexpr uint16_t GET_AUTOMATIC_SELF_CALIBRATION_ENABLED_DURATION{1};
65constexpr uint16_t SET_AUTOMATIC_SELF_CALIBRATION_TARGET_DURATION{1};
66constexpr uint16_t GET_AUTOMATIC_SELF_CALIBRATION_TARGET_DURATION{1};
67constexpr uint16_t GET_DATA_READY_STATUS_DURATION{1};
68constexpr uint16_t PERSIST_SETTINGS_DURATION{800};
69constexpr uint16_t GET_SERIAL_NUMBER_DURATION{1};
70constexpr uint16_t PERFORM_SELF_TEST_DURATION{10000};
71constexpr uint16_t PERFORM_FACTORY_RESET_DURATION{1200};
72constexpr uint16_t REINIT_DURATION{20};
74
75} // namespace scd4x
76
81class UnitSCD40 : public Component, public PeriodicMeasurementAdapter<UnitSCD40, scd4x::Data> {
82 M5_UNIT_COMPONENT_HPP_BUILDER(UnitSCD40, 0x62);
83
84public:
89 struct config_t {
91 bool start_periodic{true};
93 scd4x::Mode mode{scd4x::Mode::Normal};
95 bool calibration{true};
96 };
97
98 explicit UnitSCD40(const uint8_t addr = DEFAULT_ADDRESS)
99 : Component(addr), _data{new m5::container::CircularBuffer<scd4x::Data>(1)}
100 {
101 auto ccfg = component_config();
102 ccfg.clock = 400 * 1000U;
103 component_config(ccfg);
104 }
105 virtual ~UnitSCD40()
106 {
107 }
108
109 virtual bool begin() override;
110 virtual void update(const bool force = false) override;
111
114
115 inline config_t config() const
116 {
117 return _cfg;
118 }
120 inline void config(const config_t &cfg)
121 {
122 _cfg = cfg;
123 }
125
129 inline uint16_t co2() const
130 {
131 return !empty() ? oldest().co2() : 0;
132 }
134 inline float temperature() const
135 {
136 return !empty() ? oldest().temperature() : std::numeric_limits<float>::quiet_NaN();
137 }
139 inline float celsius() const
140 {
141 return !empty() ? oldest().celsius() : std::numeric_limits<float>::quiet_NaN();
142 }
144 inline float fahrenheit() const
145 {
146 return !empty() ? oldest().fahrenheit() : std::numeric_limits<float>::quiet_NaN();
147 }
149 inline float humidity() const
150 {
151 return !empty() ? oldest().humidity() : std::numeric_limits<float>::quiet_NaN();
152 }
154
157
162 inline bool startPeriodicMeasurement(const scd4x::Mode mode = scd4x::Mode::Normal)
163 {
164 return PeriodicMeasurementAdapter<UnitSCD40, scd4x::Data>::startPeriodicMeasurement(mode);
165 }
171 {
172 return startPeriodicMeasurement(scd4x::Mode::LowPower);
173 }
179 inline bool stopPeriodicMeasurement(const uint32_t duration = scd4x::STOP_PERIODIC_MEASUREMENT_DURATION)
180 {
181 return PeriodicMeasurementAdapter<UnitSCD40, scd4x::Data>::stopPeriodicMeasurement(duration);
182 }
184
187
197 bool writeTemperatureOffset(const float offset, const uint32_t duration = scd4x::SET_TEMPERATURE_OFFSET_DURATION);
204 bool readTemperatureOffset(float &offset);
214 bool writeSensorAltitude(const uint16_t altitude, const uint32_t duration = scd4x::SET_SENSOR_ALTITUDE_DURATION);
221 bool readSensorAltitude(uint16_t &altitude);
231 bool writeAmbientPressure(const uint16_t pressure, const uint32_t duration = scd4x::SET_AMBIENT_PRESSURE_DURATION);
237 bool readAmbientPressure(uint16_t &pressure);
239
242
250 bool performForcedRecalibration(const uint16_t concentration, int16_t &correction);
259 const bool enabled = true, const uint32_t duration = scd4x::SET_AUTOMATIC_SELF_CALIBRATION_ENABLED_DURATION);
266 bool readAutomaticSelfCalibrationEnabled(bool &enabled);
267
276 const uint16_t ppm, const uint32_t duration = scd4x::SET_AUTOMATIC_SELF_CALIBRATION_TARGET_DURATION);
283 bool readAutomaticSelfCalibrationTarget(uint16_t &ppm);
285
288
293 bool writePersistSettings(const uint32_t duration = scd4x::PERSIST_SETTINGS_DURATION);
301 bool readSerialNumber(char *serialNumber);
309 bool readSerialNumber(uint64_t &serialNumber);
317 bool performSelfTest(bool &malfunction);
325 bool performFactoryReset(const uint32_t duration = scd4x::PERFORM_FACTORY_RESET_DURATION);
332 bool reInit(const uint32_t duration = scd4x::REINIT_DURATION);
334
335protected:
336 bool read_register(const uint16_t reg, uint8_t *rbuf, const uint32_t rlen, const uint32_t duration = 1);
337 bool write_register(const uint16_t reg, uint8_t *wbuf, const uint32_t wlen);
338
339 bool start_periodic_measurement(const scd4x::Mode mode = scd4x::Mode::Normal);
340 bool stop_periodic_measurement(const uint32_t duration = scd4x::STOP_PERIODIC_MEASUREMENT_DURATION);
341 bool read_data_ready_status();
342 bool read_measurement(scd4x::Data &d, const bool all = true);
343
344 virtual bool is_valid_chip();
345 bool delay_true(const uint32_t duration);
346
347 M5_UNIT_COMPONENT_PERIODIC_MEASUREMENT_ADAPTER_HPP_BUILDER(UnitSCD40, scd4x::Data);
348
349protected:
350 std::unique_ptr<m5::container::CircularBuffer<scd4x::Data>> _data{};
351 config_t _cfg{};
352};
353
355namespace scd4x {
356namespace command {
357// Basic Commands
358constexpr uint16_t START_PERIODIC_MEASUREMENT{0x21b1};
359constexpr uint16_t READ_MEASUREMENT{0xec05};
360constexpr uint16_t STOP_PERIODIC_MEASUREMENT{0x3f86};
361// On-chip output signal compensation
362constexpr uint16_t SET_TEMPERATURE_OFFSET{0x241d};
363constexpr uint16_t GET_TEMPERATURE_OFFSET{0x2318};
364constexpr uint16_t SET_SENSOR_ALTITUDE{0x2427};
365constexpr uint16_t GET_SENSOR_ALTITUDE{0x2322};
366constexpr uint16_t AMBIENT_PRESSURE{0xe000};
367// Field calibration
368constexpr uint16_t PERFORM_FORCED_CALIBRATION{0x362f};
369constexpr uint16_t SET_AUTOMATIC_SELF_CALIBRATION_ENABLED{0x2416};
370constexpr uint16_t GET_AUTOMATIC_SELF_CALIBRATION_ENABLED{0x2313};
371constexpr uint16_t SET_AUTOMATIC_SELF_CALIBRATION_TARGET{0x243a};
372constexpr uint16_t GET_AUTOMATIC_SELF_CALIBRATION_TARGET{0x233f};
373// Low power
374constexpr uint16_t START_LOW_POWER_PERIODIC_MEASUREMENT{0x21ac};
375constexpr uint16_t GET_DATA_READY_STATUS{0xe4b8};
376// Advanced features
377constexpr uint16_t PERSIST_SETTINGS{0x3615};
378constexpr uint16_t GET_SERIAL_NUMBER{0x3682};
379constexpr uint16_t PERFORM_SELF_TEST{0x3639};
380constexpr uint16_t PERFORM_FACTORY_RESET{0x3632};
381constexpr uint16_t REINIT{0x3646};
382//
383constexpr uint16_t GET_SENSOR_VARIANT{0x202f};
384} // namespace command
385} // namespace scd4x
387
388} // namespace unit
389} // namespace m5
390#endif
SCD40 unit component.
float temperature() const
Oldest measured temperature (Celsius)
Definition unit_SCD40.hpp:134
bool performFactoryReset(const uint32_t duration=scd4x::PERFORM_FACTORY_RESET_DURATION)
Peform factory reset.
Definition unit_SCD40.cpp:434
float humidity() const
Oldest measured humidity (RH)
Definition unit_SCD40.hpp:149
bool startPeriodicMeasurement(const scd4x::Mode mode=scd4x::Mode::Normal)
Start periodic measurement.
Definition unit_SCD40.hpp:162
bool performSelfTest(bool &malfunction)
Perform self test.
Definition unit_SCD40.cpp:417
bool readSerialNumber(char *serialNumber)
Read the serial number string.
Definition unit_SCD40.cpp:377
bool writeTemperatureOffset(const float offset, const uint32_t duration=scd4x::SET_TEMPERATURE_OFFSET_DURATION)
Write the temperature offset.
Definition unit_SCD40.cpp:164
bool readAmbientPressure(uint16_t &pressure)
Read the ambient pressure.
Definition unit_SCD40.cpp:244
bool writeSensorAltitude(const uint16_t altitude, const uint32_t duration=scd4x::SET_SENSOR_ALTITUDE_DURATION)
Write the sensor altitude.
Definition unit_SCD40.cpp:198
bool readSensorAltitude(uint16_t &altitude)
Read the sensor altitude.
Definition unit_SCD40.cpp:209
bool readAutomaticSelfCalibrationTarget(uint16_t &ppm)
Read the value of the ASC baseline target.
Definition unit_SCD40.cpp:347
bool writeAutomaticSelfCalibrationEnabled(const bool enabled=true, const uint32_t duration=scd4x::SET_AUTOMATIC_SELF_CALIBRATION_ENABLED_DURATION)
Enable/disable automatic self calibration.
Definition unit_SCD40.cpp:311
float fahrenheit() const
Oldest measured temperature (Fahrenheit)
Definition unit_SCD40.hpp:144
bool reInit(const uint32_t duration=scd4x::REINIT_DURATION)
Re-initialize the sensor, load settings from EEPROM.
Definition unit_SCD40.cpp:447
config_t config() const
Gets the configration.
Definition unit_SCD40.hpp:115
bool writeAutomaticSelfCalibrationTarget(const uint16_t ppm, const uint32_t duration=scd4x::SET_AUTOMATIC_SELF_CALIBRATION_TARGET_DURATION)
Write the value of the ASC baseline target.
Definition unit_SCD40.cpp:337
float celsius() const
Oldest measured temperature (Celsius)
Definition unit_SCD40.hpp:139
bool startLowPowerPeriodicMeasurement()
Start low power periodic measurement.
Definition unit_SCD40.hpp:170
void config(const config_t &cfg)
Set the configration.
Definition unit_SCD40.hpp:120
bool stopPeriodicMeasurement(const uint32_t duration=scd4x::STOP_PERIODIC_MEASUREMENT_DURATION)
Stop periodic measurement.
Definition unit_SCD40.hpp:179
uint16_t co2() const
Oldest measured CO2 concentration (ppm)
Definition unit_SCD40.hpp:129
bool readAutomaticSelfCalibrationEnabled(bool &enabled)
Check if automatic self calibration is enabled.
Definition unit_SCD40.cpp:321
bool readTemperatureOffset(float &offset)
Read the temperature offset.
Definition unit_SCD40.cpp:182
bool writeAmbientPressure(const uint16_t pressure, const uint32_t duration=scd4x::SET_AMBIENT_PRESSURE_DURATION)
Write the ambient pressure.
Definition unit_SCD40.cpp:225
bool performForcedRecalibration(const uint16_t concentration, int16_t &correction)
Perform forced recalibration.
Definition unit_SCD40.cpp:261
bool writePersistSettings(const uint32_t duration=scd4x::PERSIST_SETTINGS_DURATION)
Write sensor settings from RAM to EEPROM.
Definition unit_SCD40.cpp:363
Top level namespace of M5stack.
For SCD40/41.
Unit-related namespace.
Settings for begin.
Definition unit_SCD40.hpp:89
bool calibration
Enable ASC on begin?
Definition unit_SCD40.hpp:95
bool start_periodic
Start periodic measurement on begin?
Definition unit_SCD40.hpp:91
scd4x::Mode mode
Mode of periodic measurement if start on begin?
Definition unit_SCD40.hpp:93
Measurement data group.
Definition unit_SCD40.hpp:38
float fahrenheit() const
temperature (Fahrenheit)
Definition unit_SCD40.cpp:61
float celsius() const
temperature (Celsius)
Definition unit_SCD40.cpp:56
float temperature() const
temperature (Celsius)
Definition unit_SCD40.hpp:42
uint16_t co2() const
CO2 concentration (ppm)
Definition unit_SCD40.cpp:51
float humidity() const
humidity (RH)
Definition unit_SCD40.cpp:66
std::array< uint8_t, 9 > raw
RAW data.
Definition unit_SCD40.hpp:39
Mode
Mode of periodic measurement.
Definition unit_SCD40.hpp:29