bme680_selftest.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /**\mainpage
  2. * Copyright (C) 2017 - 2018 Bosch Sensortec GmbH
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions are met:
  6. *
  7. * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. *
  10. * Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. *
  14. * Neither the name of the copyright holder nor the names of the
  15. * contributors may be used to endorse or promote products derived from
  16. * this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  19. * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
  20. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  21. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. * DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
  23. * OR CONTRIBUTORS BE LIABLE FOR ANY
  24. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
  25. * OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,
  26. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  27. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  29. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  31. * ANY WAY OUT OF THE USE OF THIS
  32. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
  33. *
  34. * The information provided is believed to be accurate and reliable.
  35. * The copyright holder assumes no responsibility
  36. * for the consequences of use
  37. * of such information nor for any infringement of patents or
  38. * other rights of third parties which may result from its use.
  39. * No license is granted by implication or otherwise under any patent or
  40. * patent rights of the copyright holder.
  41. *
  42. * File bme680_selftest.c
  43. * @date 16 May 2018
  44. * @version 3.5.3
  45. *
  46. */
  47. /*!
  48. * @addtogroup bme680_selftest
  49. * @brief
  50. * @{*/
  51. #include "bme680_selftest.h"
  52. #define MIN_TEMPERATURE INT16_C(0) /* 0 degree Celsius */
  53. #define MAX_TEMPERATURE INT16_C(6000) /* 60 degree Celsius */
  54. #define MIN_PRESSURE UINT32_C(90000) /* 900 hecto Pascals */
  55. #define MAX_PRESSURE UINT32_C(110000) /* 1100 hecto Pascals */
  56. #define MIN_HUMIDITY UINT32_C(20000) /* 20% relative humidity */
  57. #define MAX_HUMIDITY UINT32_C(80000) /* 80% relative humidity*/
  58. #define HEATR_DUR 2000
  59. #define N_MEAS 6
  60. #define LOW_TEMP 150
  61. #define HIGH_TEMP 350
  62. /*!
  63. * @brief Function to analyze the sensor data
  64. *
  65. * @param[in] data Array of measurement data
  66. * @param[in] n_meas Number of measurements
  67. *
  68. * @return Error code
  69. * @retval 0 Success
  70. * @retval > 0 Warning
  71. */
  72. static int8_t analyze_sensor_data(struct bme680_field_data *data, uint8_t n_meas);
  73. /*!
  74. * @brief Self-test API for the BME680
  75. */
  76. int8_t bme680_self_test(struct bme680_dev *dev)
  77. {
  78. int8_t rslt = BME680_OK;
  79. struct bme680_field_data data[N_MEAS];
  80. struct bme680_dev t_dev;
  81. /* Copy required parameters from reference bme680_dev struct */
  82. t_dev.dev_id = dev->dev_id;
  83. t_dev.amb_temp = 25;
  84. t_dev.read = dev->read;
  85. t_dev.write = dev->write;
  86. t_dev.intf = dev->intf;
  87. t_dev.delay_ms = dev->delay_ms;
  88. rslt = bme680_init(&t_dev);
  89. if (rslt == BME680_OK) {
  90. /* Select the power mode */
  91. /* Must be set before writing the sensor configuration */
  92. t_dev.power_mode = BME680_FORCED_MODE;
  93. uint16_t settings_sel;
  94. /* Set the temperature, pressure and humidity & filter settings */
  95. t_dev.tph_sett.os_hum = BME680_OS_1X;
  96. t_dev.tph_sett.os_pres = BME680_OS_16X;
  97. t_dev.tph_sett.os_temp = BME680_OS_2X;
  98. /* Set the remaining gas sensor settings and link the heating profile */
  99. t_dev.gas_sett.run_gas = BME680_ENABLE_GAS_MEAS;
  100. t_dev.gas_sett.heatr_dur = HEATR_DUR;
  101. settings_sel = BME680_OST_SEL | BME680_OSP_SEL | BME680_OSH_SEL | BME680_GAS_SENSOR_SEL;
  102. uint16_t profile_dur = 0;
  103. bme680_get_profile_dur(&profile_dur, &t_dev);
  104. uint8_t i = 0;
  105. while ((rslt == BME680_OK) && (i < N_MEAS)) {
  106. if (rslt == BME680_OK) {
  107. if (i % 2 == 0)
  108. t_dev.gas_sett.heatr_temp = HIGH_TEMP; /* Higher temperature */
  109. else
  110. t_dev.gas_sett.heatr_temp = LOW_TEMP; /* Lower temperature */
  111. rslt = bme680_set_sensor_settings(settings_sel, &t_dev);
  112. if (rslt == BME680_OK) {
  113. rslt = bme680_set_sensor_mode(&t_dev); /* Trigger a measurement */
  114. t_dev.delay_ms(profile_dur); /* Wait for the measurement to complete */
  115. rslt = bme680_get_sensor_data(&data[i], &t_dev);
  116. }
  117. }
  118. i++;
  119. }
  120. if (rslt == BME680_OK)
  121. rslt = analyze_sensor_data(data, N_MEAS);
  122. }
  123. return rslt;
  124. }
  125. /*!
  126. * @brief Function to analyze the sensor data
  127. */
  128. static int8_t analyze_sensor_data(struct bme680_field_data *data, uint8_t n_meas)
  129. {
  130. int8_t rslt = BME680_OK;
  131. uint8_t self_test_failed = 0, i;
  132. uint32_t cent_res = 0;
  133. if ((data[0].temperature < MIN_TEMPERATURE) || (data[0].temperature > MAX_TEMPERATURE))
  134. self_test_failed++;
  135. if ((data[0].pressure < MIN_PRESSURE) || (data[0].pressure > MAX_PRESSURE))
  136. self_test_failed++;
  137. if ((data[0].humidity < MIN_HUMIDITY) || (data[0].humidity > MAX_HUMIDITY))
  138. self_test_failed++;
  139. for (i = 0; i < n_meas; i++) /* Every gas measurement should be valid */
  140. if (!(data[i].status & BME680_GASM_VALID_MSK))
  141. self_test_failed++;
  142. if (n_meas >= 6)
  143. cent_res = (data[3].gas_resistance + data[5].gas_resistance) / (2 * data[4].gas_resistance);
  144. if ((cent_res * 5) < 6)
  145. self_test_failed++;
  146. if (self_test_failed)
  147. rslt = BME680_W_SELF_TEST_FAILED;
  148. return rslt;
  149. }
  150. /** @}*/