/* * Copyright (C) 2018 Otto-von-Guericke-Universität Magdeburg * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. */ #include #include #include "container.h" #include "embUnit/embUnit.h" #include "tests-sht1x.h" /** @brief Maximum difference from correct temperature value [in e-02 °C] */ static const int16_t max_diff_temp = 1; /** @brief Maximum difference from correct humidity value [in e-02 %] */ static const int16_t max_diff_hum = 10; /* * Configure tested values steps * * Verify less values on boards as without hwfloat it takes minutes to test. * Checking that the trend is valid is enough to find int overflow * or similar errors. * * Keep the full range test on native as it is "instant" */ #ifdef CPU_NATIVE #define TEMPERATURE_TEST_STEPS 1 /* Use 0.13°c steps. */ #define HUMIDITY_TEST_TEMP_STEPS 13 #else /* CPU_NATIVE */ #define TEMPERATURE_TEST_STEPS 100 #define HUMIDITY_TEST_TEMP_STEPS 1300 #endif /* CPU_NATIVE */ static int16_t expected_temp(const sht1x_dev_t *dev, uint16_t _raw) { static const double d1_table[] = { -40.1, -39.8, -39.7, -39.6, -39.4 }; double d1 = d1_table[dev->vdd]; double d2 = (dev->conf & SHT1X_CONF_LOW_RESOLUTION) ? 0.04 : 0.01; double raw = (double)_raw; double temp = d1 + d2 * raw; return (int16_t)(temp * 100.0); } static int16_t expected_hum(const sht1x_dev_t *dev, uint16_t _raw, int16_t _temp) { static const double c1 = -2.0468; static const double t1 = 0.01; double temp = ((double)_temp) / 100.0; double raw = (double)_raw; double c2, c3, t2, hum_linear, hum_real; if (dev->conf & SHT1X_CONF_LOW_RESOLUTION) { c2 = 0.5872; c3 = -4.0845e-04; t2 = 0.00128; } else { c2 = 0.0367; c3 = -1.5955e-06; t2 = 0.00008; } hum_linear = c1 + c2 * raw + c3 * (raw * raw); hum_real = (temp - 25.0) * (t1 + t2 * raw) + hum_linear; return (int16_t)(hum_real * 100.0); } static void test_sht1x_conversion(void) { const uint8_t vdds[] = { SHT1X_VDD_5_0V, SHT1X_VDD_4_0V, SHT1X_VDD_3_5V, SHT1X_VDD_3_0V, SHT1X_VDD_2_5V, }; const uint8_t confs[] = { SHT1X_CONF_LOW_RESOLUTION, 0 }; const uint16_t max_raw_temps[] = { 0xfff, 0x3fff }; const uint16_t max_raw_hums[] = { 0xff, 0xfff }; sht1x_dev_t dev = { .conf = 0 }; for (size_t i_res = 0; i_res < ARRAY_SIZE(confs); i_res++) { dev.conf = confs[i_res]; uint16_t max_raw_temp = max_raw_temps[i_res]; uint16_t max_raw_hum = max_raw_hums[i_res]; for (size_t i_vdd = 0; i_vdd < ARRAY_SIZE(vdds); i_vdd++) { dev.vdd = vdds[i_vdd]; for (uint16_t raw_temp = 0; raw_temp <= max_raw_temp; raw_temp += TEMPERATURE_TEST_STEPS) { int16_t got_temp = sht1x_temperature(&dev, raw_temp); int16_t exp_temp = expected_temp(&dev, raw_temp); TEST_ASSERT(((got_temp - max_diff_temp) <= exp_temp) && ((got_temp + max_diff_temp) >= exp_temp)); } } /* Testing for temperatures between -10.00°C and 65.00°C */ for (int16_t temp = -1000; temp < 6500; temp += HUMIDITY_TEST_TEMP_STEPS) { for (uint16_t raw_hum = 0; raw_hum <= max_raw_hum; raw_hum++) { int16_t exp_hum = expected_hum(&dev, raw_hum, temp); if ((exp_hum < 0) || (exp_hum > 10000)) { /* Result out of range, ignore it */ continue; } int16_t got_hum = sht1x_humidity(&dev, raw_hum, temp); TEST_ASSERT(((got_hum - max_diff_hum) <= exp_hum) && ((got_hum + max_diff_hum) >= exp_hum)); } } } } Test *tests_sht1x_tests(void) { EMB_UNIT_TESTFIXTURES(fixtures) { new_TestFixture(test_sht1x_conversion), }; EMB_UNIT_TESTCALLER(sht1x_tests, NULL, NULL, fixtures); return (Test *)&sht1x_tests; } void tests_sht1x(void) { TESTS_RUN(tests_sht1x_tests()); }