13#ifndef M5_UNIT_ENV_UNIT_SPA06_DATA_HPP
14#define M5_UNIT_ENV_UNIT_SPA06_DATA_HPP
68 switch (oversampling) {
69 case Oversampling::X1:
71 case Oversampling::X2:
73 case Oversampling::X4:
75 case Oversampling::X8:
77 case Oversampling::X16:
79 case Oversampling::X32:
81 case Oversampling::X64:
83 case Oversampling::X128:
86 return std::numeric_limits<float>::quiet_NaN();
92 constexpr uint32_t t[] = {36, 52, 84, 148, 276, 532, 1044, 2068};
93 return t[
static_cast<uint8_t
>(oversampling)];
104 const uint32_t r =
static_cast<uint32_t
>(1) <<
static_cast<uint8_t
>(rate);
105 uint32_t budget_x10{};
110 case Mode::Temperature:
113 case Mode::PressureAndTemperature:
117 return r * budget_x10 < 10000u;
126 const uint32_t m =
static_cast<uint32_t
>(1) << (bits - 1);
127 return static_cast<int32_t
>((v ^ m) - m);
133 int32_t c00{}, c10{};
134 int32_t c01{}, c11{}, c20{}, c21{}, c30{};
135 int32_t c31{}, c40{};
142 c.c0 =
sign_extend((
static_cast<uint32_t
>(r[0]) << 4) | (r[1] >> 4), 12);
143 c.c1 =
sign_extend(((
static_cast<uint32_t
>(r[1]) & 0x0F) << 8) | r[2], 12);
144 c.c00 =
sign_extend((
static_cast<uint32_t
>(r[3]) << 12) | (
static_cast<uint32_t
>(r[4]) << 4) | (r[5] >> 4), 20);
145 c.c10 =
sign_extend(((
static_cast<uint32_t
>(r[5]) & 0x0F) << 16) | (
static_cast<uint32_t
>(r[6]) << 8) | r[7], 20);
146 c.c01 =
sign_extend((
static_cast<uint32_t
>(r[8]) << 8) | r[9], 16);
147 c.c11 =
sign_extend((
static_cast<uint32_t
>(r[10]) << 8) | r[11], 16);
148 c.c20 =
sign_extend((
static_cast<uint32_t
>(r[12]) << 8) | r[13], 16);
149 c.c21 =
sign_extend((
static_cast<uint32_t
>(r[14]) << 8) | r[15], 16);
150 c.c30 =
sign_extend((
static_cast<uint32_t
>(r[16]) << 8) | r[17], 16);
151 c.c31 =
sign_extend((
static_cast<uint32_t
>(r[18]) << 4) | (r[19] >> 4), 12);
152 c.c40 =
sign_extend(((
static_cast<uint32_t
>(r[19]) & 0x0F) << 8) | r[20], 12);
159 const float traw_sc = tmp_raw / kt;
160 return c.c0 * 0.5f + c.c1 * traw_sc;
167 const float praw_sc = psr_raw / kp;
168 const float traw_sc = tmp_raw / kt;
169 return c.c00 + praw_sc * (c.c10 + praw_sc * (c.c20 + praw_sc * (c.c30 + praw_sc * c.c40))) + traw_sc * c.c01 +
170 traw_sc * praw_sc * (c.c11 + praw_sc * (c.c21 + praw_sc * c.c31));
174inline float altitude_m(
const float pressure_hpa,
const float sea_level_hpa)
176 return 44330.0f * (1.0f - std::pow(pressure_hpa / sea_level_hpa, 1.0f / 5.255f));
184 std::array<uint8_t, 6>
raw{};
196 return sign_extend((
static_cast<uint32_t
>(
raw[0]) << 16) | (
static_cast<uint32_t
>(
raw[1]) << 8) |
raw[2], 24);
201 return sign_extend((
static_cast<uint32_t
>(
raw[3]) << 16) | (
static_cast<uint32_t
>(
raw[4]) << 8) |
raw[5], 24);
207 : std::numeric_limits<float>::quiet_NaN();
217 return celsius() * 9.0f / 5.0f + 32.0f;
224 : std::numeric_limits<float>::quiet_NaN();
Top level namespace of M5Stack.
One SPA06 sample: a 6-byte burst from PSR_B2 (0x00) = PSR(24) + TMP(24), big-endian.
Definition unit_SPA06_data.hpp:183
coeffs_t coeffs
Calibration coefficients for compensation.
Definition unit_SPA06_data.hpp:189
float kt
Temperature scale factor kT at measurement time (0 = not populated)
Definition unit_SPA06_data.hpp:191
int32_t psr_raw() const
Raw pressure (24-bit 2's complement)
Definition unit_SPA06_data.hpp:194
std::array< uint8_t, 6 > raw
PSR B2/B1/B0 + TMP B2/B1/B0.
Definition unit_SPA06_data.hpp:184
float pressure() const
Compensated pressure (hPa); NaN if not populated/measured.
Definition unit_SPA06_data.hpp:220
float fahrenheit() const
Compensated temperature (Fahrenheit)
Definition unit_SPA06_data.hpp:215
int32_t tmp_raw() const
Raw temperature (24-bit 2's complement)
Definition unit_SPA06_data.hpp:199
float celsius() const
Compensated temperature (Celsius)
Definition unit_SPA06_data.hpp:210
float temperature() const
Compensated temperature (Celsius); NaN if not populated/measured.
Definition unit_SPA06_data.hpp:204
float kp
Pressure scale factor kP at measurement time (0 = not populated)
Definition unit_SPA06_data.hpp:190
Factory calibration coefficients (all 2's complement, already sign-extended)
Definition unit_SPA06_data.hpp:131
Oversampling
Oversampling factor; the enum value is the PM_PRC/TM_PRC nibble (datasheet Table 4)
Definition unit_SPA06_data.hpp:29
@ X128
x128 (highest precision)
float altitude_m(const float pressure_hpa, const float sea_level_hpa)
Relative altitude (m) from a pressure and a reference (both hPa), barometric formula.
Definition unit_SPA06_data.hpp:174
Rate
Measurement rate; the enum value is the PM_RATE/TMP_RATE nibble (measurements per second)
Definition unit_SPA06_data.hpp:44
@ Rate16
16 measurements/s
@ Rate64
64 measurements/s
@ Rate32
32 measurements/s
@ Rate128
128 measurements/s
float compensate_pressure(const int32_t psr_raw, const int32_t tmp_raw, const coeffs_t &c, const float kp, const float kt)
Compensated pressure (Pa) from raw PSR/TMP readings and scales kP/kT (datasheet 4....
Definition unit_SPA06_data.hpp:164
float scale_factor(const Oversampling oversampling)
Compensation scale factor kP/kT for an oversampling rate (datasheet Table 4)
Definition unit_SPA06_data.hpp:66
float compensate_temperature(const int32_t tmp_raw, const coeffs_t &c, const float kt)
Compensated temperature (degC) from a raw TMP reading and scale kT.
Definition unit_SPA06_data.hpp:157
uint32_t measurement_time_x10(const Oversampling oversampling)
Measurement time (ms x10) for an oversampling rate (datasheet Table 8), indexed by nibble.
Definition unit_SPA06_data.hpp:90
Mode
Continuous measurement type; the enum value is the MEAS_CFG MEAS_CTRL[2:0] background-mode code.
Definition unit_SPA06_data.hpp:59
@ Pressure
Continuous pressure only (temperature() returns NaN)
@ PressureAndTemperature
Continuous pressure and temperature (both valid)
coeffs_t parse_coeffs(const std::array< uint8_t, 21 > &r)
Parse the 21 COEF register bytes (0x10..0x24) into coeffs_t (datasheet Table 10)
Definition unit_SPA06_data.hpp:139
int32_t sign_extend(const uint32_t v, const uint8_t bits)
Sign-extend the low bits of v (2's complement)
Definition unit_SPA06_data.hpp:124
constexpr int32_t NOT_MEASURED
Sentinel value of psr_raw()/tmp_raw() for a register not measured yet (reset value 0x800000)
Definition unit_SPA06_data.hpp:121
bool valid_combination(const Oversampling osrs_p, const Oversampling osrs_t, const Rate rate, const Mode mode)
True if a rate/oversampling/mode combination fits the datasheet timing budget.
Definition unit_SPA06_data.hpp:102