Generic Si7021 Temp/Hum sensor library

Dependents:   Turtle_RadioShuttle

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers HELIOS_Si7021.cpp Source File

HELIOS_Si7021.cpp

00001 /*
00002  * Copyright (c) 2019 Helmut Tschemernjak
00003  * 30826 Garbsen (Hannover) Germany
00004  * Licensed under the Apache License, Version 2.0);
00005  */
00006 
00007 #include "main.h"
00008 
00009 #ifdef FEATURE_SI7021
00010 
00011 #include <HELIOS_Si7021.h>
00012 
00013 
00014 #define SI7021_MEASRH_HOLD_CMD      0xE5 // Measure Relative Humidity, Hold Master Mode
00015 #define SI7021_MEASRH_NOHOLD_CMD    0xF5 // Measure Relative Humidity, No Hold Master Mode
00016 #define SI7021_MEASTEMP_HOLD_CMD    0xE3 // Measure Temperature, Hold Master Mode
00017 #define SI7021_MEASTEMP_NOHOLD_CMD  0xF3 // Measure Temperature, No Hold Master Mode
00018 #define SI7021_READPREVTEMP_CMD     0xE0 // Read Temperature Value from Previous RH Measurement
00019 #define SI7021_RESET_CMD            0xFE
00020 #define SI7021_WRITERHT_REG_CMD     0xE6 // Write RH/T User Register 1
00021 #define SI7021_READRHT_REG_CMD      0xE7 // Read RH/T User Register 1
00022 #define SI7021_WRITEHEATER_REG_CMD  0x51 // Write Heater Control Register
00023 #define SI7021_READHEATER_REG_CMD   0x11 // Read Heater Control Register
00024 #define SI7021_ID1_CMD              0xFA0F // Read Electronic ID 1st Byte
00025 #define SI7021_ID2_CMD              0xFCC9 // Read Electronic ID 2nd Byte
00026 #define SI7021_FIRMVERS_CMD         0x84B8 // Read Firmware Revision
00027 
00028 #define SI7021_REV_1                0xff
00029 #define SI7021_REV_2                0x20
00030 
00031 
00032 
00033 /**************************************************************************/
00034 
00035 HELIOS_Si7021::HELIOS_Si7021(PinName sda, PinName scl)
00036 {
00037     sernum_a = sernum_b = 0;
00038     _model = SI_7021;
00039     _revision = 0;
00040     _foundDevice = false;
00041     _i2c = new I2C(sda, scl);
00042     
00043     reset();
00044     
00045     _data[0] = SI7021_READRHT_REG_CMD;
00046     _i2c->write(_i2caddr, _data, 1);
00047     _i2c->read(_i2caddr, _data, 1);
00048     
00049     if (_data[0] != 0x3A)
00050         return;
00051     _foundDevice = true;
00052     
00053     readSerialNumber();
00054     _readRevision();
00055 }
00056 
00057 
00058 HELIOS_Si7021::~HELIOS_Si7021(void)
00059 {
00060     if (_i2c)
00061         delete _i2c;
00062 }
00063 
00064 
00065 void HELIOS_Si7021::reset(void)
00066 {
00067 
00068     _data[0] = SI7021_RESET_CMD;
00069     _i2c->write(_i2caddr, _data, 1);
00070      wait_ms(50);
00071 }
00072 
00073 
00074 void HELIOS_Si7021::readSerialNumber(void)
00075 {
00076 
00077     if (!_foundDevice)
00078         return;
00079 
00080     _data[0] = SI7021_ID1_CMD >> 8;
00081     _data[1] = SI7021_ID1_CMD & 0xFF;
00082     _i2c->write(_i2caddr, _data, 2);
00083 
00084     _i2c->read(_i2caddr, _data, 8);
00085     sernum_a = _data[0];
00086     sernum_a <<= 8;
00087     sernum_a |= _data[2];
00088     sernum_a <<= 8;
00089     sernum_a |= _data[4];
00090     sernum_a <<= 8;
00091     sernum_a |= _data[6];
00092     
00093 
00094 
00095     _data[0] = SI7021_ID2_CMD >> 8;
00096     _data[1] = SI7021_ID2_CMD & 0xFF;
00097     _i2c->write(_i2caddr, _data, 2);
00098 
00099     _i2c->read(_i2caddr, _data, 8);
00100     sernum_b = _data[0];
00101     sernum_b <<= 8;
00102     sernum_b |= _data[2];
00103     sernum_b <<= 8;
00104     sernum_b |= _data[4];
00105     sernum_b <<= 8;
00106     sernum_b |= _data[6];
00107     
00108     
00109     switch(sernum_b >> 24) {
00110         case 0:
00111         case 0xff:
00112             _model = SI_Engineering_Samples;
00113             break;
00114         case 0x0D:
00115             _model = SI_7013;
00116             break;
00117         case 0x14:
00118             _model = SI_7020;
00119             break;
00120         case 0x15:
00121             _model = SI_7021;
00122             break;
00123         default:
00124             _model = SI_unkown;
00125     }
00126 }
00127 
00128 
00129 void HELIOS_Si7021::_readRevision(void)
00130 {
00131     if (!_foundDevice)
00132         return;
00133 
00134     _revision = 0;
00135 
00136     _data[0] = SI7021_FIRMVERS_CMD >> 8;
00137     _data[1] = SI7021_FIRMVERS_CMD & 0xFF;
00138     _i2c->write(_i2caddr, _data, 2);
00139 
00140     _i2c->read(_i2caddr, _data, 2);
00141     if (_data[0] == SI7021_REV_1) {
00142           _revision = 1;
00143     } else if (_data[0] == SI7021_REV_2) {
00144           _revision = 2;
00145     }
00146 }
00147 
00148 
00149 float HELIOS_Si7021::readTemperature(void) {
00150     if (!_foundDevice)
00151         return NAN;
00152 
00153     _data[0] = SI7021_MEASTEMP_NOHOLD_CMD;
00154     _i2c->write(_i2caddr, _data, 1);
00155 
00156     Timer t;
00157     t.start();
00158     while(_i2c->read(_i2caddr, _data, 3) != 0) {
00159         if (t.read_ms() > _TRANSACTION_TIMEOUT)
00160             return NAN;
00161         wait_ms(6); // 1/2 typical sample processing time
00162     }
00163 
00164     float temperature = _data[0] << 8 | _data[1];
00165     temperature *= 175.72;
00166     temperature /= 65536;
00167     temperature -= 46.85;
00168     
00169     return temperature;
00170 }
00171 
00172 
00173 float HELIOS_Si7021::readHumidity(void)
00174 {
00175     if (!_foundDevice)
00176         return NAN;
00177 
00178     _data[0] = SI7021_MEASRH_NOHOLD_CMD;
00179     _i2c->write(_i2caddr, _data, 1);
00180     
00181     Timer t;
00182     t.start();
00183     while(_i2c->read(_i2caddr, _data, 3) != 0) {
00184         if (t.read_ms() > _TRANSACTION_TIMEOUT)
00185             return NAN;
00186         wait_ms(6); // 1/2 typical sample processing time
00187     }
00188 
00189     float humidity = (_data[0] << 8 | _data[1]) * 125;
00190     humidity /= 65536;
00191     humidity -= 6;
00192 
00193     return humidity;
00194 }
00195 
00196 
00197 const char *HELIOS_Si7021::getModelName(void)
00198 {
00199     switch(_model) {
00200         case SI_Engineering_Samples:
00201             return "SI engineering samples";
00202         case SI_7013:
00203             return "Si7013";
00204         case SI_7020:
00205             return "Si7020";
00206         case SI_7021:
00207             return "Si7021";
00208         case SI_unkown:
00209         default:
00210             return "unknown";
00211     }
00212 }
00213 
00214 
00215 HELIOS_Si7021::sensorType HELIOS_Si7021::getModel(void)
00216 {
00217     return _model;
00218 }
00219 
00220 #endif // FEATURE_SI7021
00221