Silicon Labs Si7021-A20 device driver: I2C Humidity and Temperature Sensor
SI7021.h@1:344923bddd4f, 2017-09-14 (annotated)
- Committer:
- ninensei
- Date:
- Thu Sep 14 00:16:02 2017 +0000
- Revision:
- 1:344923bddd4f
Converted to template so that I2C driver derivations can be used (I2C, SoftI2C, etc...); Changed filename to match class name.
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| ninensei | 1:344923bddd4f | 1 | /* mbed Microcontroller Library |
| ninensei | 1:344923bddd4f | 2 | * Copyright (c) 2017 AT&T, IIoT Foundry, Plano, TX, USA |
| ninensei | 1:344923bddd4f | 3 | * |
| ninensei | 1:344923bddd4f | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| ninensei | 1:344923bddd4f | 5 | * you may not use this file except in compliance with the License. |
| ninensei | 1:344923bddd4f | 6 | * You may obtain a copy of the License at |
| ninensei | 1:344923bddd4f | 7 | * |
| ninensei | 1:344923bddd4f | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| ninensei | 1:344923bddd4f | 9 | * |
| ninensei | 1:344923bddd4f | 10 | * Unless required by applicable law or agreed to in writing, software |
| ninensei | 1:344923bddd4f | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| ninensei | 1:344923bddd4f | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| ninensei | 1:344923bddd4f | 13 | * See the License for the specific language governing permissions and |
| ninensei | 1:344923bddd4f | 14 | * limitations under the License. |
| ninensei | 1:344923bddd4f | 15 | */ |
| ninensei | 1:344923bddd4f | 16 | |
| ninensei | 1:344923bddd4f | 17 | /** \addtogroup drivers */ |
| ninensei | 1:344923bddd4f | 18 | |
| ninensei | 1:344923bddd4f | 19 | /** Support for Silicon Labs SI7021 temperature and humidity sensor |
| ninensei | 1:344923bddd4f | 20 | * |
| ninensei | 1:344923bddd4f | 21 | * Example: |
| ninensei | 1:344923bddd4f | 22 | * @code |
| ninensei | 1:344923bddd4f | 23 | * |
| ninensei | 1:344923bddd4f | 24 | * #include "mbed.h" |
| ninensei | 1:344923bddd4f | 25 | * #include "SI7021.h" |
| ninensei | 1:344923bddd4f | 26 | * |
| ninensei | 1:344923bddd4f | 27 | * I2C i2c(I2C_SDA, I2C_SCL); |
| ninensei | 1:344923bddd4f | 28 | * SI7021<I2C> si7021(&i2c); |
| ninensei | 1:344923bddd4f | 29 | * |
| ninensei | 1:344923bddd4f | 30 | * int main() { |
| ninensei | 1:344923bddd4f | 31 | * si7021_measurements_t data; |
| ninensei | 1:344923bddd4f | 32 | * bool ok; |
| ninensei | 1:344923bddd4f | 33 | * |
| ninensei | 1:344923bddd4f | 34 | * ok = si7021->read(&data); |
| ninensei | 1:344923bddd4f | 35 | * |
| ninensei | 1:344923bddd4f | 36 | * if (ok) { |
| ninensei | 1:344923bddd4f | 37 | * printf("%%RelHum: %f\r\n", data.humidity_PR); |
| ninensei | 1:344923bddd4f | 38 | * printf("temp C/F: %f/%f\r\n", data.temp_C, data.temp_C * 9 / 5 + 32); |
| ninensei | 1:344923bddd4f | 39 | * } else { |
| ninensei | 1:344923bddd4f | 40 | * printf("si7021 error!\r\n"); |
| ninensei | 1:344923bddd4f | 41 | * } |
| ninensei | 1:344923bddd4f | 42 | * } |
| ninensei | 1:344923bddd4f | 43 | * @endcode |
| ninensei | 1:344923bddd4f | 44 | * @ingroup drivers |
| ninensei | 1:344923bddd4f | 45 | */ |
| ninensei | 1:344923bddd4f | 46 | |
| ninensei | 1:344923bddd4f | 47 | #pragma once |
| ninensei | 1:344923bddd4f | 48 | |
| ninensei | 1:344923bddd4f | 49 | #define SI7021A20_I2C_ADDR 0x80 |
| ninensei | 1:344923bddd4f | 50 | |
| ninensei | 1:344923bddd4f | 51 | #define SI7021A20_CMD_MEAS_RH_HMM 0xE5 |
| ninensei | 1:344923bddd4f | 52 | #define SI7021A20_CMD_MEAS_RH_NHMM 0xF5 |
| ninensei | 1:344923bddd4f | 53 | #define SI7021A20_CMD_MEAS_TEMP_HMM 0xE3 |
| ninensei | 1:344923bddd4f | 54 | #define SI7021A20_CMD_MEAS_TEMP_NHMM 0xF3 |
| ninensei | 1:344923bddd4f | 55 | #define SI7021A20_CMD_READ_TEMP 0xE0 |
| ninensei | 1:344923bddd4f | 56 | #define SI7021A20_CMD_RESET 0xFE |
| ninensei | 1:344923bddd4f | 57 | #define SI7021A20_CMD_WRITE_USER1 0xE6 |
| ninensei | 1:344923bddd4f | 58 | #define SI7021A20_CMD_WRITE_USER2 0xE7 |
| ninensei | 1:344923bddd4f | 59 | #define SI7021A20_CMD_WRITE_HEAT_CTRL 0x51 |
| ninensei | 1:344923bddd4f | 60 | #define SI7021A20_CMD_READ_HEAT_CTRL 0x11 |
| ninensei | 1:344923bddd4f | 61 | #define SI7021A20_CMD_READ_ID1 0xFA0F |
| ninensei | 1:344923bddd4f | 62 | #define SI7021A20_CMD_READ_ID2 0xFCC9 |
| ninensei | 1:344923bddd4f | 63 | #define SI7021A20_REGF_ID2_DEV_ID 0x15 |
| ninensei | 1:344923bddd4f | 64 | #define SI7021A20_CMD_READ_FW_REV 0x84B8 |
| ninensei | 1:344923bddd4f | 65 | |
| ninensei | 1:344923bddd4f | 66 | typedef struct { |
| ninensei | 1:344923bddd4f | 67 | float temp_C; |
| ninensei | 1:344923bddd4f | 68 | float humidity_PR; |
| ninensei | 1:344923bddd4f | 69 | } si7021_measurements_t; |
| ninensei | 1:344923bddd4f | 70 | |
| ninensei | 1:344923bddd4f | 71 | template <class T> |
| ninensei | 1:344923bddd4f | 72 | class SI7021 { |
| ninensei | 1:344923bddd4f | 73 | public: |
| ninensei | 1:344923bddd4f | 74 | /** |
| ninensei | 1:344923bddd4f | 75 | * Constructor |
| ninensei | 1:344923bddd4f | 76 | * |
| ninensei | 1:344923bddd4f | 77 | * @param i2c I2C class servicing the strip |
| ninensei | 1:344923bddd4f | 78 | */ |
| ninensei | 1:344923bddd4f | 79 | SI7021(T * i2c) : _i2c(i2c) {} |
| ninensei | 1:344923bddd4f | 80 | |
| ninensei | 1:344923bddd4f | 81 | /** |
| ninensei | 1:344923bddd4f | 82 | * Read temperature and humidity |
| ninensei | 1:344923bddd4f | 83 | * |
| ninensei | 1:344923bddd4f | 84 | * @param data points to struct to store measurements in. Stucture is |
| ninensei | 1:344923bddd4f | 85 | * valid only when function returns success indication. |
| ninensei | 1:344923bddd4f | 86 | * |
| ninensei | 1:344923bddd4f | 87 | * @returns true (success) or false (failure) |
| ninensei | 1:344923bddd4f | 88 | */ |
| ninensei | 1:344923bddd4f | 89 | bool read(si7021_measurements_t * data) { |
| ninensei | 1:344923bddd4f | 90 | bool ok; |
| ninensei | 1:344923bddd4f | 91 | union { |
| ninensei | 1:344923bddd4f | 92 | char cmd; |
| ninensei | 1:344923bddd4f | 93 | struct { |
| ninensei | 1:344923bddd4f | 94 | uint8_t meas_msb; |
| ninensei | 1:344923bddd4f | 95 | uint8_t meas_lsb; |
| ninensei | 1:344923bddd4f | 96 | }; |
| ninensei | 1:344923bddd4f | 97 | } buff; |
| ninensei | 1:344923bddd4f | 98 | |
| ninensei | 1:344923bddd4f | 99 | buff.cmd = SI7021A20_CMD_MEAS_RH_HMM; |
| ninensei | 1:344923bddd4f | 100 | ok = (_i2c_transfer(SI7021A20_I2C_ADDR, &buff, 1, 2)); |
| ninensei | 1:344923bddd4f | 101 | if (ok) { |
| ninensei | 1:344923bddd4f | 102 | // Humidity% = measurement * 125/65536 - 6 |
| ninensei | 1:344923bddd4f | 103 | int meas_raw = ((int)buff.meas_msb << 8) + buff.meas_lsb; |
| ninensei | 1:344923bddd4f | 104 | data->humidity_PR = (float)meas_raw * (125.0F/65536.0F) - 6.0F; |
| ninensei | 1:344923bddd4f | 105 | |
| ninensei | 1:344923bddd4f | 106 | buff.cmd = SI7021A20_CMD_READ_TEMP; |
| ninensei | 1:344923bddd4f | 107 | ok = _i2c_transfer(SI7021A20_I2C_ADDR, &buff, 1, 2); |
| ninensei | 1:344923bddd4f | 108 | } |
| ninensei | 1:344923bddd4f | 109 | if (ok) { |
| ninensei | 1:344923bddd4f | 110 | // TempC = measurement * 175.72/65536 - 46.85 |
| ninensei | 1:344923bddd4f | 111 | int meas_raw = ((int)buff.meas_msb << 8) + buff.meas_lsb; |
| ninensei | 1:344923bddd4f | 112 | data->temp_C = meas_raw * (175.72/65536.0) - 46.85; |
| ninensei | 1:344923bddd4f | 113 | } |
| ninensei | 1:344923bddd4f | 114 | return ok; |
| ninensei | 1:344923bddd4f | 115 | } |
| ninensei | 1:344923bddd4f | 116 | |
| ninensei | 1:344923bddd4f | 117 | protected: |
| ninensei | 1:344923bddd4f | 118 | |
| ninensei | 1:344923bddd4f | 119 | /** |
| ninensei | 1:344923bddd4f | 120 | * I2C read/write helper function |
| ninensei | 1:344923bddd4f | 121 | * |
| ninensei | 1:344923bddd4f | 122 | * @param address is the register to read/write |
| ninensei | 1:344923bddd4f | 123 | * @param buff holds the data to write and recieves the data to read |
| ninensei | 1:344923bddd4f | 124 | * @param writeSize is the number of bytes to write to register |
| ninensei | 1:344923bddd4f | 125 | * @param readSize is the number of bytes to retrieve from device |
| ninensei | 1:344923bddd4f | 126 | * |
| ninensei | 1:344923bddd4f | 127 | * @returns true (success) or false (failure) |
| ninensei | 1:344923bddd4f | 128 | */ |
| ninensei | 1:344923bddd4f | 129 | bool _i2c_transfer(int address, void * buff, size_t writeSize, size_t readSize) { |
| ninensei | 1:344923bddd4f | 130 | bool ok; |
| ninensei | 1:344923bddd4f | 131 | bool expect_response = (readSize != 0); |
| ninensei | 1:344923bddd4f | 132 | |
| ninensei | 1:344923bddd4f | 133 | ok = !_i2c->write(address, (char*)buff, writeSize, expect_response); |
| ninensei | 1:344923bddd4f | 134 | if (ok && expect_response) |
| ninensei | 1:344923bddd4f | 135 | ok = !_i2c->read(address, (char*)buff, readSize); |
| ninensei | 1:344923bddd4f | 136 | |
| ninensei | 1:344923bddd4f | 137 | return ok; |
| ninensei | 1:344923bddd4f | 138 | } |
| ninensei | 1:344923bddd4f | 139 | |
| ninensei | 1:344923bddd4f | 140 | |
| ninensei | 1:344923bddd4f | 141 | T *_i2c; |
| ninensei | 1:344923bddd4f | 142 | }; |
| ninensei | 1:344923bddd4f | 143 |