638 lines
22 KiB
C++
638 lines
22 KiB
C++
/*
|
|
* SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
/*
|
|
UnitTest for UnitBME688
|
|
*/
|
|
#include <gtest/gtest.h>
|
|
#include <Wire.h>
|
|
#include <M5Unified.h>
|
|
#include <M5UnitUnified.hpp>
|
|
#include <googletest/test_helper.hpp>
|
|
#include <googletest/test_template.hpp>
|
|
#include <unit/unit_BME688.hpp>
|
|
#include <chrono>
|
|
#include <random>
|
|
#include <set>
|
|
|
|
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<UnitBME688, bool> {
|
|
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 <config/bme688/bme688_sel_33v_300s_4d/bsec_selectivity.txt>
|
|
};
|
|
#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<bsec_virtual_sensor_t> 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());
|
|
}
|