diff --git a/CHANGELOG.md b/CHANGELOG.md index a6e3a3f4c..d233720f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ All notable changes to this project will be documented in this file. ### Fixed - ESP32 Arduino Core WiFi timeout is changed from msec to seconds - Reduce blocking by adding WifiPollDns before resolving NTP and/or MQTT server names (#14394) +- SHT1X driver hangs and wrong values on ESP32 (#15790) ### Removed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 063d3aa33..9a08d4691 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -143,6 +143,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo - BL09xx negative power presentation [#15374](https://github.com/arendst/Tasmota/issues/15374) - Possible pin output toggle after power on [#15630](https://github.com/arendst/Tasmota/issues/15630) - Reduce blocking by adding WifiPollDns before resolving NTP and/or MQTT server names [#14394](https://github.com/arendst/Tasmota/issues/14394) +- SHT1X driver hangs and wrong values on ESP32 [#15790](https://github.com/arendst/Tasmota/issues/15790) - ESP32 Arduino Core WiFi timeout is changed from msec to seconds ### Removed diff --git a/tasmota/tasmota_xsns_sensor/xsns_07_sht1x.ino b/tasmota/tasmota_xsns_sensor/xsns_07_sht1x.ino index 60e004098..4d571960c 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_07_sht1x.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_07_sht1x.ino @@ -25,7 +25,7 @@ * Reading temperature and humidity takes about 320 milliseconds! * Source: Marinus vd Broek https://github.com/ESP8266nu/ESPEasy * - * I2C Address: None + * I2C Address: None and ruins I2C bus hence reinit I2C after each call \*********************************************************************************************/ #define XSNS_07 7 @@ -37,98 +37,95 @@ enum { SHT1X_CMD_SOFT_RESET = B00011110 }; -int8_t sht_sda_pin; -int8_t sht_scl_pin; -uint8_t sht_type = 0; -char sht_types[] = "SHT1X"; -uint8_t sht_valid = 0; -float sht_temperature = 0; -float sht_humidity = 0; +struct { + float temperature = 0; + float humidity = 0; + int8_t sda_pin; + int8_t scl_pin; + uint8_t type = 0; + uint8_t valid = 0; + char types[6] = "SHT1X"; +} Sht1x; -bool ShtReset(void) -{ - pinMode(sht_sda_pin, INPUT_PULLUP); - pinMode(sht_scl_pin, OUTPUT); +bool ShtReset(void) { + pinMode(Sht1x.sda_pin, INPUT_PULLUP); + pinMode(Sht1x.scl_pin, OUTPUT); delay(11); for (uint32_t i = 0; i < 9; i++) { - digitalWrite(sht_scl_pin, HIGH); - digitalWrite(sht_scl_pin, LOW); + digitalWrite(Sht1x.scl_pin, HIGH); + digitalWrite(Sht1x.scl_pin, LOW); } bool success = ShtSendCommand(SHT1X_CMD_SOFT_RESET); delay(11); return success; } -bool ShtSendCommand(const uint8_t cmd) -{ - pinMode(sht_sda_pin, OUTPUT); +bool ShtSendCommand(const uint8_t cmd) { + pinMode(Sht1x.sda_pin, OUTPUT); // Transmission Start sequence - digitalWrite(sht_sda_pin, HIGH); - digitalWrite(sht_scl_pin, HIGH); - digitalWrite(sht_sda_pin, LOW); - digitalWrite(sht_scl_pin, LOW); - digitalWrite(sht_scl_pin, HIGH); - digitalWrite(sht_sda_pin, HIGH); - digitalWrite(sht_scl_pin, LOW); + digitalWrite(Sht1x.sda_pin, HIGH); + digitalWrite(Sht1x.scl_pin, HIGH); + digitalWrite(Sht1x.sda_pin, LOW); + digitalWrite(Sht1x.scl_pin, LOW); + digitalWrite(Sht1x.scl_pin, HIGH); + digitalWrite(Sht1x.sda_pin, HIGH); + digitalWrite(Sht1x.scl_pin, LOW); // Send the command (address must be 000b) - TasShiftOut(sht_sda_pin, sht_scl_pin, MSBFIRST, cmd); + TasShiftOut(Sht1x.sda_pin, Sht1x.scl_pin, MSBFIRST, cmd); // Wait for ACK bool ackerror = false; - digitalWrite(sht_scl_pin, HIGH); - pinMode(sht_sda_pin, INPUT_PULLUP); - if (digitalRead(sht_sda_pin) != LOW) { + digitalWrite(Sht1x.scl_pin, HIGH); + pinMode(Sht1x.sda_pin, INPUT_PULLUP); + if (digitalRead(Sht1x.sda_pin) != LOW) { ackerror = true; } - digitalWrite(sht_scl_pin, LOW); + digitalWrite(Sht1x.scl_pin, LOW); delayMicroseconds(1); // Give the sensor time to release the data line - if (digitalRead(sht_sda_pin) != HIGH) { + if (digitalRead(Sht1x.sda_pin) != HIGH) { ackerror = true; } if (ackerror) { -// sht_type = 0; +// Sht1x.type = 0; AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_SHT1 D_SENSOR_DID_NOT_ACK_COMMAND)); } return (!ackerror); } -bool ShtAwaitResult(void) -{ +bool ShtAwaitResult(void) { // Maximum 320ms for 14 bit measurement for (uint32_t i = 0; i < 16; i++) { - if (LOW == digitalRead(sht_sda_pin)) { + if (LOW == digitalRead(Sht1x.sda_pin)) { return true; } delay(20); } AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_SHT1 D_SENSOR_BUSY)); -// sht_type = 0; +// Sht1x.type = 0; return false; } -int ShtReadData(void) -{ +int ShtReadData(void) { int val = 0; // Read most significant byte - val = TasShiftIn(sht_sda_pin, sht_scl_pin, 8); + val = TasShiftIn(Sht1x.sda_pin, Sht1x.scl_pin, 8); val <<= 8; // Send ACK - pinMode(sht_sda_pin, OUTPUT); - digitalWrite(sht_sda_pin, LOW); - digitalWrite(sht_scl_pin, HIGH); - digitalWrite(sht_scl_pin, LOW); - pinMode(sht_sda_pin, INPUT_PULLUP); + pinMode(Sht1x.sda_pin, OUTPUT); + digitalWrite(Sht1x.sda_pin, LOW); + digitalWrite(Sht1x.scl_pin, HIGH); + digitalWrite(Sht1x.scl_pin, LOW); + pinMode(Sht1x.sda_pin, INPUT_PULLUP); // Read least significant byte - val |= TasShiftIn(sht_sda_pin, sht_scl_pin, 8); + val |= TasShiftIn(Sht1x.sda_pin, Sht1x.scl_pin, 8); // Keep DATA pin high to skip CRC - digitalWrite(sht_scl_pin, HIGH); - digitalWrite(sht_scl_pin, LOW); + digitalWrite(Sht1x.scl_pin, HIGH); + digitalWrite(Sht1x.scl_pin, LOW); return val; } -bool ShtRead(void) -{ - if (sht_valid) { sht_valid--; } +bool ShtRead(void) { + if (Sht1x.valid) { Sht1x.valid--; } if (!ShtReset()) { return false; } if (!ShtSendCommand(SHT1X_CMD_MEASURE_TEMP)) { return false; } if (!ShtAwaitResult()) { return false; } @@ -140,50 +137,46 @@ bool ShtRead(void) // Temperature conversion coefficients from SHT1X datasheet for version 4 const float d1 = -39.7f; // 3.5V const float d2 = 0.01f; // 14-bit - sht_temperature = d1 + (tempRaw * d2); + Sht1x.temperature = d1 + (tempRaw * d2); const float c1 = -2.0468f; const float c2 = 0.0367f; const float c3 = -1.5955E-6f; const float t1 = 0.01f; const float t2 = 0.00008f; float rhLinear = c1 + c2 * humRaw + c3 * humRaw * humRaw; - sht_humidity = (sht_temperature - 25) * (t1 + t2 * humRaw) + rhLinear; - sht_temperature = ConvertTemp(sht_temperature); - sht_humidity = ConvertHumidity(sht_humidity); + Sht1x.humidity = (Sht1x.temperature - 25) * (t1 + t2 * humRaw) + rhLinear; + Sht1x.temperature = ConvertTemp(Sht1x.temperature); + Sht1x.humidity = ConvertHumidity(Sht1x.humidity); - sht_valid = SENSOR_MAX_MISS; + Sht1x.valid = SENSOR_MAX_MISS; return true; } /********************************************************************************************/ -void ShtDetect(void) -{ - sht_sda_pin = Pin(GPIO_I2C_SDA); - sht_scl_pin = Pin(GPIO_I2C_SCL); +void ShtDetect(void) { + Sht1x.sda_pin = Pin(GPIO_I2C_SDA); + Sht1x.scl_pin = Pin(GPIO_I2C_SCL); if (ShtRead()) { - sht_type = 1; + Sht1x.type = 1; AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_I2C D_SHT1X_FOUND)); - } else { - I2cBegin(sht_sda_pin, sht_scl_pin); - sht_type = 0; } + I2cBegin(Sht1x.sda_pin, Sht1x.scl_pin); // Reinit I2C bus } -void ShtEverySecond(void) -{ - if (!(TasmotaGlobal.uptime %4)) { // Every 4 seconds +void ShtEverySecond(void) { + if (!(TasmotaGlobal.uptime %4)) { // Every 4 seconds // 344mS if (!ShtRead()) { - AddLogMissed(sht_types, sht_valid); + AddLogMissed(Sht1x.types, Sht1x.valid); } + I2cBegin(Sht1x.sda_pin, Sht1x.scl_pin); // Reinit I2C bus } } -void ShtShow(bool json) -{ - if (sht_valid) { - TempHumDewShow(json, (0 == TasmotaGlobal.tele_period), sht_types, sht_temperature, sht_humidity); +void ShtShow(bool json) { + if (Sht1x.valid) { + TempHumDewShow(json, (0 == TasmotaGlobal.tele_period), Sht1x.types, Sht1x.temperature, Sht1x.humidity); } } @@ -191,8 +184,7 @@ void ShtShow(bool json) * Interface \*********************************************************************************************/ -bool Xsns07(uint8_t function) -{ +bool Xsns07(uint8_t function) { if (!I2cEnabled(XI2C_08)) { return false; } bool result = false; @@ -200,7 +192,7 @@ bool Xsns07(uint8_t function) if (FUNC_INIT == function) { ShtDetect(); } - else if (sht_type) { + else if (Sht1x.type) { switch (function) { case FUNC_EVERY_SECOND: ShtEverySecond();