From ff891426ab6940c927697eeca0385a9387d0309c Mon Sep 17 00:00:00 2001 From: Pim van Pelt Date: Mon, 2 Apr 2018 21:11:18 +0200 Subject: [PATCH] Finish Si7021 Based on datasheet: https://cdn.instructables.com/ORIG/FOR/G7DY/IHXRC1XG/FORG7DYIHXRC1XG.pdf - Add CRC8 (poly 0x31, init 0x00) - Add Temperature and Humidity data polling. --- src/mgos_si7021.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/mgos_si7021.c b/src/mgos_si7021.c index 2c54a0a..0e257bd 100644 --- a/src/mgos_si7021.c +++ b/src/mgos_si7021.c @@ -19,6 +19,19 @@ #include "mgos_i2c.h" // Private functions follow +static uint8_t crc8(const uint8_t *data, int len) +{ + const uint8_t POLYNOMIAL=0x31; + uint8_t crc=0x00; + + for (int j=len; j; --j ) { + crc ^= *data++; + for ( int i = 8; i; --i ) + crc = ( crc & 0x80 ) ? (crc << 1) ^ POLYNOMIAL : (crc << 1); + } + return crc; +} + // Private functions end // Public functions follow @@ -63,6 +76,49 @@ bool mgos_si7021_read(struct mgos_si7021 *sensor) { } // Read out sensor data here // + uint8_t cmd = MGOS_SI7021_MEASRH_NOHOLD_CMD; + uint8_t data[3]; + + if (!mgos_i2c_write(sensor->i2c, sensor->i2caddr, &cmd, 1, false)) { + LOG(LL_ERROR, ("Could not write command")); + return false; + } + if (!mgos_i2c_read(sensor->i2c, sensor->i2caddr, data, 3, false)) { + LOG(LL_ERROR, ("Could not read command")); + return false; + } + if (data[2] != crc8(&data[0], 2)) { + LOG(LL_ERROR, ("CRC error on humidity data")); + return false; + } + + uint16_t hum = (data[0]<<8)+data[1]; + float humidity = hum; + humidity *= 125; + humidity /= 65536; + humidity -= 6; + sensor->humidity = humidity; + + cmd=MGOS_SI7021_MEASTEMP_NOHOLD_CMD; + if (!mgos_i2c_write(sensor->i2c, sensor->i2caddr, &cmd, 1, false)) { + LOG(LL_ERROR, ("Could not write command")); + return false; + } + if (!mgos_i2c_read(sensor->i2c, sensor->i2caddr, data, 3, false)) { + LOG(LL_ERROR, ("Could not read command")); + return false; + } + if (data[2] != crc8(&data[0], 2)) { + LOG(LL_ERROR, ("CRC error on temperature data")); + return false; + } + + uint16_t temp = (data[0]<<8)+data[1]; + float temperature = temp; + temperature *= 175.72; + temperature /= 65536; + temperature -= 46.85; + sensor->temperature = temperature; LOG(LL_DEBUG, ("temperature=%.2fC humidity=%.1f%%", sensor->temperature, sensor->humidity)); sensor->last_read_time=now;