Silicon Labs Si7021-A20 device driver: I2C Humidity and Temperature Sensor
Revision 1:344923bddd4f, committed 2017-09-14
- Comitter:
- ninensei
- Date:
- Thu Sep 14 00:16:02 2017 +0000
- Parent:
- 0:9909c9c7d326
- Commit message:
- Converted to template so that I2C driver derivations can be used (I2C, SoftI2C, etc...); Changed filename to match class name.
Changed in this revision
diff -r 9909c9c7d326 -r 344923bddd4f SI7021.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SI7021.h Thu Sep 14 00:16:02 2017 +0000 @@ -0,0 +1,143 @@ +/* mbed Microcontroller Library + * Copyright (c) 2017 AT&T, IIoT Foundry, Plano, TX, USA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** \addtogroup drivers */ + +/** Support for Silicon Labs SI7021 temperature and humidity sensor + * + * Example: + * @code + * + * #include "mbed.h" + * #include "SI7021.h" + * + * I2C i2c(I2C_SDA, I2C_SCL); + * SI7021<I2C> si7021(&i2c); + * + * int main() { + * si7021_measurements_t data; + * bool ok; + * + * ok = si7021->read(&data); + * + * if (ok) { + * printf("%%RelHum: %f\r\n", data.humidity_PR); + * printf("temp C/F: %f/%f\r\n", data.temp_C, data.temp_C * 9 / 5 + 32); + * } else { + * printf("si7021 error!\r\n"); + * } + * } + * @endcode + * @ingroup drivers + */ + +#pragma once + +#define SI7021A20_I2C_ADDR 0x80 + +#define SI7021A20_CMD_MEAS_RH_HMM 0xE5 +#define SI7021A20_CMD_MEAS_RH_NHMM 0xF5 +#define SI7021A20_CMD_MEAS_TEMP_HMM 0xE3 +#define SI7021A20_CMD_MEAS_TEMP_NHMM 0xF3 +#define SI7021A20_CMD_READ_TEMP 0xE0 +#define SI7021A20_CMD_RESET 0xFE +#define SI7021A20_CMD_WRITE_USER1 0xE6 +#define SI7021A20_CMD_WRITE_USER2 0xE7 +#define SI7021A20_CMD_WRITE_HEAT_CTRL 0x51 +#define SI7021A20_CMD_READ_HEAT_CTRL 0x11 +#define SI7021A20_CMD_READ_ID1 0xFA0F +#define SI7021A20_CMD_READ_ID2 0xFCC9 +#define SI7021A20_REGF_ID2_DEV_ID 0x15 +#define SI7021A20_CMD_READ_FW_REV 0x84B8 + +typedef struct { + float temp_C; + float humidity_PR; +} si7021_measurements_t; + +template <class T> +class SI7021 { + public: + /** + * Constructor + * + * @param i2c I2C class servicing the strip + */ + SI7021(T * i2c) : _i2c(i2c) {} + + /** + * Read temperature and humidity + * + * @param data points to struct to store measurements in. Stucture is + * valid only when function returns success indication. + * + * @returns true (success) or false (failure) + */ + bool read(si7021_measurements_t * data) { + bool ok; + union { + char cmd; + struct { + uint8_t meas_msb; + uint8_t meas_lsb; + }; + } buff; + + buff.cmd = SI7021A20_CMD_MEAS_RH_HMM; + ok = (_i2c_transfer(SI7021A20_I2C_ADDR, &buff, 1, 2)); + if (ok) { + // Humidity% = measurement * 125/65536 - 6 + int meas_raw = ((int)buff.meas_msb << 8) + buff.meas_lsb; + data->humidity_PR = (float)meas_raw * (125.0F/65536.0F) - 6.0F; + + buff.cmd = SI7021A20_CMD_READ_TEMP; + ok = _i2c_transfer(SI7021A20_I2C_ADDR, &buff, 1, 2); + } + if (ok) { + // TempC = measurement * 175.72/65536 - 46.85 + int meas_raw = ((int)buff.meas_msb << 8) + buff.meas_lsb; + data->temp_C = meas_raw * (175.72/65536.0) - 46.85; + } + return ok; + } + + protected: + + /** + * I2C read/write helper function + * + * @param address is the register to read/write + * @param buff holds the data to write and recieves the data to read + * @param writeSize is the number of bytes to write to register + * @param readSize is the number of bytes to retrieve from device + * + * @returns true (success) or false (failure) + */ + bool _i2c_transfer(int address, void * buff, size_t writeSize, size_t readSize) { + bool ok; + bool expect_response = (readSize != 0); + + ok = !_i2c->write(address, (char*)buff, writeSize, expect_response); + if (ok && expect_response) + ok = !_i2c->read(address, (char*)buff, readSize); + + return ok; + } + + + T *_i2c; +}; +
diff -r 9909c9c7d326 -r 344923bddd4f si7021.cpp --- a/si7021.cpp Tue Sep 12 17:17:03 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -#include "si7021.h" - -#define SI7021A20_I2C_ADDR 0x80 - -#define SI7021A20_CMD_MEAS_RH_HMM 0xE5 -#define SI7021A20_CMD_MEAS_RH_NHMM 0xF5 -#define SI7021A20_CMD_MEAS_TEMP_HMM 0xE3 -#define SI7021A20_CMD_MEAS_TEMP_NHMM 0xF3 -#define SI7021A20_CMD_READ_TEMP 0xE0 -#define SI7021A20_CMD_RESET 0xFE -#define SI7021A20_CMD_WRITE_USER1 0xE6 -#define SI7021A20_CMD_WRITE_USER2 0xE7 -#define SI7021A20_CMD_WRITE_HEAT_CTRL 0x51 -#define SI7021A20_CMD_READ_HEAT_CTRL 0x11 -#define SI7021A20_CMD_READ_ID1 0xFA0F -#define SI7021A20_CMD_READ_ID2 0xFCC9 -#define SI7021A20_REGF_ID2_DEV_ID 0x15 -#define SI7021A20_CMD_READ_FW_REV 0x84B8 - -bool SI7021::_i2c_transfer(int address, void * buff, size_t write_size, size_t read_size) -{ - bool ok; - bool expect_response = (read_size != 0); - - ok = !_i2c->write(address, (char*)buff, write_size, expect_response); - if (ok && expect_response) - ok = !_i2c->read(address, (char*)buff, read_size); - - return ok; -} - -/* -bool SI7021::_validate(void) -{ - bool ok; - uint8_t buff[4]; - - buff[0] = (uint8_t)(SI7021A20_CMD_READ_ID2 >> 8); - buff[1] = (uint8_t)(SI7021A20_CMD_READ_ID2); - - ok = (i2c_transfer(SI7021A20_I2C_ADDR, buff, 2, 1)) && - (SI7021A20_REGF_ID2_DEV_ID == buff[0]); - - return ok; -} -*/ - -bool SI7021::read(si7021_measurements_t * data) { - bool ok; - union { - char cmd; - struct { - uint8_t meas_msb; - uint8_t meas_lsb; - }; - } buff; - - buff.cmd = SI7021A20_CMD_MEAS_RH_HMM; - ok = (_i2c_transfer(SI7021A20_I2C_ADDR, &buff, 1, 2)); - if (ok) { - // Humidity% = measurement * 125/65536 - 6 - int meas_raw = ((int)buff.meas_msb << 8) + buff.meas_lsb; - data->humidity_PR = (float)meas_raw * (125.0F/65536.0F) - 6.0F; -// data->humidity = meas_raw / 2 - 1573; -// data->humidity_norm = 262; -// printf("<humidityH/r = %f/%d>", Humidity, meas_raw); - - buff.cmd = SI7021A20_CMD_READ_TEMP; - ok = _i2c_transfer(SI7021A20_I2C_ADDR, &buff, 1, 2); - } - if (ok) { - // TempC = measurement * 175.72/65536 - 46.85 - int meas_raw = ((int)buff.meas_msb << 8) + buff.meas_lsb; - data->temp_C = meas_raw * (175.72/65536.0) - 46.85; -// data->temp = meas_raw / 2 - 8736; -// data->temp_norm = 186; -// printf("<tempC/F/r = %f/%f/%d>", Temp, Temp * 9 / 5 + 32, meas_raw); - } - return ok; -}
diff -r 9909c9c7d326 -r 344923bddd4f si7021.h --- a/si7021.h Tue Sep 12 17:17:03 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -#include "mbed.h" - -#ifndef SI7021_H -#define SI7021_H - -typedef struct { - float temp_C; - float humidity_PR; -// int16_t temp; -// int16_t temp_norm; -// int16_t humidity; -// int16_t humidity_norm; -} si7021_measurements_t; - -class SI7021 { - public: - /** - * Constructor - * - * @param i2c I2C class servicing the strip - */ - SI7021(I2C * i2c) : _i2c(i2c) {} - - /** - * Read temperature and humidity - * - * @param data points to struct to store measurements in. Stucture is - * valid only when function returns success indication. - * - * @returns true (success) or false (failure) - */ - bool read(si7021_measurements_t * data); - - protected: - - /** - * I2C read/write helper function - * - * @param address is the register to read/write - * @param buff holds the data to write and recieves the data to read - * @param writeSize is the number of bytes to write to register - * @param readSize is the number of bytes to retrieve from device - * - * @returns true (success) or false (failure) - */ - bool _i2c_transfer(int address, void * buff, size_t writeSize, size_t readSize); - - /** - * - bool _validate(void) - */ - - I2C *_i2c; -}; - -#endif //SI7021_H