Silicon Labs Si7021-A20 device driver: I2C Humidity and Temperature Sensor

Files at this revision

API Documentation at this revision

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

SI7021.h Show annotated file Show diff for this revision Revisions of this file
si7021.cpp Show diff for this revision Revisions of this file
si7021.h Show diff for this revision Revisions of this file
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