first commit
This commit is contained in:
commit
5893b00dd2
1669 changed files with 1982740 additions and 0 deletions
390
libraries/M5Unit-ENV/src/unit/unit_SCD40.hpp
Normal file
390
libraries/M5Unit-ENV/src/unit/unit_SCD40.hpp
Normal file
|
|
@ -0,0 +1,390 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
/*!
|
||||
@file unit_SCD40.hpp
|
||||
@brief SCD40 Unit for M5UnitUnified
|
||||
*/
|
||||
#ifndef M5_UNIT_ENV_UNIT_SCD40_HPP
|
||||
#define M5_UNIT_ENV_UNIT_SCD40_HPP
|
||||
|
||||
#include <M5UnitComponent.hpp>
|
||||
#include <m5_utility/container/circular_buffer.hpp>
|
||||
#include <limits> // NaN
|
||||
|
||||
namespace m5 {
|
||||
namespace unit {
|
||||
|
||||
/*!
|
||||
@namespace scd4x
|
||||
@brief For SCD40/41
|
||||
*/
|
||||
namespace scd4x {
|
||||
/*!
|
||||
@enum Mode
|
||||
@brief Mode of periodic measurement
|
||||
*/
|
||||
enum class Mode : uint8_t {
|
||||
Normal, //!< Normal (Receive data every 5 seconds)
|
||||
LowPower, //!< Low power (Receive data every 30 seconds)
|
||||
};
|
||||
|
||||
/*!
|
||||
@struct Data
|
||||
@brief Measurement data group
|
||||
*/
|
||||
struct Data {
|
||||
std::array<uint8_t, 9> raw{}; //!< @brief RAW data
|
||||
uint16_t co2() const; //!< @brief CO2 concentration (ppm)
|
||||
//! @brief temperature (Celsius)
|
||||
inline float temperature() const
|
||||
{
|
||||
return celsius();
|
||||
}
|
||||
float celsius() const; //!< @brief temperature (Celsius)
|
||||
float fahrenheit() const; //!< @brief temperature (Fahrenheit)
|
||||
float humidity() const; //!< @brief humidity (RH)
|
||||
};
|
||||
|
||||
///@cond
|
||||
// Max command duration(ms)
|
||||
// For SCD40/41
|
||||
constexpr uint16_t READ_MEASUREMENT_DURATION{1};
|
||||
constexpr uint16_t STOP_PERIODIC_MEASUREMENT_DURATION{500};
|
||||
constexpr uint16_t SET_TEMPERATURE_OFFSET_DURATION{1};
|
||||
constexpr uint16_t GET_TEMPERATURE_OFFSET_DURATION{1};
|
||||
constexpr uint16_t SET_SENSOR_ALTITUDE_DURATION{1};
|
||||
constexpr uint16_t GET_SENSOR_ALTITUDE_DURATION{1};
|
||||
constexpr uint16_t SET_AMBIENT_PRESSURE_DURATION{1};
|
||||
constexpr uint16_t GET_AMBIENT_PRESSURE_DURATION{1};
|
||||
constexpr uint16_t PERFORM_FORCED_CALIBRATION_DURATION{400};
|
||||
constexpr uint16_t SET_AUTOMATIC_SELF_CALIBRATION_ENABLED_DURATION{1};
|
||||
constexpr uint16_t GET_AUTOMATIC_SELF_CALIBRATION_ENABLED_DURATION{1};
|
||||
constexpr uint16_t SET_AUTOMATIC_SELF_CALIBRATION_TARGET_DURATION{1};
|
||||
constexpr uint16_t GET_AUTOMATIC_SELF_CALIBRATION_TARGET_DURATION{1};
|
||||
constexpr uint16_t GET_DATA_READY_STATUS_DURATION{1};
|
||||
constexpr uint16_t PERSIST_SETTINGS_DURATION{800};
|
||||
constexpr uint16_t GET_SERIAL_NUMBER_DURATION{1};
|
||||
constexpr uint16_t PERFORM_SELF_TEST_DURATION{10000};
|
||||
constexpr uint16_t PERFORM_FACTORY_RESET_DURATION{1200};
|
||||
constexpr uint16_t REINIT_DURATION{20};
|
||||
/// @endcond
|
||||
|
||||
} // namespace scd4x
|
||||
|
||||
/*!
|
||||
@class m5::unit::UnitSCD40
|
||||
@brief SCD40 unit component
|
||||
*/
|
||||
class UnitSCD40 : public Component, public PeriodicMeasurementAdapter<UnitSCD40, scd4x::Data> {
|
||||
M5_UNIT_COMPONENT_HPP_BUILDER(UnitSCD40, 0x62);
|
||||
|
||||
public:
|
||||
/*!
|
||||
@struct config_t
|
||||
@brief Settings for begin
|
||||
*/
|
||||
struct config_t {
|
||||
//! Start periodic measurement on begin?
|
||||
bool start_periodic{true};
|
||||
//! Mode of periodic measurement if start on begin?
|
||||
scd4x::Mode mode{scd4x::Mode::Normal};
|
||||
//! Enable ASC on begin?
|
||||
bool calibration{true};
|
||||
};
|
||||
|
||||
explicit UnitSCD40(const uint8_t addr = DEFAULT_ADDRESS)
|
||||
: Component(addr), _data{new m5::container::CircularBuffer<scd4x::Data>(1)}
|
||||
{
|
||||
auto ccfg = component_config();
|
||||
ccfg.clock = 400 * 1000U;
|
||||
component_config(ccfg);
|
||||
}
|
||||
virtual ~UnitSCD40()
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool begin() override;
|
||||
virtual void update(const bool force = false) override;
|
||||
|
||||
///@name Settings for begin
|
||||
///@{
|
||||
/*! @brief Gets the configration */
|
||||
inline config_t config() const
|
||||
{
|
||||
return _cfg;
|
||||
}
|
||||
//! @brief Set the configration
|
||||
inline void config(const config_t &cfg)
|
||||
{
|
||||
_cfg = cfg;
|
||||
}
|
||||
///@}
|
||||
|
||||
///@name Measurement data by periodic
|
||||
///@{
|
||||
//! @brief Oldest measured CO2 concentration (ppm)
|
||||
inline uint16_t co2() const
|
||||
{
|
||||
return !empty() ? oldest().co2() : 0;
|
||||
}
|
||||
//! @brief Oldest measured temperature (Celsius)
|
||||
inline float temperature() const
|
||||
{
|
||||
return !empty() ? oldest().temperature() : std::numeric_limits<float>::quiet_NaN();
|
||||
}
|
||||
//! @brief Oldest measured temperature (Celsius)
|
||||
inline float celsius() const
|
||||
{
|
||||
return !empty() ? oldest().celsius() : std::numeric_limits<float>::quiet_NaN();
|
||||
}
|
||||
//! @brief Oldest measured temperature (Fahrenheit)
|
||||
inline float fahrenheit() const
|
||||
{
|
||||
return !empty() ? oldest().fahrenheit() : std::numeric_limits<float>::quiet_NaN();
|
||||
}
|
||||
//! @brief Oldest measured humidity (RH)
|
||||
inline float humidity() const
|
||||
{
|
||||
return !empty() ? oldest().humidity() : std::numeric_limits<float>::quiet_NaN();
|
||||
}
|
||||
///@}
|
||||
|
||||
///@name Periodic measurement
|
||||
///@{
|
||||
/*!
|
||||
@brief Start periodic measurement
|
||||
@param mode Measurement mode
|
||||
@return True if successful
|
||||
*/
|
||||
inline bool startPeriodicMeasurement(const scd4x::Mode mode = scd4x::Mode::Normal)
|
||||
{
|
||||
return PeriodicMeasurementAdapter<UnitSCD40, scd4x::Data>::startPeriodicMeasurement(mode);
|
||||
}
|
||||
/*!
|
||||
@brief Start low power periodic measurement
|
||||
@return True if successful
|
||||
*/
|
||||
inline bool startLowPowerPeriodicMeasurement()
|
||||
{
|
||||
return startPeriodicMeasurement(scd4x::Mode::LowPower);
|
||||
}
|
||||
/*!
|
||||
@brief Stop periodic measurement
|
||||
@param duration Max command duration(ms)
|
||||
@return True if successful
|
||||
*/
|
||||
inline bool stopPeriodicMeasurement(const uint32_t duration = scd4x::STOP_PERIODIC_MEASUREMENT_DURATION)
|
||||
{
|
||||
return PeriodicMeasurementAdapter<UnitSCD40, scd4x::Data>::stopPeriodicMeasurement(duration);
|
||||
}
|
||||
///@}
|
||||
|
||||
///@name On-Chip Output Signal Compensation
|
||||
///@{
|
||||
/*!
|
||||
@brief Write the temperature offset
|
||||
@details Define how warm the sensor is compared to ambient, so RH and T
|
||||
are temperature compensated. Has no effect on the CO2 reading Default offsetis 4C
|
||||
@param offset (0 <= offset < 175)
|
||||
@param duration Max command duration(ms)
|
||||
@return True if successful
|
||||
@note Recommended temperature offset values are between 0 and 20
|
||||
@warning During periodic detection runs, an error is returned
|
||||
*/
|
||||
bool writeTemperatureOffset(const float offset, const uint32_t duration = scd4x::SET_TEMPERATURE_OFFSET_DURATION);
|
||||
/*!
|
||||
@brief Read the temperature offset
|
||||
@param[out] offset Offset value
|
||||
@return True if successful
|
||||
@warning During periodic detection runs, an error is returned
|
||||
*/
|
||||
bool readTemperatureOffset(float &offset);
|
||||
/*!
|
||||
@brief Write the sensor altitude
|
||||
@details Define the sensor altitude in metres above sea level, so RH and CO2 arecompensated for atmospheric
|
||||
pressure Default altitude is 0m
|
||||
@param altitude Sensor altitude [m]
|
||||
@param duration Max command duration(ms)
|
||||
@return True if successful
|
||||
@warning During periodic detection runs, an error is returned
|
||||
*/
|
||||
bool writeSensorAltitude(const uint16_t altitude, const uint32_t duration = scd4x::SET_SENSOR_ALTITUDE_DURATION);
|
||||
/*!
|
||||
@brief Read the sensor altitude
|
||||
@param[out] altitude Sensor altitude [m]
|
||||
@return True if successful
|
||||
@warning During periodic detection runs, an error is returned
|
||||
*/
|
||||
bool readSensorAltitude(uint16_t &altitude);
|
||||
/*!
|
||||
@brief Write the ambient pressure
|
||||
@details Define the ambient pressure in Pascals, so RH and CO2 are compensated for atmospheric pressure
|
||||
setAmbientPressure overrides setSensorAltitude
|
||||
@param pressure Ambient pressure [hPa]
|
||||
@param duration Max command duration(ms)
|
||||
@return True if successful
|
||||
@warning Valid Valid input values are between 700 – 1200 hPa
|
||||
*/
|
||||
bool writeAmbientPressure(const uint16_t pressure, const uint32_t duration = scd4x::SET_AMBIENT_PRESSURE_DURATION);
|
||||
/*!
|
||||
@brief Read the ambient pressure
|
||||
@param[out] presure Ambient pressure [hPa]
|
||||
@return True if successful
|
||||
*/
|
||||
bool readAmbientPressure(uint16_t &pressure);
|
||||
///@}
|
||||
|
||||
///@name Field Calibration
|
||||
///@{
|
||||
/*!
|
||||
@brief Perform forced recalibration
|
||||
@param concentration Unit:ppm
|
||||
@param[out] correction The FRC correction value
|
||||
@return True if successful
|
||||
@warning During periodic detection runs, an error is returned
|
||||
@warning Blocked until the process is completed (about 400ms)
|
||||
*/
|
||||
bool performForcedRecalibration(const uint16_t concentration, int16_t &correction);
|
||||
/*!
|
||||
@brief Enable/disable automatic self calibration
|
||||
@param enabled Enable automatic self calibration if true
|
||||
@param duration Max command duration(ms)
|
||||
@return True if successful
|
||||
@warning During periodic detection runs, an error is returned
|
||||
*/
|
||||
bool writeAutomaticSelfCalibrationEnabled(
|
||||
const bool enabled = true, const uint32_t duration = scd4x::SET_AUTOMATIC_SELF_CALIBRATION_ENABLED_DURATION);
|
||||
/*!
|
||||
@brief Check if automatic self calibration is enabled
|
||||
@param[out] enabled True if automatic self calibration is enabled
|
||||
@return True if successful
|
||||
@warning During periodic detection runs, an error is returned
|
||||
*/
|
||||
bool readAutomaticSelfCalibrationEnabled(bool &enabled);
|
||||
|
||||
/*!
|
||||
@brief Write the value of the ASC baseline target
|
||||
@param ppm ASC target ppm
|
||||
@param duration Max command duration(ms)
|
||||
@return True if successful
|
||||
@warning During periodic detection runs, an error is returned
|
||||
*/
|
||||
bool writeAutomaticSelfCalibrationTarget(
|
||||
const uint16_t ppm, const uint32_t duration = scd4x::SET_AUTOMATIC_SELF_CALIBRATION_TARGET_DURATION);
|
||||
/*!
|
||||
@brief Read the value of the ASC baseline target
|
||||
@param[out] ppm ASC target ppm
|
||||
@return True if successful
|
||||
@warning During periodic detection runs, an error is returned
|
||||
*/
|
||||
bool readAutomaticSelfCalibrationTarget(uint16_t &ppm);
|
||||
///@}
|
||||
|
||||
///@name Advanced Features
|
||||
///@{
|
||||
/*!
|
||||
@brief Write sensor settings from RAM to EEPROM
|
||||
@return True if successful
|
||||
@warning During periodic detection runs, an error is returned
|
||||
*/
|
||||
bool writePersistSettings(const uint32_t duration = scd4x::PERSIST_SETTINGS_DURATION);
|
||||
/*!
|
||||
@brief Read the serial number string
|
||||
@param[out] serialNumber Output buffer
|
||||
@return True if successful
|
||||
@warning Size must be at least 13 bytes
|
||||
@warning During periodic detection runs, an error is returned
|
||||
*/
|
||||
bool readSerialNumber(char *serialNumber);
|
||||
/*!
|
||||
@brief Read the serial number value
|
||||
@param[out] serialNumber serial number value
|
||||
@return True if successful
|
||||
@note The serial number is 48 bit
|
||||
@warning During periodic detection runs, an error is returned
|
||||
*/
|
||||
bool readSerialNumber(uint64_t &serialNumber);
|
||||
/*!
|
||||
@brief Perform self test
|
||||
@param[out] True if malfunction detected
|
||||
@return True if successful
|
||||
@note Takes 10 seconds to complete
|
||||
@warning During periodic detection runs, an error is returned
|
||||
*/
|
||||
bool performSelfTest(bool &malfunction);
|
||||
/*!
|
||||
@brief Peform factory reset
|
||||
@details Reset all settings to the factory values
|
||||
@return True if successful
|
||||
@warning During periodic detection runs, an error is returned
|
||||
@warning Measurement duration max 1200 ms
|
||||
*/
|
||||
bool performFactoryReset(const uint32_t duration = scd4x::PERFORM_FACTORY_RESET_DURATION);
|
||||
/*!
|
||||
@brief Re-initialize the sensor, load settings from EEPROM
|
||||
@return True if successful
|
||||
@warning During periodic detection runs, an error is returned
|
||||
@warning Measurement duration max 20 ms
|
||||
*/
|
||||
bool reInit(const uint32_t duration = scd4x::REINIT_DURATION);
|
||||
///@}
|
||||
|
||||
protected:
|
||||
bool read_register(const uint16_t reg, uint8_t *rbuf, const uint32_t rlen, const uint32_t duration = 1);
|
||||
bool write_register(const uint16_t reg, uint8_t *wbuf, const uint32_t wlen);
|
||||
|
||||
bool start_periodic_measurement(const scd4x::Mode mode = scd4x::Mode::Normal);
|
||||
bool stop_periodic_measurement(const uint32_t duration = scd4x::STOP_PERIODIC_MEASUREMENT_DURATION);
|
||||
bool read_data_ready_status();
|
||||
bool read_measurement(scd4x::Data &d, const bool all = true);
|
||||
|
||||
virtual bool is_valid_chip();
|
||||
bool delay_true(const uint32_t duration);
|
||||
|
||||
M5_UNIT_COMPONENT_PERIODIC_MEASUREMENT_ADAPTER_HPP_BUILDER(UnitSCD40, scd4x::Data);
|
||||
|
||||
protected:
|
||||
std::unique_ptr<m5::container::CircularBuffer<scd4x::Data>> _data{};
|
||||
config_t _cfg{};
|
||||
};
|
||||
|
||||
///@cond
|
||||
namespace scd4x {
|
||||
namespace command {
|
||||
// Basic Commands
|
||||
constexpr uint16_t START_PERIODIC_MEASUREMENT{0x21b1};
|
||||
constexpr uint16_t READ_MEASUREMENT{0xec05};
|
||||
constexpr uint16_t STOP_PERIODIC_MEASUREMENT{0x3f86};
|
||||
// On-chip output signal compensation
|
||||
constexpr uint16_t SET_TEMPERATURE_OFFSET{0x241d};
|
||||
constexpr uint16_t GET_TEMPERATURE_OFFSET{0x2318};
|
||||
constexpr uint16_t SET_SENSOR_ALTITUDE{0x2427};
|
||||
constexpr uint16_t GET_SENSOR_ALTITUDE{0x2322};
|
||||
constexpr uint16_t AMBIENT_PRESSURE{0xe000};
|
||||
// Field calibration
|
||||
constexpr uint16_t PERFORM_FORCED_CALIBRATION{0x362f};
|
||||
constexpr uint16_t SET_AUTOMATIC_SELF_CALIBRATION_ENABLED{0x2416};
|
||||
constexpr uint16_t GET_AUTOMATIC_SELF_CALIBRATION_ENABLED{0x2313};
|
||||
constexpr uint16_t SET_AUTOMATIC_SELF_CALIBRATION_TARGET{0x243a};
|
||||
constexpr uint16_t GET_AUTOMATIC_SELF_CALIBRATION_TARGET{0x233f};
|
||||
// Low power
|
||||
constexpr uint16_t START_LOW_POWER_PERIODIC_MEASUREMENT{0x21ac};
|
||||
constexpr uint16_t GET_DATA_READY_STATUS{0xe4b8};
|
||||
// Advanced features
|
||||
constexpr uint16_t PERSIST_SETTINGS{0x3615};
|
||||
constexpr uint16_t GET_SERIAL_NUMBER{0x3682};
|
||||
constexpr uint16_t PERFORM_SELF_TEST{0x3639};
|
||||
constexpr uint16_t PERFORM_FACTORY_RESET{0x3632};
|
||||
constexpr uint16_t REINIT{0x3646};
|
||||
//
|
||||
constexpr uint16_t GET_SENSOR_VARIANT{0x202f};
|
||||
} // namespace command
|
||||
} // namespace scd4x
|
||||
///@endcond
|
||||
|
||||
} // namespace unit
|
||||
} // namespace m5
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue