SHT3X_ATY.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. /**
  2. * @file SHT3X_ATY.c
  3. *
  4. * @param Project DEVICE_GENERAL_ATY_LIB
  5. *
  6. * @author ATY
  7. *
  8. * @copyright
  9. * - Copyright 2017 - 2023 MZ-ATY
  10. * - This code follows:
  11. * - MZ-ATY Various Contents Joint Statement -
  12. * <a href="https://mengze.top/MZ-ATY_VCJS">
  13. * https://mengze.top/MZ-ATY_VCJS</a>
  14. * - CC 4.0 BY-NC-SA -
  15. * <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
  16. * https://creativecommons.org/licenses/by-nc-sa/4.0/</a>
  17. * - Your use will be deemed to have accepted the terms of this statement.
  18. *
  19. * @brief Familiar functions of SHT3X tem&hum transistor for all devices
  20. *
  21. * @version
  22. * - 1_01_200318 > ATY
  23. * -# Preliminary version, first Release
  24. * - 1_02_231229 > ATY
  25. * -# add multy addr and channel
  26. ********************************************************************************
  27. */
  28. #ifndef __SHT3X_ATY_C
  29. #define __SHT3X_ATY_C
  30. #include "SHT3X_ATY.h"
  31. /******************************* For user *************************************/
  32. /******************************************************************************/
  33. float temperatureSHT3X = 0.0;
  34. float humiditySHT3X = 0.0;
  35. /* 0: 0-65T, 10-90H, Best accuracy
  36. 1: -40-0/65-120T, 0-10/90-100H, not good accuracy, warning
  37. 2: out of limit data, error
  38. */
  39. uint8_t warningFlag = 0;
  40. /**
  41. * @brief calc crc with SHT3X data
  42. * @param sht3xData data to calc
  43. * @param nbrOfBytes length of data to calc
  44. * @return uint8_t crc value
  45. */
  46. uint8_t SHT3X_CalcCrc(uint8_t* sht3xData, uint8_t nbrOfBytes)
  47. {
  48. uint8_t bit_t; // bit mask
  49. uint8_t crc = 0xFF; // calculated checksum
  50. uint8_t byteCtr; // byte counter
  51. // calculates 8-Bit checksum with given polynomial
  52. for(byteCtr = 0; byteCtr < nbrOfBytes; byteCtr++)
  53. {
  54. crc ^= sht3xData[byteCtr];
  55. for(bit_t = 8; bit_t > 0; --bit_t)
  56. {
  57. if(crc & 0x80)
  58. crc = (crc << 1) ^ POLYNOMIAL;
  59. else
  60. crc = (crc << 1);
  61. }
  62. }
  63. return crc;
  64. }
  65. /**
  66. * @brief check crc with SHT3X data
  67. * @param sht3xData data to check
  68. * @param nbrOfBytes length of data to check
  69. * @param checksum compare value with calculated crc
  70. * @return !0: wrong, 0: success
  71. */
  72. uint8_t SHT3X_CheckCrc(uint8_t* sht3xData, uint8_t nbrOfBytes, uint8_t checksum)
  73. {
  74. // calculates 8-Bit checksum
  75. uint8_t crc = SHT3X_CalcCrc(sht3xData, nbrOfBytes);
  76. if(crc != checksum)
  77. return 1;
  78. else
  79. return 0;
  80. }
  81. /**
  82. * @brief write command to SHT3X
  83. * @param cmd command to send
  84. * @param addr chip address
  85. * @param channel chip channel
  86. */
  87. void SHT3X_WriteCommand(sht3xCommands cmd, uint8_t addr, uint8_t channel)
  88. {
  89. uint8_t cmd_t[2];
  90. cmd_t[0] = cmd >> 8;
  91. cmd_t[1] = cmd & 0xFF;
  92. I2C_Write(addr, cmd_t, 2, channel);
  93. }
  94. /**
  95. * @brief start periodic measurment
  96. * @param repeatability repeatability
  97. * @param frequency frequency
  98. * @param addr chip address
  99. * @param channel chip channel
  100. * @note use depending on the required repeatability and frequency,
  101. * the corresponding command
  102. */
  103. void SHT3X_StartPeriodicMeasurment(sht3xRepeatability repeatability, sht3xFrequency frequency, uint8_t addr, uint8_t channel)
  104. {
  105. switch(repeatability)
  106. {
  107. case REPEATAB_LOW: // low repeatability
  108. switch(frequency)
  109. {
  110. case FREQUENCY_HZ5: // low repeatability, 0.5 Hz
  111. SHT3X_WriteCommand(CMD_MEAS_PERI_05_L, addr, channel);
  112. break;
  113. case FREQUENCY_1HZ: // low repeatability, 1.0 Hz
  114. SHT3X_WriteCommand(CMD_MEAS_PERI_1_L, addr, channel);
  115. break;
  116. case FREQUENCY_2HZ: // low repeatability, 2.0 Hz
  117. SHT3X_WriteCommand(CMD_MEAS_PERI_2_L, addr, channel);
  118. break;
  119. case FREQUENCY_4HZ: // low repeatability, 4.0 Hz
  120. SHT3X_WriteCommand(CMD_MEAS_PERI_4_L, addr, channel);
  121. break;
  122. case FREQUENCY_10HZ: // low repeatability, 10.0 Hz
  123. SHT3X_WriteCommand(CMD_MEAS_PERI_10_L, addr, channel);
  124. break;
  125. default:
  126. break;
  127. }
  128. break;
  129. case REPEATAB_MEDIUM: // medium repeatability
  130. switch(frequency)
  131. {
  132. case FREQUENCY_HZ5: // medium repeatability, 0.5 Hz
  133. SHT3X_WriteCommand(CMD_MEAS_PERI_05_M, addr, channel);
  134. break;
  135. case FREQUENCY_1HZ: // medium repeatability, 1.0 Hz
  136. SHT3X_WriteCommand(CMD_MEAS_PERI_1_M, addr, channel);
  137. break;
  138. case FREQUENCY_2HZ: // medium repeatability, 2.0 Hz
  139. SHT3X_WriteCommand(CMD_MEAS_PERI_2_M, addr, channel);
  140. break;
  141. case FREQUENCY_4HZ: // medium repeatability, 4.0 Hz
  142. SHT3X_WriteCommand(CMD_MEAS_PERI_4_M, addr, channel);
  143. break;
  144. case FREQUENCY_10HZ: // medium repeatability, 10.0 Hz
  145. SHT3X_WriteCommand(CMD_MEAS_PERI_10_M, addr, channel);
  146. break;
  147. default:
  148. break;
  149. }
  150. break;
  151. case REPEATAB_HIGH: // high repeatability
  152. switch(frequency)
  153. {
  154. case FREQUENCY_HZ5: // high repeatability, 0.5 Hz
  155. SHT3X_WriteCommand(CMD_MEAS_PERI_05_H, addr, channel);
  156. break;
  157. case FREQUENCY_1HZ: // high repeatability, 1.0 Hz
  158. SHT3X_WriteCommand(CMD_MEAS_PERI_1_H, addr, channel);
  159. break;
  160. case FREQUENCY_2HZ: // high repeatability, 2.0 Hz
  161. SHT3X_WriteCommand(CMD_MEAS_PERI_2_H, addr, channel);
  162. break;
  163. case FREQUENCY_4HZ: // high repeatability, 4.0 Hz
  164. SHT3X_WriteCommand(CMD_MEAS_PERI_4_H, addr, channel);
  165. break;
  166. case FREQUENCY_10HZ: // high repeatability, 10.0 Hz
  167. SHT3X_WriteCommand(CMD_MEAS_PERI_10_H);
  168. break;
  169. default:
  170. break;
  171. }
  172. break;
  173. default:
  174. break;
  175. }
  176. }
  177. /**
  178. * @brief calc real value from 16 bit data
  179. * @param temperature temperature 16 bit origin value
  180. * @param humidity humidity 16 bit origin value
  181. */
  182. void SHT3X_ValuePorcess(uint16_t* temperature, uint16_t* humidity)
  183. {
  184. temperatureSHT3X = -45 + 175 * (1.0 * (*temperature) / 65535);
  185. humiditySHT3X = 100 * (1.0 * (*humidity) / 65535);
  186. warningFlag = 0;
  187. if(temperatureSHT3X < 0 || temperatureSHT3X>65)
  188. warningFlag = 1;
  189. else if(temperatureSHT3X < -40)
  190. {
  191. warningFlag = 2;
  192. temperatureSHT3X = -40;
  193. }
  194. else if(temperatureSHT3X > 120)
  195. {
  196. warningFlag = 2;
  197. temperatureSHT3X = 120;
  198. }
  199. if(humiditySHT3X < 10 || humiditySHT3X>90)
  200. warningFlag = 1;
  201. else if(humiditySHT3X < 0)
  202. {
  203. warningFlag = 2;
  204. humiditySHT3X = 0;
  205. }
  206. else if(humiditySHT3X > 100)
  207. {
  208. warningFlag = 2;
  209. humiditySHT3X = 100;
  210. }
  211. }
  212. /**
  213. * @brief read all data from SHT3X
  214. * @param temperature temperature 16 bit origin value
  215. * @param humidity humidity 16 bit origin value
  216. * @param addr chip address
  217. * @param channel chip channel
  218. */
  219. void SHT3X_ReadDataAndCrc(uint16_t* temperature, uint16_t* humidity, uint8_t addr, uint8_t channel)
  220. {
  221. uint8_t bytes[6]; // read 2 data array and 1 checksum byte
  222. // read two data bytes and one checksum byte
  223. I2C_Read(addr, bytes, 6, channel);
  224. // verify checksum then combine the two bytes to a 16-bit value
  225. if(!SHT3X_CheckCrc(bytes, 2, bytes[2]))
  226. *temperature = (bytes[0] << 8) | bytes[1];
  227. // else
  228. // *temperature = 0;
  229. if(!SHT3X_CheckCrc(bytes + 3, 2, bytes[5]))
  230. *humidity = (bytes[3] << 8) | bytes[4];
  231. // else
  232. // *humidity = 0;
  233. SHT3X_ValuePorcess(temperature, humidity);
  234. }
  235. /**
  236. * @brief read data and calc real value
  237. * @param addr chip address
  238. * @param channel chip channel
  239. */
  240. void SHT3X_ReadMeasurementBuffer(uint8_t addr, uint8_t channel)
  241. {
  242. uint16_t hexValueTemp = 0;
  243. uint16_t hexValueHumi = 0;
  244. SHT3X_WriteCommand(CMD_FETCH_DATA, addr, channel);
  245. SHT3X_ReadDataAndCrc(&hexValueTemp, &hexValueHumi, addr, channel);
  246. }
  247. /**
  248. * @brief start measurement in clock stretching mode
  249. * @param repeatability repeatability
  250. * @param addr chip address
  251. * @param channel chip channel
  252. * @note use depending on the required repeatability, the corresponding command
  253. */
  254. void SHT3X_GetTempAndHumiClkStretch(sht3xRepeatability repeatability, uint8_t addr, uint8_t channel)
  255. {
  256. uint16_t hexTempValue = 0;
  257. uint16_t hexHumiValue = 0;
  258. switch(repeatability)
  259. {
  260. case REPEATAB_LOW:
  261. SHT3X_WriteCommand(CMD_MEAS_CLOCKSTR_L, addr, channel);
  262. break;
  263. case REPEATAB_MEDIUM:
  264. SHT3X_WriteCommand(CMD_MEAS_CLOCKSTR_M, addr, channel);
  265. break;
  266. case REPEATAB_HIGH:
  267. SHT3X_WriteCommand(CMD_MEAS_CLOCKSTR_H, addr, channel);
  268. break;
  269. default:
  270. break;
  271. }
  272. SHT3X_ReadDataAndCrc(&hexTempValue, &hexHumiValue, addr, channel);
  273. }
  274. /**
  275. * @brief init SHT3X, check device
  276. * @param addr chip address
  277. * @param channel chip channel
  278. * @note put at main init
  279. */
  280. void SHT3X_InitBegin(uint8_t addr, uint8_t channel)
  281. {
  282. uint8_t i = 0;
  283. SHT3X_StartPeriodicMeasurment(REPEATAB_HIGH, FREQUENCY_10HZ, addr, channel);
  284. for(i = 0; i < 9; i++)
  285. {
  286. DelayMs(110);
  287. SHT3X_ReadMeasurementBuffer(addr, channel);
  288. // SHT3X_GetTempAndHumiClkStretch(REPEATAB_LOW, addr, channel);
  289. }
  290. // SHT3X_StartPeriodicMeasurment(REPEATAB_LOW, FREQUENCY_HZ1, addr, channel);
  291. SHT3X_StartPeriodicMeasurment(REPEATAB_HIGH, FREQUENCY_10HZ, addr, channel);
  292. }
  293. // todo: not tested
  294. // void main()
  295. // {
  296. // SHT3X_InitBegin(addr, channel);
  297. // while(1)
  298. // {
  299. // SHT3X_ReadMeasurementBuffer(addr, channel);
  300. // UartSendStr("\r\nHT: ");
  301. // UartSendStr(TemperatureStr);
  302. // UartSendStr(" - ");
  303. // UartSendStr(HumidityStr);
  304. // DelayMs(2000);
  305. // }
  306. // }
  307. // // declare 5byte group, last with '\0' for show
  308. // uint8_t Temperature[5] = {0, 0, '.', 0};
  309. // uint8_t Humidity[5] = {0, 0, '.', 0};
  310. // uint8_t TemperatureStr[5] = {0, 0, '.', 0};
  311. // uint8_t HumidityStr[5] = {0, 0, '.', 0};
  312. // uint8_t temperatureHexI = 0; // integer
  313. // uint8_t temperatureHexD = 0; // decimal
  314. // uint8_t humidityHexI = 0;
  315. // uint8_t humidityHexD = 0;
  316. // temperature = ((uint8_t)decTempValue << 8) + ((uint16_t)(decTempValue * 100) % 100);
  317. // humidity = ((uint8_t)decHumiValue << 8) + ((uint16_t)(decHumiValue * 100) % 100);
  318. // temperatureHexI = temperature >> 8;
  319. // temperatureHexD = temperature;
  320. // humidityHexI = humidity >> 8;
  321. // humidityHexD = humidity;
  322. // // todo higher than 100 or below 0
  323. // // todo only get origin data, do not change type here
  324. // // todo AHT20 deal the same, and change I2C function to standard
  325. // // if()
  326. // Temperature[0] = temperatureHexI / 10;
  327. // Temperature[1] = temperatureHexI % 10;
  328. // Temperature[3] = temperatureHexD / 10;
  329. // Humidity[0] = humidityHexI / 10;
  330. // Humidity[1] = humidityHexI % 10;
  331. // Humidity[3] = humidityHexD / 10;
  332. // TemperatureStr[0] = Temperature[0] + '0';
  333. // TemperatureStr[1] = Temperature[1] + '0';
  334. // TemperatureStr[3] = Temperature[3] + '0';
  335. // HumidityStr[0] = Humidity[0] + '0';
  336. // HumidityStr[1] = Humidity[1] + '0';
  337. // HumidityStr[3] = Humidity[3] + '0';
  338. #endif /* __SHT3X_ATY_C */
  339. /******************************** End Of File *********************************/