Add I2C bus2 support to HTU temperature sensor

This commit is contained in:
Theo Arends 2023-10-19 17:37:19 +02:00
parent b6811b2f4e
commit 49709807c7
4 changed files with 86 additions and 90 deletions

View File

@ -5,7 +5,8 @@ All notable changes to this project will be documented in this file.
## [13.2.0.1] ## [13.2.0.1]
### Added ### Added
- ESP32 I2C bus2 support to iAQ core driver (#19799) - I2C bus2 support to iAQ core sensor (#19799)
- I2C bus2 support to HTU temperature sensor
### Breaking Changed ### Breaking Changed

View File

@ -113,7 +113,8 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
## Changelog v13.2.0.1 ## Changelog v13.2.0.1
### Added ### Added
- Experimental support for ESP32-C2 and ESP32-C6 using Arduino core v3 - Experimental support for ESP32-C2 and ESP32-C6 using Arduino core v3
- ESP32 I2C bus2 support to iAQ core driver [#19799](https://github.com/arendst/Tasmota/issues/19799) - I2C bus2 support to iAQ core sensor [#19799](https://github.com/arendst/Tasmota/issues/19799)
- I2C bus2 support to HTU temperature sensor
### Breaking Changed ### Breaking Changed

View File

@ -63,6 +63,7 @@ struct {
float temperature = 0; float temperature = 0;
float humidity = 0; float humidity = 0;
uint8_t address; uint8_t address;
uint8_t bus;
uint8_t type = 0; uint8_t type = 0;
uint8_t delay_temp; uint8_t delay_temp;
uint8_t delay_humidity = 50; uint8_t delay_humidity = 50;
@ -72,8 +73,7 @@ struct {
/*********************************************************************************************/ /*********************************************************************************************/
uint8_t HtuCheckCrc8(uint16_t data) uint8_t HtuCheckCrc8(uint16_t data) {
{
for (uint32_t bit = 0; bit < 16; bit++) { for (uint32_t bit = 0; bit < 16; bit++) {
if (data & 0x8000) { if (data & 0x8000) {
data = (data << 1) ^ HTU21_CRC8_POLYNOM; data = (data << 1) ^ HTU21_CRC8_POLYNOM;
@ -84,22 +84,33 @@ uint8_t HtuCheckCrc8(uint16_t data)
return data >>= 8; return data >>= 8;
} }
uint8_t HtuReadDeviceId(void) bool HtuReset(void) {
{ TwoWire& myWire = I2cGetWire(Htu.bus);
HtuReset(); // Fixes ESP32 sensor loss at restart if (&myWire == nullptr) { return false; } // No valid I2c bus
myWire.beginTransmission(HTU21_ADDR);
myWire.write(HTU21_RESET);
myWire.endTransmission();
delay(15); // Reset takes 15ms
return true;
}
uint8_t HtuReadDeviceId(void) {
if (!HtuReset()) { return 0; }; // Fixes ESP32 sensor loss at restart
uint16_t deviceID = 0; uint16_t deviceID = 0;
uint8_t checksum = 0; uint8_t checksum = 0;
Wire.beginTransmission(HTU21_ADDR); TwoWire& myWire = I2cGetWire(Htu.bus);
Wire.write(HTU21_SERIAL2_READ1); myWire.beginTransmission(HTU21_ADDR);
Wire.write(HTU21_SERIAL2_READ2); myWire.write(HTU21_SERIAL2_READ1);
Wire.endTransmission(); myWire.write(HTU21_SERIAL2_READ2);
myWire.endTransmission();
Wire.requestFrom(HTU21_ADDR, 3); myWire.requestFrom(HTU21_ADDR, 3);
deviceID = Wire.read() << 8; deviceID = myWire.read() << 8;
deviceID |= Wire.read(); deviceID |= myWire.read();
checksum = Wire.read(); checksum = myWire.read();
if (HtuCheckCrc8(deviceID) == checksum) { if (HtuCheckCrc8(deviceID) == checksum) {
deviceID = deviceID >> 8; deviceID = deviceID >> 8;
} else { } else {
@ -108,28 +119,17 @@ uint8_t HtuReadDeviceId(void)
return (uint8_t)deviceID; return (uint8_t)deviceID;
} }
void HtuSetResolution(uint8_t resolution) void HtuSetResolution(uint8_t resolution) {
{ uint8_t current = I2cRead8(HTU21_ADDR, HTU21_READREG, Htu.bus);
uint8_t current = I2cRead8(HTU21_ADDR, HTU21_READREG);
current &= 0x7E; // Replace current resolution bits with 0 current &= 0x7E; // Replace current resolution bits with 0
current |= resolution; // Add new resolution bits to register current |= resolution; // Add new resolution bits to register
I2cWrite8(HTU21_ADDR, HTU21_WRITEREG, current); I2cWrite8(HTU21_ADDR, HTU21_WRITEREG, current, Htu.bus);
} }
void HtuReset(void) void HtuHeater(uint8_t heater) {
{ uint8_t current = I2cRead8(HTU21_ADDR, HTU21_READREG, Htu.bus);
Wire.beginTransmission(HTU21_ADDR);
Wire.write(HTU21_RESET);
Wire.endTransmission();
delay(15); // Reset takes 15ms
}
void HtuHeater(uint8_t heater) switch(heater) {
{
uint8_t current = I2cRead8(HTU21_ADDR, HTU21_READREG);
switch(heater)
{
case HTU21_HEATER_ON : current |= heater; case HTU21_HEATER_ON : current |= heater;
break; break;
case HTU21_HEATER_OFF : current &= heater; case HTU21_HEATER_OFF : current &= heater;
@ -137,48 +137,47 @@ void HtuHeater(uint8_t heater)
default : current &= heater; default : current &= heater;
break; break;
} }
I2cWrite8(HTU21_ADDR, HTU21_WRITEREG, current); I2cWrite8(HTU21_ADDR, HTU21_WRITEREG, current, Htu.bus);
} }
void HtuInit(void) void HtuInit(void) {
{
HtuReset(); HtuReset();
HtuHeater(HTU21_HEATER_OFF); HtuHeater(HTU21_HEATER_OFF);
HtuSetResolution(HTU21_RES_RH12_T14); HtuSetResolution(HTU21_RES_RH12_T14);
} }
bool HtuRead(void) bool HtuRead(void) {
{
uint8_t checksum = 0; uint8_t checksum = 0;
uint16_t sensorval = 0; uint16_t sensorval = 0;
if (Htu.valid) { Htu.valid--; } if (Htu.valid) { Htu.valid--; }
Wire.beginTransmission(HTU21_ADDR); TwoWire& myWire = I2cGetWire(Htu.bus);
Wire.write(HTU21_READTEMP); myWire.beginTransmission(HTU21_ADDR);
if (Wire.endTransmission() != 0) { return false; } // In case of error myWire.write(HTU21_READTEMP);
if (myWire.endTransmission() != 0) { return false; } // In case of error
delay(Htu.delay_temp); // Sensor time at max resolution delay(Htu.delay_temp); // Sensor time at max resolution
Wire.requestFrom(HTU21_ADDR, 3); myWire.requestFrom(HTU21_ADDR, 3);
if (3 == Wire.available()) { if (3 == myWire.available()) {
sensorval = Wire.read() << 8; // MSB sensorval = myWire.read() << 8; // MSB
sensorval |= Wire.read(); // LSB sensorval |= myWire.read(); // LSB
checksum = Wire.read(); checksum = myWire.read();
} }
if (HtuCheckCrc8(sensorval) != checksum) { return false; } // Checksum mismatch if (HtuCheckCrc8(sensorval) != checksum) { return false; } // Checksum mismatch
Htu.temperature = ConvertTemp(0.002681f * (float)sensorval - 46.85f); Htu.temperature = ConvertTemp(0.002681f * (float)sensorval - 46.85f);
Wire.beginTransmission(HTU21_ADDR); myWire.beginTransmission(HTU21_ADDR);
Wire.write(HTU21_READHUM); myWire.write(HTU21_READHUM);
if (Wire.endTransmission() != 0) { return false; } // In case of error if (myWire.endTransmission() != 0) { return false; } // In case of error
delay(Htu.delay_humidity); // Sensor time at max resolution delay(Htu.delay_humidity); // Sensor time at max resolution
Wire.requestFrom(HTU21_ADDR, 3); myWire.requestFrom(HTU21_ADDR, 3);
if (3 <= Wire.available()) { if (3 <= myWire.available()) {
sensorval = Wire.read() << 8; // MSB sensorval = myWire.read() << 8; // MSB
sensorval |= Wire.read(); // LSB sensorval |= myWire.read(); // LSB
checksum = Wire.read(); checksum = myWire.read();
} }
if (HtuCheckCrc8(sensorval) != checksum) { return false; } // Checksum mismatch if (HtuCheckCrc8(sensorval) != checksum) { return false; } // Checksum mismatch
@ -201,41 +200,42 @@ bool HtuRead(void)
/********************************************************************************************/ /********************************************************************************************/
void HtuDetect(void) void HtuDetect(void) {
{
Htu.address = HTU21_ADDR; Htu.address = HTU21_ADDR;
if (!I2cSetDevice(Htu.address)) { return; } for (Htu.bus = 0; Htu.bus < 2; Htu.bus++) {
if (!I2cSetDevice(Htu.address, Htu.bus)) { continue; }
Htu.type = HtuReadDeviceId(); Htu.type = HtuReadDeviceId();
if (Htu.type) { if (Htu.type) {
uint8_t index = 0; uint8_t index = 0;
HtuInit(); HtuInit();
switch (Htu.type) { switch (Htu.type) {
case HTU21_CHIPID: case HTU21_CHIPID:
Htu.delay_temp = 50; Htu.delay_temp = 50;
Htu.delay_humidity = 16; Htu.delay_humidity = 16;
break; break;
case SI7021_CHIPID: case SI7021_CHIPID:
index++; // 3 index++; // 3
case SI7020_CHIPID: case SI7020_CHIPID:
index++; // 2 index++; // 2
case SI7013_CHIPID: case SI7013_CHIPID:
index++; // 1 index++; // 1
Htu.delay_temp = 12; Htu.delay_temp = 12;
Htu.delay_humidity = 23; Htu.delay_humidity = 23;
break; break;
default: default:
index = 4; index = 4;
Htu.delay_temp = 50; Htu.delay_temp = 50;
Htu.delay_humidity = 23; Htu.delay_humidity = 23;
}
GetTextIndexed(Htu.types, sizeof(Htu.types), index, kHtuTypes);
I2cSetActiveFound(Htu.address, Htu.types);
break;
} }
GetTextIndexed(Htu.types, sizeof(Htu.types), index, kHtuTypes);
I2cSetActiveFound(Htu.address, Htu.types);
} }
} }
void HtuEverySecond(void) void HtuEverySecond(void) {
{
if (TasmotaGlobal.uptime &1) { // Every 2 seconds if (TasmotaGlobal.uptime &1) { // Every 2 seconds
// HTU21: 68mS, SI70xx: 37mS // HTU21: 68mS, SI70xx: 37mS
if (!HtuRead()) { if (!HtuRead()) {
@ -244,8 +244,7 @@ void HtuEverySecond(void)
} }
} }
void HtuShow(bool json) void HtuShow(bool json) {
{
if (Htu.valid) { if (Htu.valid) {
TempHumDewShow(json, (0 == TasmotaGlobal.tele_period), Htu.types, Htu.temperature, Htu.humidity); TempHumDewShow(json, (0 == TasmotaGlobal.tele_period), Htu.types, Htu.temperature, Htu.humidity);
} }

View File

@ -75,14 +75,9 @@ void IAQ_Init(void) {
if (!IAQ_Read()) { continue; } if (!IAQ_Read()) { continue; }
I2cSetActiveFound(I2_ADR_IAQ, "IAQ", bus); I2cSetActiveFound(I2_ADR_IAQ, "IAQ", bus);
iAQ.ready = true; iAQ.ready = true;
break;
} }
/*
if (!I2cSetDevice(I2_ADR_IAQ)) { return; }
I2cSetActiveFound(I2_ADR_IAQ, "IAQ");
iAQ.i2c_address = I2_ADR_IAQ;
iAQ.ready = true;
*/
/* /*
for (iAQ.i2c_address = I2_ADR_IAQ; iAQ.i2c_address < I2_ADR_IAQ +5; iAQ.i2c_address++) { for (iAQ.i2c_address = I2_ADR_IAQ; iAQ.i2c_address < I2_ADR_IAQ +5; iAQ.i2c_address++) {
if (I2cActive(iAQ.i2c_address)) { continue; } if (I2cActive(iAQ.i2c_address)) { continue; }