/* * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD * * SPDX-License-Identifier: MIT */ /* UnitTest for UnitBME688 */ #include #include #include #include #include #include #include #include #include #include using namespace m5::unit::googletest; using namespace m5::unit; using namespace m5::unit::bme688; #if defined(UNIT_BME688_USING_BSEC2) using namespace m5::unit::bme688::bsec2; #endif const ::testing::Environment* global_fixture = ::testing::AddGlobalTestEnvironment(new GlobalFixture<400000U>()); class TestBME688 : public ComponentTestBase { protected: virtual UnitBME688* get_instance() override { auto ptr = new m5::unit::UnitBME688(); auto ccfg = ptr->component_config(); ccfg.stored_size = 8; ptr->component_config(ccfg); return ptr; } virtual bool is_using_hal() const override { return GetParam(); }; }; // INSTANTIATE_TEST_SUITE_P(ParamValues, TestBME688, // ::testing::Values(false, true)); // INSTANTIATE_TEST_SUITE_P(ParamValues, TestBME688, ::testing::Values(true)); INSTANTIATE_TEST_SUITE_P(ParamValues, TestBME688, ::testing::Values(false)); namespace { constexpr Oversampling os_table[] = { Oversampling::None, Oversampling::x1, Oversampling::x1, Oversampling::x2, Oversampling::x4, Oversampling::x8, Oversampling::x16, }; constexpr Filter filter_table[] = { Filter::None, Filter::Coeff_1, Filter::Coeff_3, Filter::Coeff_7, Filter::Coeff_15, Filter::Coeff_31, Filter::Coeff_63, Filter::Coeff_127, }; #if defined(UNIT_BME688_USING_BSEC2) // All outputs constexpr bsec_virtual_sensor_t vs_table[] = { BSEC_OUTPUT_IAQ, BSEC_OUTPUT_STATIC_IAQ, BSEC_OUTPUT_CO2_EQUIVALENT, BSEC_OUTPUT_BREATH_VOC_EQUIVALENT, BSEC_OUTPUT_RAW_TEMPERATURE, BSEC_OUTPUT_RAW_PRESSURE, BSEC_OUTPUT_RAW_HUMIDITY, BSEC_OUTPUT_RAW_GAS, BSEC_OUTPUT_STABILIZATION_STATUS, BSEC_OUTPUT_RUN_IN_STATUS, BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE, BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY, BSEC_OUTPUT_GAS_PERCENTAGE, BSEC_OUTPUT_GAS_ESTIMATE_1, BSEC_OUTPUT_GAS_ESTIMATE_2, BSEC_OUTPUT_GAS_ESTIMATE_3, BSEC_OUTPUT_GAS_ESTIMATE_4, BSEC_OUTPUT_RAW_GAS_INDEX, BSEC_OUTPUT_REGRESSION_ESTIMATE_1, BSEC_OUTPUT_REGRESSION_ESTIMATE_2, BSEC_OUTPUT_REGRESSION_ESTIMATE_3, BSEC_OUTPUT_REGRESSION_ESTIMATE_4, }; // Using BSEC2 library configuration files constexpr uint8_t bsec_config[] = { #include }; #endif auto rng = std::default_random_engine{}; void check_measurement_values(UnitBME688* u) { auto latest = u->latest(); // for raw EXPECT_TRUE(std::isfinite(latest.raw_temperature())); EXPECT_TRUE(std::isfinite(latest.raw_pressure())); EXPECT_TRUE(std::isfinite(latest.raw_humidity())); EXPECT_TRUE(std::isfinite(latest.raw_gas())); // M5_LOGI("%f/%f/%f/%f", latest.raw_temperature(), latest.raw_pressure(), latest.raw_humidity(), latest.raw_gas()); } } // namespace TEST_P(TestBME688, Misc) { #if defined(UNIT_BME688_USING_BSEC2) for (auto&& v : vs_table) { EXPECT_EQ(subscribe_to_bits(v), 1U << v); } auto bits = subscribe_to_bits( BSEC_OUTPUT_IAQ, BSEC_OUTPUT_STATIC_IAQ, BSEC_OUTPUT_CO2_EQUIVALENT, BSEC_OUTPUT_BREATH_VOC_EQUIVALENT, BSEC_OUTPUT_RAW_TEMPERATURE, BSEC_OUTPUT_RAW_PRESSURE, BSEC_OUTPUT_RAW_HUMIDITY, BSEC_OUTPUT_RAW_GAS, BSEC_OUTPUT_STABILIZATION_STATUS, BSEC_OUTPUT_RUN_IN_STATUS, BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE, BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY, BSEC_OUTPUT_GAS_PERCENTAGE, BSEC_OUTPUT_GAS_ESTIMATE_1, BSEC_OUTPUT_GAS_ESTIMATE_2, BSEC_OUTPUT_GAS_ESTIMATE_3, BSEC_OUTPUT_GAS_ESTIMATE_4, BSEC_OUTPUT_RAW_GAS_INDEX, BSEC_OUTPUT_REGRESSION_ESTIMATE_1, BSEC_OUTPUT_REGRESSION_ESTIMATE_2, BSEC_OUTPUT_REGRESSION_ESTIMATE_3, BSEC_OUTPUT_REGRESSION_ESTIMATE_4); constexpr uint32_t val{ 1U << BSEC_OUTPUT_IAQ | 1U << BSEC_OUTPUT_STATIC_IAQ | 1U << BSEC_OUTPUT_CO2_EQUIVALENT | 1U << BSEC_OUTPUT_BREATH_VOC_EQUIVALENT | 1U << BSEC_OUTPUT_RAW_TEMPERATURE | 1U << BSEC_OUTPUT_RAW_PRESSURE | 1U << BSEC_OUTPUT_RAW_HUMIDITY | 1U << BSEC_OUTPUT_RAW_GAS | 1U << BSEC_OUTPUT_STABILIZATION_STATUS | 1U << BSEC_OUTPUT_RUN_IN_STATUS | 1U << BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE | 1U << BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY | 1U << BSEC_OUTPUT_GAS_PERCENTAGE | 1U << BSEC_OUTPUT_GAS_ESTIMATE_1 | 1U << BSEC_OUTPUT_GAS_ESTIMATE_2 | 1U << BSEC_OUTPUT_GAS_ESTIMATE_3 | 1U << BSEC_OUTPUT_GAS_ESTIMATE_4 | 1U << BSEC_OUTPUT_RAW_GAS_INDEX | 1U << BSEC_OUTPUT_REGRESSION_ESTIMATE_1 | 1U << BSEC_OUTPUT_REGRESSION_ESTIMATE_2 | 1U << BSEC_OUTPUT_REGRESSION_ESTIMATE_3 | 1U << BSEC_OUTPUT_REGRESSION_ESTIMATE_4}; EXPECT_EQ(bits, val); #endif } TEST_P(TestBME688, Settings) { SCOPED_TRACE(ustr); Oversampling os{}; Filter f{}; uint32_t serial{}; EXPECT_TRUE(unit->readUniqueID(serial)); EXPECT_NE(serial, 0U); // TPH for (auto&& e : os_table) { EXPECT_TRUE(unit->writeOversamplingTemperature(e)); EXPECT_EQ(unit->tphSetting().os_temp, m5::stl::to_underlying(e)); EXPECT_TRUE(unit->readOversamplingTemperature(os)); EXPECT_EQ(os, e); } for (auto&& e : os_table) { EXPECT_TRUE(unit->writeOversamplingPressure(e)); EXPECT_EQ(unit->tphSetting().os_pres, m5::stl::to_underlying(e)); EXPECT_TRUE(unit->readOversamplingPressure(os)); EXPECT_EQ(os, e); } for (auto&& e : os_table) { EXPECT_TRUE(unit->writeOversamplingHumidity(e)); EXPECT_EQ(unit->tphSetting().os_hum, m5::stl::to_underlying(e)); EXPECT_TRUE(unit->readOversamplingHumidity(os)); EXPECT_EQ(os, e); } for (auto&& e : filter_table) { EXPECT_TRUE(unit->writeIIRFilter(e)); EXPECT_EQ(unit->tphSetting().filter, m5::stl::to_underlying(e)); EXPECT_TRUE(unit->readIIRFilter(f)); EXPECT_EQ(f, e); } uint32_t cnt{10}; while (cnt--) { bme68xConf tph = unit->tphSetting(); tph.os_temp = rng() % 0x06; tph.os_pres = rng() % 0x06; tph.os_hum = rng() % 0x06; tph.filter = rng() % 0x07; // M5_LOGW("%u/%u/%u/%u", tph.os_temp, tph.os_pres, tph.os_hum, // tph.filter); EXPECT_TRUE(unit->writeTPHSetting(tph)); EXPECT_EQ(unit->tphSetting().os_temp, tph.os_temp); EXPECT_EQ(unit->tphSetting().os_pres, tph.os_pres); EXPECT_EQ(unit->tphSetting().os_hum, tph.os_hum); bme68xConf after{}; EXPECT_TRUE(unit->readTPHSetting(after)); EXPECT_TRUE(memcmp(&tph, &after, sizeof(tph)) == 0) << tph.os_temp << "/" << tph.os_pres << "/" << tph.os_hum << "/" << tph.filter; EXPECT_TRUE( unit->writeOversampling((Oversampling)tph.os_temp, (Oversampling)tph.os_pres, (Oversampling)tph.os_hum)); EXPECT_EQ(unit->tphSetting().os_temp, tph.os_temp); EXPECT_EQ(unit->tphSetting().os_pres, tph.os_pres); EXPECT_EQ(unit->tphSetting().os_hum, tph.os_hum); EXPECT_TRUE(unit->readTPHSetting(after)); EXPECT_TRUE(memcmp(&tph, &after, sizeof(tph)) == 0) << tph.os_temp << "/" << tph.os_pres << "/" << tph.os_hum << "/" << tph.filter; } // Calibration bme68xCalibration c0{}, c1{}; EXPECT_TRUE(unit->readCalibration(c0)); EXPECT_TRUE(unit->writeCalibration(c0)); EXPECT_TRUE(unit->readCalibration(c1)); EXPECT_TRUE(memcmp(&c0, &c1, sizeof(c1)) == 0); // softReset rewinds settings EXPECT_TRUE(unit->softReset()); // EXPECT_TRUE(unit->readOversamplingTemperature(os)); EXPECT_EQ(os, Oversampling::None); EXPECT_TRUE(unit->readOversamplingPressure(os)); EXPECT_EQ(os, Oversampling::None); EXPECT_TRUE(unit->readOversamplingHumidity(os)); EXPECT_EQ(os, Oversampling::None); EXPECT_TRUE(unit->readIIRFilter(f)); EXPECT_EQ(f, Filter::None); } #if defined(UNIT_BME688_USING_BSEC2) TEST_P(TestBME688, BSEC2) { SCOPED_TRACE(ustr); EXPECT_TRUE(unit->inPeriodic()); EXPECT_TRUE(unit->stopPeriodicMeasurement()); EXPECT_FALSE(unit->inPeriodic()); uint8_t cfg[BSEC_MAX_PROPERTY_BLOB_SIZE]{}; uint8_t state[BSEC_MAX_STATE_BLOB_SIZE]{}; uint8_t state2[BSEC_MAX_STATE_BLOB_SIZE]{}; uint32_t actual{}; EXPECT_TRUE(unit->bsec2GetState(state, actual)); // get current // Version auto& ver = unit->bsec2Version(); EXPECT_NE(ver.major, 0); EXPECT_NE(ver.minor, 0); // M5_LOGI("bsec2 ver:%u.%u.%u.%u", ver.major, ver.minor, ver.major_bugfix, ver.minor_bugfix); // Subscribe constexpr bsec_virtual_sensor_t sensorList[] = { BSEC_OUTPUT_IAQ, BSEC_OUTPUT_RAW_TEMPERATURE, BSEC_OUTPUT_RAW_PRESSURE, BSEC_OUTPUT_RAW_HUMIDITY, BSEC_OUTPUT_RAW_GAS, BSEC_OUTPUT_STABILIZATION_STATUS, BSEC_OUTPUT_RUN_IN_STATUS}; std::vector nosubscribed(vs_table, vs_table + m5::stl::size(vs_table)); auto it = std::remove_if(nosubscribed.begin(), nosubscribed.end(), [&sensorList](bsec_virtual_sensor_t vs) { auto e = std::begin(sensorList) + m5::stl::size(sensorList); return std::find(std::begin(sensorList), e, vs) != e; }); nosubscribed.erase(it, nosubscribed.end()); EXPECT_TRUE(unit->bsec2UpdateSubscription(sensorList, m5::stl::size(sensorList), bsec2::SampleRate::LowPower)); for (auto&& e : sensorList) { EXPECT_TRUE(unit->bsec2IsSubscribed(e)) << e; } for (auto&& e : nosubscribed) { EXPECT_FALSE(unit->bsec2IsSubscribed(e)) << e; } for (auto&& e : sensorList) { EXPECT_TRUE(unit->bsec2Unsubscribe(e)) << e; EXPECT_FALSE(unit->bsec2IsSubscribed(e)) << e; } for (auto&& e : nosubscribed) { EXPECT_FALSE(unit->bsec2IsSubscribed(e)) << e; } for (auto&& e : sensorList) { EXPECT_TRUE(unit->bsec2Subscribe(e)) << e; EXPECT_TRUE(unit->bsec2IsSubscribed(e)) << e; } for (auto&& e : nosubscribed) { EXPECT_FALSE(unit->bsec2IsSubscribed(e)) << e; } EXPECT_TRUE(unit->bsec2UnsubscribeAll()); // Same as stop for (auto&& e : vs_table) { EXPECT_FALSE(unit->bsec2IsSubscribed(e)) << e; } // Measurement EXPECT_TRUE(unit->startPeriodicMeasurement(sensorList, m5::stl::size(sensorList), bsec2::SampleRate::LowPower)); auto bits = virtual_sensor_array_to_bits(sensorList, m5::stl::size(sensorList)); EXPECT_EQ(unit->bsec2Subscription(), bits); #if 1 test_periodic_measurement(unit.get(), 8, 8, (unit->interval() * 2) * 8, check_measurement_values, false); EXPECT_TRUE(unit->stopPeriodicMeasurement()); EXPECT_FALSE(unit->inPeriodic()); EXPECT_EQ(unit->mode(), Mode::Sleep); EXPECT_EQ(unit->available(), 8U); EXPECT_FALSE(unit->empty()); EXPECT_TRUE(unit->full()); uint32_t cnt{4}; while (unit->available() && cnt--) { EXPECT_TRUE(std::isfinite(unit->iaq())); EXPECT_TRUE(std::isfinite(unit->temperature())); EXPECT_TRUE(std::isfinite(unit->pressure())); EXPECT_TRUE(std::isfinite(unit->humidity())); EXPECT_TRUE(std::isfinite(unit->gas())); EXPECT_FLOAT_EQ(unit->iaq(), unit->oldest().iaq()); EXPECT_FLOAT_EQ(unit->temperature(), unit->oldest().temperature()); EXPECT_FLOAT_EQ(unit->pressure(), unit->oldest().pressure()); EXPECT_FLOAT_EQ(unit->humidity(), unit->oldest().humidity()); EXPECT_FLOAT_EQ(unit->gas(), unit->oldest().gas()); EXPECT_FALSE(unit->empty()); unit->discard(); } #else uint32_t cnt{8}; while (cnt--) { auto now{m5::utility::millis()}; auto timeout_at = now + 3 * 1000; // LowPower do { unit->update(); now = m5::utility::millis(); if (unit->updated()) { break; } m5::utility::delay(1); } while (now <= timeout_at); // M5_LOGW("now:%ld timeout_at:%ld", now, timeout_at); EXPECT_TRUE(unit->updated()); if (cnt < 2) { EXPECT_LE(now, timeout_at); } auto d = unit->latest(); for (auto&& vs : sensorList) { float f = d.get(vs); // M5_LOGI("[%u]:%.2f", vs, f); EXPECT_TRUE(std::isfinite(f)) << vs; } for (auto&& vs : nosubscribed) { float f = d.get(vs); EXPECT_FALSE(std::isfinite(f)) << vs; } } EXPECT_TRUE(unit->inPeriodic()); EXPECT_TRUE(unit->stopPeriodicMeasurement()); EXPECT_FALSE(unit->inPeriodic()); EXPECT_EQ(unit->available(), 8U); EXPECT_FALSE(unit->empty()); EXPECT_TRUE(unit->full()); cnt = 4; while (unit->available() && cnt--) { EXPECT_TRUE(std::isfinite(unit->iaq())); EXPECT_TRUE(std::isfinite(unit->temperature())); EXPECT_TRUE(std::isfinite(unit->pressure())); EXPECT_TRUE(std::isfinite(unit->humidity())); EXPECT_TRUE(std::isfinite(unit->gas())); EXPECT_FLOAT_EQ(unit->iaq(), unit->oldest().iaq()); EXPECT_FLOAT_EQ(unit->temperature(), unit->oldest().temperature()); EXPECT_FLOAT_EQ(unit->pressure(), unit->oldest().pressure()); EXPECT_FLOAT_EQ(unit->humidity(), unit->oldest().humidity()); EXPECT_FLOAT_EQ(unit->gas(), unit->oldest().gas()); EXPECT_FALSE(unit->empty()); unit->discard(); } #endif EXPECT_EQ(unit->available(), 4U); EXPECT_FALSE(unit->empty()); EXPECT_FALSE(unit->full()); unit->flush(); EXPECT_EQ(unit->available(), 0U); EXPECT_TRUE(unit->empty()); EXPECT_FALSE(unit->full()); // Config EXPECT_EQ(sizeof(bsec_config), BSEC_MAX_PROPERTY_BLOB_SIZE); EXPECT_TRUE(unit->bsec2GetConfig(cfg, actual)); // get current EXPECT_NE(memcmp(cfg, bsec_config, actual), 0); EXPECT_TRUE(unit->bsec2SetConfig(bsec_config)); // overwrite EXPECT_TRUE(unit->bsec2GetConfig(cfg, actual)); auto cmp = memcmp(cfg, bsec_config, actual) == 0; EXPECT_TRUE(cmp); if (!cmp) { M5_DUMPI(cfg, actual); M5_DUMPI(bsec_config, actual); } // State EXPECT_TRUE(unit->bsec2GetState(state2, actual)); // get current cmp = memcmp(state2, state, actual) == 0; EXPECT_FALSE(cmp); EXPECT_TRUE(unit->bsec2SetState(state)); // rewrite EXPECT_TRUE(unit->bsec2GetState(state2, actual)); // get cmp = memcmp(state2, state, actual) == 0; if (!cmp) { M5_DUMPI(state, actual); M5_DUMPI(state2, actual); } } #endif TEST_P(TestBME688, SingleShot) { SCOPED_TRACE(ustr); bme68xConf tph{}; tph.os_temp = m5::stl::to_underlying(Oversampling::x2); tph.os_pres = m5::stl::to_underlying(Oversampling::x1); tph.os_hum = m5::stl::to_underlying(Oversampling::x16); tph.filter = m5::stl::to_underlying(Filter::None); tph.odr = m5::stl::to_underlying(ODR::None); EXPECT_TRUE(unit->writeTPHSetting(tph)); m5::unit::bme688::bme68xHeatrConf hs{}; hs.enable = true; hs.heatr_temp = 300; hs.heatr_dur = 100; EXPECT_TRUE(unit->writeHeaterSetting(Mode::Forced, hs)); bme68xData data{}; EXPECT_TRUE(unit->inPeriodic()); EXPECT_FALSE(unit->measureSingleShot(data)); EXPECT_TRUE(unit->stopPeriodicMeasurement()); Mode m{}; EXPECT_TRUE(unit->readMode(m)); EXPECT_EQ(m, Mode::Sleep); EXPECT_FALSE(unit->inPeriodic()); EXPECT_TRUE(unit->measureSingleShot(data)); #if 0 M5_LOGI( "Status:%u\n" "Gidx:%u Midx:%u\n" "ResHeate:%u IDAC:%u GasWait:%u\n" "T:%f P:%f H:%f R:%f", data.status, data.gas_index, data.meas_index, data.res_heat, data.idac, data.gas_wait, data.temperature, data.pressure, data.humidity, data.gas_resistance); #endif } TEST_P(TestBME688, PeriodicForced) { SCOPED_TRACE(ustr); EXPECT_TRUE(unit->inPeriodic()); EXPECT_TRUE(unit->stopPeriodicMeasurement()); EXPECT_FALSE(unit->inPeriodic()); bme68xConf tph{}; tph.os_temp = m5::stl::to_underlying(Oversampling::x2); tph.os_pres = m5::stl::to_underlying(Oversampling::x1); tph.os_hum = m5::stl::to_underlying(Oversampling::x16); tph.filter = m5::stl::to_underlying(Filter::None); tph.odr = m5::stl::to_underlying(ODR::None); EXPECT_TRUE(unit->writeTPHSetting(tph)); m5::unit::bme688::bme68xHeatrConf hs{}; hs.enable = true; hs.heatr_temp = 300; hs.heatr_dur = 100; EXPECT_TRUE(unit->writeHeaterSetting(Mode::Forced, hs)); // EXPECT_FALSE(unit->inPeriodic()); EXPECT_TRUE(unit->startPeriodicMeasurement(Mode::Forced)); EXPECT_TRUE(unit->inPeriodic()); EXPECT_EQ(unit->mode(), Mode::Forced); // Always wait for an interval to obtain the correct value for the first measurement // EXPECT_EQ(unit->updatedMillis(), 0); // EXPECT_EQ(unit->available(), 0U); EXPECT_TRUE(unit->empty()); EXPECT_FALSE(unit->full()); test_periodic_measurement(unit.get(), 8, 8, (unit->interval() * 2) * 8, check_measurement_values, false); EXPECT_TRUE(unit->stopPeriodicMeasurement()); EXPECT_FALSE(unit->inPeriodic()); EXPECT_EQ(unit->mode(), Mode::Sleep); EXPECT_EQ(unit->available(), 8U); EXPECT_FALSE(unit->empty()); EXPECT_TRUE(unit->full()); uint32_t cnt{4}; while (unit->available() && cnt--) { EXPECT_TRUE(std::isfinite(unit->oldest().raw_temperature())); EXPECT_TRUE(std::isfinite(unit->oldest().raw_pressure())); EXPECT_TRUE(std::isfinite(unit->oldest().raw_humidity())); EXPECT_TRUE(std::isfinite(unit->oldest().raw_gas())); EXPECT_FALSE(unit->empty()); unit->discard(); } EXPECT_EQ(unit->available(), 4U); EXPECT_FALSE(unit->empty()); EXPECT_FALSE(unit->full()); unit->flush(); EXPECT_EQ(unit->available(), 0U); EXPECT_TRUE(unit->empty()); EXPECT_FALSE(unit->full()); } TEST_P(TestBME688, PeriodicParallel) { SCOPED_TRACE(ustr); EXPECT_TRUE(unit->inPeriodic()); EXPECT_TRUE(unit->stopPeriodicMeasurement()); EXPECT_FALSE(unit->inPeriodic()); uint16_t temp_prof[10] = {320, 100, 100, 100, 200, 200, 200, 320, 320, 320}; /* Multiplier to the shared heater duration */ uint16_t mul_prof[10] = {5, 2, 10, 30, 5, 5, 5, 5, 5, 5}; bme68xConf tph{}; tph.os_temp = m5::stl::to_underlying(Oversampling::x2); tph.os_pres = m5::stl::to_underlying(Oversampling::x1); tph.os_hum = m5::stl::to_underlying(Oversampling::x16); tph.filter = m5::stl::to_underlying(Filter::None); tph.odr = m5::stl::to_underlying(ODR::None); EXPECT_TRUE(unit->writeTPHSetting(tph)); m5::unit::bme688::bme68xHeatrConf hs{}; hs.enable = true; memcpy(hs.temp_prof, temp_prof, sizeof(temp_prof)); memcpy(hs.dur_prof, mul_prof, sizeof(mul_prof)); hs.shared_heatr_dur = (uint16_t)(140 - (unit->calculateMeasurementInterval(Mode::Parallel, tph) / 1000)); hs.profile_len = 10; EXPECT_TRUE(unit->writeHeaterSetting(Mode::Parallel, hs)); // EXPECT_FALSE(unit->inPeriodic()); EXPECT_TRUE(unit->startPeriodicMeasurement(Mode::Parallel)); EXPECT_TRUE(unit->inPeriodic()); EXPECT_EQ(unit->mode(), Mode::Parallel); EXPECT_EQ(unit->available(), 0U); EXPECT_TRUE(unit->empty()); EXPECT_FALSE(unit->full()); // TODO : What are the measurement intervals in the parallel mode datasheet? test_periodic_measurement(unit.get(), 8, 1, (unit->interval() * 10) * 10, check_measurement_values, false); EXPECT_TRUE(unit->stopPeriodicMeasurement()); EXPECT_FALSE(unit->inPeriodic()); EXPECT_EQ(unit->mode(), Mode::Sleep); EXPECT_EQ(unit->available(), 8U); EXPECT_FALSE(unit->empty()); EXPECT_TRUE(unit->full()); uint32_t cnt{4}; while (unit->available() && cnt--) { EXPECT_TRUE(std::isfinite(unit->oldest().raw_temperature())); EXPECT_TRUE(std::isfinite(unit->oldest().raw_pressure())); EXPECT_TRUE(std::isfinite(unit->oldest().raw_humidity())); EXPECT_TRUE(std::isfinite(unit->oldest().raw_gas())); EXPECT_FALSE(unit->empty()); unit->discard(); } EXPECT_EQ(unit->available(), 4U); EXPECT_FALSE(unit->empty()); EXPECT_FALSE(unit->full()); unit->flush(); EXPECT_EQ(unit->available(), 0U); EXPECT_TRUE(unit->empty()); EXPECT_FALSE(unit->full()); } TEST_P(TestBME688, PeriodiSequential) { SCOPED_TRACE(ustr); EXPECT_TRUE(unit->inPeriodic()); EXPECT_TRUE(unit->stopPeriodicMeasurement()); EXPECT_FALSE(unit->inPeriodic()); uint16_t temp_prof[10] = {200, 240, 280, 320, 360, 360, 320, 280, 240, 200}; /* Heating duration in milliseconds */ uint16_t dur_prof[10] = {100, 100, 100, 100, 100, 100, 100, 100, 100, 100}; bme68xConf tph{}; tph.os_temp = m5::stl::to_underlying(Oversampling::x2); tph.os_pres = m5::stl::to_underlying(Oversampling::x1); tph.os_hum = m5::stl::to_underlying(Oversampling::x16); tph.filter = m5::stl::to_underlying(Filter::None); tph.odr = m5::stl::to_underlying(ODR::None); EXPECT_TRUE(unit->writeTPHSetting(tph)); m5::unit::bme688::bme68xHeatrConf hs{}; hs.enable = true; memcpy(hs.temp_prof, temp_prof, sizeof(temp_prof)); memcpy(hs.dur_prof, dur_prof, sizeof(dur_prof)); hs.profile_len = 10; EXPECT_TRUE(unit->writeHeaterSetting(Mode::Sequential, hs)); // EXPECT_FALSE(unit->inPeriodic()); EXPECT_TRUE(unit->startPeriodicMeasurement(Mode::Sequential)); EXPECT_TRUE(unit->inPeriodic()); EXPECT_EQ(unit->mode(), Mode::Sequential); test_periodic_measurement(unit.get(), 8, 1, (unit->interval() * 2) * 8, check_measurement_values, false); EXPECT_TRUE(unit->stopPeriodicMeasurement()); EXPECT_FALSE(unit->inPeriodic()); EXPECT_EQ(unit->mode(), Mode::Sleep); } TEST_P(TestBME688, SelfTest) { SCOPED_TRACE(ustr); EXPECT_TRUE(unit->selfTest()); }