xsns_14_sht3x.ino 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /*
  2. xsns_14_sht3x.ino - SHT3X temperature and humidity sensor support for Sonoff-Tasmota
  3. Copyright (C) 2018 Theo Arends
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. #ifdef USE_I2C
  16. #ifdef USE_SHT3X
  17. /*********************************************************************************************\
  18. * SHT3X and SHTC3 - Temperature and Humidity
  19. *
  20. * I2C Address: 0x44, 0x45 or 0x70 (SHTC3)
  21. \*********************************************************************************************/
  22. #define XSNS_14 14
  23. #define SHT3X_ADDR_GND 0x44 // address pin low (GND)
  24. #define SHT3X_ADDR_VDD 0x45 // address pin high (VDD)
  25. #define SHTC3_ADDR 0x70 // address for shtc3 sensor
  26. #define SHT3X_MAX_SENSORS 3
  27. const char kShtTypes[] PROGMEM = "SHT3X|SHT3X|SHTC3";
  28. uint8_t sht3x_addresses[] = { SHT3X_ADDR_GND, SHT3X_ADDR_VDD, SHTC3_ADDR };
  29. uint8_t sht3x_count = 0;
  30. struct SHT3XSTRUCT {
  31. uint8_t address; // I2C bus address
  32. char types[6]; // Sensor type name and address - "SHT3X-0xXX"
  33. } sht3x_sensors[SHT3X_MAX_SENSORS];
  34. bool Sht3xRead(float &t, float &h, uint8_t sht3x_address)
  35. {
  36. unsigned int data[6];
  37. t = NAN;
  38. h = NAN;
  39. Wire.beginTransmission(sht3x_address);
  40. if (SHTC3_ADDR == sht3x_address) {
  41. Wire.write(0x35); // Wake from
  42. Wire.write(0x17); // sleep
  43. Wire.endTransmission();
  44. Wire.beginTransmission(sht3x_address);
  45. Wire.write(0x78); // Disable clock stretching ( I don't think that wire library support clock stretching )
  46. Wire.write(0x66); // High resolution
  47. } else {
  48. Wire.write(0x2C); // Enable clock stretching
  49. Wire.write(0x06); // High repeatability
  50. }
  51. if (Wire.endTransmission() != 0) { // Stop I2C transmission
  52. return false;
  53. }
  54. delay(30); // Timing verified with logic analyzer (10 is to short)
  55. Wire.requestFrom(sht3x_address, (uint8_t)6); // Request 6 bytes of data
  56. for (int i = 0; i < 6; i++) {
  57. data[i] = Wire.read(); // cTemp msb, cTemp lsb, cTemp crc, humidity msb, humidity lsb, humidity crc
  58. };
  59. t = ConvertTemp((float)((((data[0] << 8) | data[1]) * 175) / 65535.0) - 45);
  60. h = (float)((((data[3] << 8) | data[4]) * 100) / 65535.0);
  61. return (!isnan(t) && !isnan(h));
  62. }
  63. /********************************************************************************************/
  64. void Sht3xDetect(void)
  65. {
  66. if (sht3x_count) return;
  67. float t;
  68. float h;
  69. for (byte i = 0; i < SHT3X_MAX_SENSORS; i++) {
  70. if (Sht3xRead(t, h, sht3x_addresses[i])) {
  71. sht3x_sensors[sht3x_count].address = sht3x_addresses[i];
  72. GetTextIndexed(sht3x_sensors[sht3x_count].types, sizeof(sht3x_sensors[sht3x_count].types), i, kShtTypes);
  73. snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, sht3x_sensors[sht3x_count].types, sht3x_sensors[sht3x_count].address);
  74. AddLog(LOG_LEVEL_DEBUG);
  75. sht3x_count++;
  76. }
  77. }
  78. }
  79. void Sht3xShow(boolean json)
  80. {
  81. if (sht3x_count) {
  82. float t;
  83. float h;
  84. char types[11];
  85. for (byte i = 0; i < sht3x_count; i++) {
  86. if (Sht3xRead(t, h, sht3x_sensors[i].address)) {
  87. if (0 == i) { SetGlobalValues(t, h); }
  88. char temperature[33];
  89. dtostrfd(t, Settings.flag2.temperature_resolution, temperature);
  90. char humidity[33];
  91. dtostrfd(h, Settings.flag2.humidity_resolution, humidity);
  92. snprintf_P(types, sizeof(types), PSTR("%s-0x%02X"), sht3x_sensors[i].types, sht3x_sensors[i].address); // "SHT3X-0xXX"
  93. if (json) {
  94. snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, types, temperature, humidity);
  95. #ifdef USE_DOMOTICZ
  96. if ((0 == tele_period) && (0 == i)) { // We want the same first sensor to report to Domoticz in case a read is missed
  97. DomoticzTempHumSensor(temperature, humidity);
  98. }
  99. #endif // USE_DOMOTICZ
  100. #ifdef USE_KNX
  101. if (0 == tele_period) {
  102. KnxSensor(KNX_TEMPERATURE, t);
  103. KnxSensor(KNX_HUMIDITY, h);
  104. }
  105. #endif // USE_KNX
  106. #ifdef USE_WEBSERVER
  107. } else {
  108. snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, types, temperature, TempUnit());
  109. snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_HUM, mqtt_data, types, humidity);
  110. #endif // USE_WEBSERVER
  111. }
  112. }
  113. }
  114. }
  115. }
  116. /*********************************************************************************************\
  117. * Interface
  118. \*********************************************************************************************/
  119. boolean Xsns14(byte function)
  120. {
  121. boolean result = false;
  122. if (i2c_flg) {
  123. switch (function) {
  124. case FUNC_INIT:
  125. Sht3xDetect();
  126. break;
  127. case FUNC_JSON_APPEND:
  128. Sht3xShow(1);
  129. break;
  130. #ifdef USE_WEBSERVER
  131. case FUNC_WEB_APPEND:
  132. Sht3xShow(0);
  133. break;
  134. #endif // USE_WEBSERVER
  135. }
  136. }
  137. return result;
  138. }
  139. #endif // USE_SHT3X
  140. #endif // USE_I2C