Steve Martin / libdev_si7021
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SI7021.h Source File

SI7021.h

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2017 AT&T, IIoT Foundry, Plano, TX, USA
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 /** \addtogroup drivers */
00018 
00019 /** Support for Silicon Labs SI7021 temperature and humidity sensor
00020  *
00021  * Example:
00022  * @code
00023  *
00024  * #include "mbed.h"
00025  * #include "SI7021.h"
00026  *
00027  * I2C          i2c(I2C_SDA, I2C_SCL);
00028  * SI7021<I2C>  si7021(&i2c);
00029  *
00030  * int main() {
00031  *     si7021_measurements_t  data;
00032  *     bool                   ok;
00033  *
00034  *     ok = si7021->read(&data);
00035  *           
00036  *     if (ok) {
00037  *         printf("%%RelHum: %f\r\n", data.humidity_PR);
00038  *         printf("temp C/F: %f/%f\r\n", data.temp_C, data.temp_C * 9 / 5 + 32);
00039  *     } else {
00040  *         printf("si7021 error!\r\n");
00041  *     }
00042  * }
00043  * @endcode
00044  * @ingroup drivers
00045  */
00046 
00047 #pragma once
00048 
00049 #define SI7021A20_I2C_ADDR              0x80
00050 
00051 #define SI7021A20_CMD_MEAS_RH_HMM       0xE5
00052 #define SI7021A20_CMD_MEAS_RH_NHMM      0xF5
00053 #define SI7021A20_CMD_MEAS_TEMP_HMM     0xE3
00054 #define SI7021A20_CMD_MEAS_TEMP_NHMM    0xF3
00055 #define SI7021A20_CMD_READ_TEMP         0xE0
00056 #define SI7021A20_CMD_RESET             0xFE
00057 #define SI7021A20_CMD_WRITE_USER1       0xE6
00058 #define SI7021A20_CMD_WRITE_USER2       0xE7
00059 #define SI7021A20_CMD_WRITE_HEAT_CTRL   0x51
00060 #define SI7021A20_CMD_READ_HEAT_CTRL    0x11
00061 #define SI7021A20_CMD_READ_ID1          0xFA0F
00062 #define SI7021A20_CMD_READ_ID2          0xFCC9
00063 #define SI7021A20_REGF_ID2_DEV_ID               0x15
00064 #define SI7021A20_CMD_READ_FW_REV       0x84B8
00065 
00066 typedef struct {
00067     float       temp_C;
00068     float       humidity_PR;
00069 } si7021_measurements_t;
00070 
00071 template <class T>
00072 class SI7021 {
00073  public:
00074     /**
00075     * Constructor
00076     *
00077     * @param i2c I2C class servicing the strip
00078     */
00079     SI7021(T * i2c) : _i2c(i2c) {}
00080 
00081     /**
00082     * Read temperature and humidity
00083     *
00084     * @param data points to struct to store measurements in.  Stucture is
00085     *      valid only when function returns success indication.
00086     *
00087     * @returns true (success) or false (failure)
00088     */
00089     bool read(si7021_measurements_t * data) {
00090         bool    ok;
00091         union {
00092             char    cmd;
00093             struct {
00094                 uint8_t  meas_msb;
00095                 uint8_t  meas_lsb;
00096             };
00097         } buff;
00098         
00099         buff.cmd = SI7021A20_CMD_MEAS_RH_HMM;
00100         ok = (_i2c_transfer(SI7021A20_I2C_ADDR, &buff, 1, 2));
00101         if (ok) {
00102             // Humidity% = measurement * 125/65536 - 6
00103             int meas_raw        = ((int)buff.meas_msb << 8) + buff.meas_lsb;
00104             data->humidity_PR   = (float)meas_raw * (125.0F/65536.0F) - 6.0F;
00105         
00106             buff.cmd = SI7021A20_CMD_READ_TEMP;
00107             ok = _i2c_transfer(SI7021A20_I2C_ADDR, &buff, 1, 2);
00108         }
00109         if (ok) {
00110             // TempC = measurement * 175.72/65536 - 46.85
00111             int meas_raw    = ((int)buff.meas_msb << 8) + buff.meas_lsb;
00112             data->temp_C    = meas_raw * (175.72/65536.0) - 46.85;
00113          }
00114         return ok;
00115     }    
00116 
00117  protected:
00118 
00119     /**
00120     * I2C read/write helper function
00121     *
00122     * @param address is the register to read/write
00123     * @param buff holds the data to write and recieves the data to read
00124     * @param writeSize is the number of bytes to write to register
00125     * @param readSize is the number of bytes to retrieve from device
00126     *
00127     * @returns true (success) or false (failure)
00128     */
00129     bool _i2c_transfer(int address, void * buff, size_t writeSize, size_t readSize) {
00130         bool ok;
00131         bool expect_response = (readSize != 0);
00132     
00133         ok = !_i2c->write(address, (char*)buff, writeSize, expect_response);
00134         if (ok && expect_response)
00135             ok = !_i2c->read(address, (char*)buff, readSize);
00136     
00137         return ok;
00138     }
00139     
00140 
00141     T  *_i2c;
00142 };
00143