Generic Si7021 Temp/Hum sensor library
Dependents: Turtle_RadioShuttle
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
Generated on Tue Jul 12 2022 17:59:48 by 1.7.2