Refactored I2C drivers HTU21, BH1750 and HYT

This commit is contained in:
Theo Arends 2024-09-16 16:27:30 +02:00
parent c61dd0fd2c
commit 97970974fc
6 changed files with 107 additions and 14 deletions

View File

@ -15,6 +15,7 @@ All notable changes to this project will be documented in this file.
### Breaking Changed ### Breaking Changed
### Changed ### Changed
- Refactored I2C drivers HTU21, BH1750 and HYT
### Fixed ### Fixed
- Shutter missing HOLD on shutterbutton (#22108) - Shutter missing HOLD on shutterbutton (#22108)

View File

@ -146,6 +146,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
- GPIOViewer from v1.5.5 to v1.5.6 - GPIOViewer from v1.5.5 to v1.5.6
- Energy BL09xx command ``CurrentSet`` input changed from Ampere to milliAmpere - Energy BL09xx command ``CurrentSet`` input changed from Ampere to milliAmpere
- Energy force Apparent Power equals Active Power when (Calculated) Apparent Power is less than Active Power [#20653](https://github.com/arendst/Tasmota/issues/20653) - Energy force Apparent Power equals Active Power when (Calculated) Apparent Power is less than Active Power [#20653](https://github.com/arendst/Tasmota/issues/20653)
- Refactored I2C drivers HTU21, BH1750 and HYT
### Fixed ### Fixed
- Crash when calling TasmotaSerial destructor when initialized with incorrect arguments [#22036](https://github.com/arendst/Tasmota/issues/22036) - Crash when calling TasmotaSerial destructor when initialized with incorrect arguments [#22036](https://github.com/arendst/Tasmota/issues/22036)

View File

@ -149,6 +149,8 @@ int32_t I2cRead24(uint8_t addr, uint8_t reg, uint8_t bus = 0) {
return i2c_buffer; return i2c_buffer;
} }
/*-------------------------------------------------------------------------------------------*/
bool I2cWrite(uint8_t addr, uint8_t reg, uint32_t val, uint8_t size, uint8_t bus = 0) { bool I2cWrite(uint8_t addr, uint8_t reg, uint32_t val, uint8_t size, uint8_t bus = 0) {
TwoWire& myWire = I2cGetWire(bus); TwoWire& myWire = I2cGetWire(bus);
if (&myWire == nullptr) { return false; } // No valid I2c bus if (&myWire == nullptr) { return false; } // No valid I2c bus
@ -166,6 +168,10 @@ bool I2cWrite(uint8_t addr, uint8_t reg, uint32_t val, uint8_t size, uint8_t bus
return (x); // 0 = Error, 1 = OK return (x); // 0 = Error, 1 = OK
} }
bool I2cWrite0(uint8_t addr, uint8_t reg, uint8_t bus = 0) {
return I2cWrite(addr, reg, 0, 0, bus); // 0 = Error, 1 = OK
}
bool I2cWrite8(uint8_t addr, uint8_t reg, uint32_t val, uint8_t bus = 0) { bool I2cWrite8(uint8_t addr, uint8_t reg, uint32_t val, uint8_t bus = 0) {
return I2cWrite(addr, reg, val, 1, bus); // 0 = Error, 1 = OK return I2cWrite(addr, reg, val, 1, bus); // 0 = Error, 1 = OK
} }
@ -178,14 +184,12 @@ bool I2cWrite16(uint8_t addr, uint8_t reg, uint32_t val, uint8_t bus = 0) {
* Return code: 0 = OK, 1 = Error * Return code: 0 = OK, 1 = Error
\*-------------------------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------------------------*/
bool I2cReadBuffer(uint8_t addr, uint8_t reg, uint8_t *reg_data, uint16_t len, uint8_t bus = 0) { bool I2cReadBuffer0(uint8_t addr, uint8_t *reg_data, uint16_t len, uint8_t bus = 0) {
TwoWire& myWire = I2cGetWire(bus); TwoWire& myWire = I2cGetWire(bus);
if (&myWire == nullptr) { return true; } // No valid I2c bus if (&myWire == nullptr) { return true; } // No valid I2c bus
myWire.beginTransmission((uint8_t)addr); myWire.requestFrom((uint8_t)addr, (uint8_t)len);
myWire.write((uint8_t)reg); if (myWire.available() != len) {
myWire.endTransmission();
if (len != myWire.requestFrom((uint8_t)addr, (uint8_t)len)) {
return true; // 1 = Error return true; // 1 = Error
} }
while (len--) { while (len--) {
@ -195,9 +199,34 @@ bool I2cReadBuffer(uint8_t addr, uint8_t reg, uint8_t *reg_data, uint16_t len, u
return false; // 0 = OK return false; // 0 = OK
} }
int8_t I2cWriteBuffer(uint8_t addr, uint8_t reg, uint8_t *reg_data, uint16_t len, uint8_t bus = 0) { bool I2cReadBuffer(uint8_t addr, int reg, uint8_t *reg_data, uint16_t len, uint8_t bus = 0) {
TwoWire& myWire = I2cGetWire(bus); TwoWire& myWire = I2cGetWire(bus);
if (&myWire == nullptr) { return 1; } // 1 = Error, No valid I2c bus if (&myWire == nullptr) { return true; } // No valid I2c bus
myWire.beginTransmission((uint8_t)addr);
if (reg > -1) {
myWire.write((uint8_t)reg);
if (reg > 255) {
myWire.write((uint8_t)(reg >> 8));
}
myWire.endTransmission();
}
if (len != myWire.requestFrom((uint8_t)addr, (uint8_t)len)) {
return true; // 1 = Error
}
while (len--) {
*reg_data = (uint8_t)myWire.read();
reg_data++;
}
if (reg < 0) {
myWire.endTransmission();
}
return false; // 0 = OK
}
bool I2cWriteBuffer(uint8_t addr, uint8_t reg, uint8_t *reg_data, uint16_t len, uint8_t bus = 0) {
TwoWire& myWire = I2cGetWire(bus);
if (&myWire == nullptr) { return true; } // 1 = Error, No valid I2c bus
myWire.beginTransmission((uint8_t)addr); myWire.beginTransmission((uint8_t)addr);
myWire.write((uint8_t)reg); myWire.write((uint8_t)reg);
@ -206,7 +235,7 @@ int8_t I2cWriteBuffer(uint8_t addr, uint8_t reg, uint8_t *reg_data, uint16_t len
reg_data++; reg_data++;
} }
myWire.endTransmission(); myWire.endTransmission();
return 0; // 0 = OK return false; // 0 = OK
} }
/*-------------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------------*/

View File

@ -85,19 +85,23 @@ uint8_t HtuCheckCrc8(uint16_t data) {
} }
bool HtuReset(void) { bool HtuReset(void) {
/*
TwoWire& myWire = I2cGetWire(Htu.bus); TwoWire& myWire = I2cGetWire(Htu.bus);
if (&myWire == nullptr) { return false; } // No valid I2c bus if (&myWire == nullptr) { return false; } // No valid I2c bus
myWire.beginTransmission(HTU21_ADDR); myWire.beginTransmission(HTU21_ADDR);
myWire.write(HTU21_RESET); myWire.write(HTU21_RESET);
myWire.endTransmission(); myWire.endTransmission();
*/
I2cWrite0(HTU21_ADDR, HTU21_RESET, Htu.bus);
delay(15); // Reset takes 15ms delay(15); // Reset takes 15ms
return true; return true;
} }
uint8_t HtuReadDeviceId(void) { uint8_t HtuReadDeviceId(void) {
if (!HtuReset()) { return 0; }; // Fixes ESP32 sensor loss at restart 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;
@ -116,6 +120,16 @@ uint8_t HtuReadDeviceId(void) {
} else { } else {
deviceID = 0; deviceID = 0;
} }
*/
uint8_t data[3];
I2cReadBuffer(HTU21_ADDR, HTU21_SERIAL2_READ2 << 8 | HTU21_SERIAL2_READ1, data, 3, Htu.bus);
uint16_t deviceID = (data[0] << 8) | data[1];
if (HtuCheckCrc8(deviceID) == data[2]) {
deviceID = deviceID >> 8;
} else {
deviceID = 0;
}
return (uint8_t)deviceID; return (uint8_t)deviceID;
} }
@ -146,12 +160,24 @@ void HtuInit(void) {
HtuSetResolution(HTU21_RES_RH12_T14); HtuSetResolution(HTU21_RES_RH12_T14);
} }
bool HtuRead(void) { bool HtuI2cRead(uint8_t reg, uint8_t hdelay, uint16_t &sensorval) {
uint8_t checksum = 0; if (!I2cWrite0(HTU21_ADDR, reg, Htu.bus)) { return false; }
uint16_t sensorval = 0; delay(hdelay); // Sensor time at max resolution
uint8_t data[3] = { 0 };
if (!I2cReadBuffer0(HTU21_ADDR, data, 3, Htu.bus)) {
sensorval = data[0] << 8 | data[1]; // MSB, LSB
}
if (HtuCheckCrc8(sensorval) != data[2]) { return false; } // Checksum mismatch
return true;
}
bool HtuRead(void) {
if (Htu.valid) { Htu.valid--; } if (Htu.valid) { Htu.valid--; }
uint16_t sensorval = 0;
/*
uint8_t checksum = 0;
TwoWire& myWire = I2cGetWire(Htu.bus); TwoWire& myWire = I2cGetWire(Htu.bus);
myWire.beginTransmission(HTU21_ADDR); myWire.beginTransmission(HTU21_ADDR);
myWire.write(HTU21_READTEMP); myWire.write(HTU21_READTEMP);
@ -180,6 +206,11 @@ bool HtuRead(void) {
checksum = myWire.read(); checksum = myWire.read();
} }
if (HtuCheckCrc8(sensorval) != checksum) { return false; } // Checksum mismatch if (HtuCheckCrc8(sensorval) != checksum) { return false; } // Checksum mismatch
*/
if (!HtuI2cRead(HTU21_READTEMP, Htu.delay_temp, sensorval)) { return false; } // Checksum mismatch
Htu.temperature = ConvertTemp(0.002681f * (float)sensorval - 46.85f);
if (!HtuI2cRead(HTU21_READHUM, Htu.delay_humidity, sensorval)) { return false; } // Checksum mismatch
sensorval ^= 0x02; // clear status bits sensorval ^= 0x02; // clear status bits
Htu.humidity = 0.001907f * (float)sensorval - 6; Htu.humidity = 0.001907f * (float)sensorval - 6;

View File

@ -79,13 +79,17 @@ uint8_t Bh1750Resolution(uint32_t sensor_index) {
} }
bool Bh1750SetResolution(uint32_t sensor_index) { bool Bh1750SetResolution(uint32_t sensor_index) {
/*
TwoWire& myWire = I2cGetWire(Bh1750_sensors[sensor_index].bus); TwoWire& myWire = I2cGetWire(Bh1750_sensors[sensor_index].bus);
myWire.beginTransmission(Bh1750_sensors[sensor_index].address); myWire.beginTransmission(Bh1750_sensors[sensor_index].address);
myWire.write(Bh1750.resolution[Bh1750Resolution(sensor_index)]); myWire.write(Bh1750.resolution[Bh1750Resolution(sensor_index)]);
return (!myWire.endTransmission()); return (!myWire.endTransmission());
*/
return I2cWrite0(Bh1750_sensors[sensor_index].address, Bh1750.resolution[Bh1750Resolution(sensor_index)], Bh1750_sensors[sensor_index].bus);
} }
bool Bh1750SetMTreg(uint32_t sensor_index) { bool Bh1750SetMTreg(uint32_t sensor_index) {
/*
TwoWire& myWire = I2cGetWire(Bh1750_sensors[sensor_index].bus); TwoWire& myWire = I2cGetWire(Bh1750_sensors[sensor_index].bus);
if (&myWire == nullptr) { return false; } // No valid I2c bus if (&myWire == nullptr) { return false; } // No valid I2c bus
myWire.beginTransmission(Bh1750_sensors[sensor_index].address); myWire.beginTransmission(Bh1750_sensors[sensor_index].address);
@ -96,16 +100,31 @@ bool Bh1750SetMTreg(uint32_t sensor_index) {
data = BH1750_MEASUREMENT_TIME_LOW | (Bh1750_sensors[sensor_index].mtreg & 0x1F); data = BH1750_MEASUREMENT_TIME_LOW | (Bh1750_sensors[sensor_index].mtreg & 0x1F);
myWire.write(data); myWire.write(data);
if (myWire.endTransmission()) { return false; } if (myWire.endTransmission()) { return false; }
*/
uint8_t reg = BH1750_MEASUREMENT_TIME_HIGH | ((Bh1750_sensors[sensor_index].mtreg >> 5) & 0x07);
if (!I2cWrite0(Bh1750_sensors[sensor_index].address, reg, Bh1750_sensors[sensor_index].bus)) {
return false;
}
reg = BH1750_MEASUREMENT_TIME_LOW | (Bh1750_sensors[sensor_index].mtreg & 0x1F);
if (!I2cWrite0(Bh1750_sensors[sensor_index].address, reg, Bh1750_sensors[sensor_index].bus)) {
return false;
}
return Bh1750SetResolution(sensor_index); return Bh1750SetResolution(sensor_index);
} }
bool Bh1750Read(uint32_t sensor_index) { bool Bh1750Read(uint32_t sensor_index) {
if (Bh1750_sensors[sensor_index].valid) { Bh1750_sensors[sensor_index].valid--; } if (Bh1750_sensors[sensor_index].valid) { Bh1750_sensors[sensor_index].valid--; }
/*
TwoWire& myWire = I2cGetWire(Bh1750_sensors[sensor_index].bus); TwoWire& myWire = I2cGetWire(Bh1750_sensors[sensor_index].bus);
if (2 != myWire.requestFrom(Bh1750_sensors[sensor_index].address, (uint8_t)2)) { return false; } if (2 != myWire.requestFrom(Bh1750_sensors[sensor_index].address, (uint8_t)2)) { return false; }
float illuminance = (myWire.read() << 8) | myWire.read(); float illuminance = (myWire.read() << 8) | myWire.read();
*/
uint8_t data[2];
if (I2cReadBuffer0(Bh1750_sensors[sensor_index].address, data, 2, Bh1750_sensors[sensor_index].bus)) {
return false;
}
float illuminance = (data[0] << 8) | data[1];
illuminance *= 57.5 / (float)Bh1750_sensors[sensor_index].mtreg; // Fix #16022 illuminance *= 57.5 / (float)Bh1750_sensors[sensor_index].mtreg; // Fix #16022
if (1 == Bh1750Resolution(sensor_index)) { if (1 == Bh1750Resolution(sensor_index)) {
illuminance /= 2; illuminance /= 2;

View File

@ -44,7 +44,7 @@ struct HYT {
bool HYT_Read(void) { bool HYT_Read(void) {
if (HYT.valid) { HYT.valid--; } if (HYT.valid) { HYT.valid--; }
/*
TwoWire& myWire = I2cGetWire(HYT.bus); TwoWire& myWire = I2cGetWire(HYT.bus);
if (&myWire == nullptr) { return false; } // No valid I2c bus if (&myWire == nullptr) { return false; } // No valid I2c bus
myWire.beginTransmission(HYT_ADDR); myWire.beginTransmission(HYT_ADDR);
@ -64,6 +64,18 @@ bool HYT_Read(void) {
HYT.humidity = ConvertHumidity(humidity); HYT.humidity = ConvertHumidity(humidity);
HYT.temperature = ConvertTemp(temperature); HYT.temperature = ConvertTemp(temperature);
} }
*/
uint8_t data[4];
if (!I2cReadBuffer(HYT_ADDR, -1, data, 4, HYT.bus)) {
// Convert the data to 14-bits
float humidity = ((((data[0] & 0x3F) * 256) + data[1]) * 100.0) / 16383.0;
int temp = ((data[2] * 256) + (data[3] & 0xFC)) / 4;
float temperature = (temp / 16384.0) * 165.0 - 40.0;
HYT.humidity = ConvertHumidity(humidity);
HYT.temperature = ConvertTemp(temperature);
}
if (isnan(HYT.temperature) || isnan(HYT.humidity)) { return false; } if (isnan(HYT.temperature) || isnan(HYT.humidity)) { return false; }
HYT.valid = SENSOR_MAX_MISS; HYT.valid = SENSOR_MAX_MISS;