![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Internet of Greens. Mini automated greenhouse, with an internet of sensors.
Dependencies: HC_SR04_Ultrasonic_Library PixelArrayBuffer Servo TSL2561 mbed-rtos mbed
Fork of Final_project by
th02.cpp
00001 // ********************************************************************************** 00002 // Driver definition for HopeRF TH02 temperature and humidity sensor 00003 // ********************************************************************************** 00004 // Creative Commons Attrib Share-Alike License 00005 // You are free to use/extend this library but please abide with the CC-BY-SA license: 00006 // http://creativecommons.org/licenses/by-sa/4.0/ 00007 // 00008 // For any explanation see TH02 sensor information at 00009 // http://www.hoperf.com/sensor/app/TH02.htm 00010 // 00011 // Code based on following datasheet 00012 // http://www.hoperf.com/upload/sensor/TH02_V1.1.pdf 00013 // 00014 // Written by Charles-Henri Hallard (http://hallard.me) 00015 // 00016 // History : V1.00 2014-07-14 - First release 00017 // V1.10 2015-04-13 - changed to Wire library instead of m_I2C 00018 // 00019 // All text above must be included in any redistribution. 00020 // 00021 // ********************************************************************************** 00022 #include "th02.h" 00023 #include "mbed.h" 00024 #include "math.h" 00025 00026 // Class Constructor 00027 00028 TH02::TH02(PinName sda,PinName scl,uint8_t address): m_I2C(sda, scl) 00029 { 00030 _address = address; // m_I2C Module Address 00031 _last_temp = TH02_UNINITIALIZED_TEMP; // Last measured temperature (for linearization) 00032 _last_rh = TH02_UNINITIALIZED_RH; // Last measured RH 00033 } 00034 00035 TH02::~TH02() 00036 { 00037 00038 } 00039 00040 00041 00042 /* ====================================================================== 00043 Function: writeCommand 00044 Purpose : write the "register address" value on m_I2C bus 00045 Input : register address 00046 true if we need to release the bus after (default yes) 00047 Output : Arduino Wire library return code (0 if ok) 00048 Comments: 00049 ====================================================================== */ 00050 uint8_t TH02::writeCommand(uint8_t command, bool release) 00051 {int iError; 00052 (void) m_I2C.start(); 00053 //Wire.beginTransmission(_address); 00054 iError=m_I2C.write(_address);// send adress of i2c slave 00055 00056 if (iError==1) 00057 { 00058 // Wire.write(command) ; 00059 iError= m_I2C.write(command); 00060 } 00061 if (release==true) 00062 { m_I2C.stop();// return stop error code 00063 } 00064 if (iError==1) iError=0;// ack received 00065 else iError=1;// no ack 00066 return iError; 00067 } 00068 00069 /* ====================================================================== 00070 Function: writeRegister 00071 Purpose : write a value on the designed register address on m_I2C bus 00072 Input : register address 00073 value to write 00074 Output : Arduino Wire library return code (0 if ok) 00075 Comments: 00076 ====================================================================== */ 00077 uint8_t TH02::writeRegister(uint8_t reg, uint8_t value) 00078 { int iError; 00079 00080 bool ret = false; 00081 00082 //Wire.beginTransmission(_address); 00083 (void) m_I2C.start(); 00084 iError=m_I2C.write(_address);// send adress of i2c slave 00085 // Wire.write(reg); 00086 if (iError==1){ 00087 00088 iError= m_I2C.write(reg); 00089 00090 // Wire.write(value); 00091 (void) m_I2C.write(value); 00092 } 00093 // return Wire.endTransmission(); 00094 m_I2C.stop();// return stop error code 00095 if (iError==1) iError=0;// ack received 00096 else iError=1;// no ack 00097 return iError; 00098 } 00099 00100 /* ====================================================================== 00101 Function: readRegister 00102 Purpose : read a register address value on m_I2C bus 00103 Input : register address 00104 pointer where the return value will be filled 00105 Output : Arduino Wire library return code (0 if ok) 00106 Comments: 00107 ====================================================================== */ 00108 uint8_t TH02::readRegister(uint8_t reg, uint8_t * value) 00109 { 00110 uint8_t ret ; 00111 int iAck,iRedVal,iError; 00112 // Send a register reading command 00113 // but DO NOT release the m_I2C bus 00114 // (void) m_I2C.start(); 00115 // iError=m_I2C.write(_address);// send adress of i2c slave 00116 00117 //if (iError==1) 00118 00119 ret = writeCommand(reg, false); 00120 00121 if ( ret == 0) //if command ok 00122 { 00123 // Wire.requestFrom( (uint8_t) _address, (uint8_t) 1); 00124 (void) m_I2C.start(); 00125 iError=m_I2C.write(_address+0x01);// send adress of i2c slave in read mode 00126 iRedVal=m_I2C.read(0);//send non ack 00127 // if (Wire.available() != 1) 00128 /*if (iAck != 1) 00129 00130 // Other error as Wire library 00131 ret = 4; 00132 else 00133 // grab the value*/ 00134 *value = iRedVal; // return Red value by ref 00135 00136 //} 00137 00138 // Ok now we have finished 00139 // Wire.endTransmission(); 00140 00141 } 00142 (void) m_I2C.stop();// return stop error code 00143 return ret; 00144 } 00145 00146 /* ====================================================================== 00147 Function: getId 00148 Purpose : Get device ID register 00149 Input : pointer where the return value will be filled 00150 Output : Arduino Wire library return code (0 if ok) 00151 Comments: - 00152 ====================================================================== */ 00153 uint8_t TH02::getId(uint8_t * pvalue) 00154 { 00155 return (readRegister(TH02_ID, pvalue)); 00156 } 00157 00158 /* ====================================================================== 00159 Function: getStatus 00160 Purpose : Get device status register 00161 Input : pointer where the return value will be filled 00162 Output : Arduino Wire library return code (0 if ok) 00163 Comments: 00164 ====================================================================== */ 00165 uint8_t TH02::getStatus(uint8_t * pvalue) 00166 { 00167 return (readRegister(TH02_STATUS, pvalue)); 00168 } 00169 00170 /* ====================================================================== 00171 Function: isConverting 00172 Purpose : Indicate if a temperature or humidity conversion is in progress 00173 Input : - 00174 Output : true if conversion in progress false otherwise 00175 Comments: 00176 ====================================================================== */ 00177 bool TH02::isConverting(void) 00178 { 00179 uint8_t status; 00180 // Get status and check RDY bit 00181 if ( getStatus(&status) == 0) 00182 { 00183 //{ printf("\n lecture status %x",status); 00184 if ( (status & TH02_STATUS_RDY) ==1 ) 00185 return true; 00186 } 00187 return false; 00188 } 00189 00190 /* ====================================================================== 00191 Function: getConfig 00192 Purpose : Get device configuration register 00193 Input : pointer where the return value will be filled 00194 Output : Arduino Wire library return code (0 if ok) 00195 Comments: 00196 ====================================================================== */ 00197 uint8_t TH02::getConfig(uint8_t * pvalue) 00198 { 00199 return (readRegister(TH02_CONFIG, pvalue)); 00200 } 00201 00202 /* ====================================================================== 00203 Function: setConfig 00204 Purpose : Set device configuration register 00205 Input : value to set 00206 Output : true if succeded, false otherwise 00207 Comments: 00208 ====================================================================== */ 00209 uint8_t TH02::setConfig(uint8_t config) 00210 { 00211 return (writeRegister(TH02_CONFIG, config)); 00212 } 00213 00214 /* ====================================================================== 00215 Function: startTempConv 00216 Purpose : Start a temperature conversion 00217 Input : - fastmode true to enable fast conversion 00218 - heater true to enable heater 00219 Output : true if succeded, false otherwise 00220 Comments: if heater enabled, it will not be auto disabled 00221 ====================================================================== */ 00222 uint8_t TH02::startTempConv(bool fastmode, bool heater) 00223 { 00224 // init configuration register to start and temperature 00225 uint8_t config = TH02_CONFIG_START | TH02_CONFIG_TEMP; 00226 00227 // set fast mode and heater if asked 00228 if (fastmode) config |= TH02_CONFIG_FAST; 00229 if (heater) config |= TH02_CONFIG_HEAT; 00230 00231 // write to configuration register 00232 return ( setConfig( config ) ); 00233 } 00234 00235 /* ====================================================================== 00236 Function: startRHConv 00237 Purpose : Start a relative humidity conversion 00238 Input : - fastmode true to enable fast conversion 00239 - heater true to enable heater 00240 Output : true if succeded, false otherwise 00241 Comments: if heater enabled, it will not be auto disabled 00242 ====================================================================== */ 00243 uint8_t TH02::startRHConv(bool fastmode, bool heater) 00244 { 00245 // init configuration register to start and no temperature (so RH) 00246 uint8_t config = TH02_CONFIG_START; 00247 00248 // set fast mode and heater if asked 00249 if (fastmode) config |= TH02_CONFIG_FAST; 00250 if (heater) config |= TH02_CONFIG_HEAT; 00251 00252 // write to configuration register 00253 return ( setConfig( config ) ); 00254 } 00255 00256 /* ====================================================================== 00257 Function: waitEndConversion 00258 Purpose : wait for a temperature or RH conversion is done 00259 Input : 00260 Output : delay in ms the process took. 00261 Comments: if return >= TH02_CONVERSION_TIME_OUT, time out occured 00262 ====================================================================== */ 00263 uint8_t TH02::waitEndConversion(void) 00264 { 00265 // okay this is basic approach not so accurate 00266 // but avoid using long and millis() 00267 uint8_t time_out = 0; 00268 00269 // loop until conversion done or duration >= time out 00270 while (isConverting() && time_out <= TH02_CONVERSION_TIME_OUT ) 00271 { 00272 ++time_out; 00273 wait_ms(1); 00274 } 00275 00276 // return approx time of conversion 00277 return (time_out); 00278 } 00279 00280 /* ====================================================================== 00281 Function: roundInt 00282 Purpose : round a float value to int 00283 Input : float value 00284 Output : int value rounded 00285 Comments: 00286 ====================================================================== */ 00287 int16_t TH02::roundInt(float value) 00288 { 00289 00290 // check positive number and do round 00291 if (value >= 0.0f) 00292 value = floor(value + 0.5f); 00293 else 00294 value = ceil(value - 0.5f); 00295 00296 // return int value 00297 return (static_cast<int16_t>(value)); 00298 } 00299 00300 /* to avoid math library may I need to test something 00301 like that 00302 float TH02::showDecimals(float x, int numDecimals) 00303 { 00304 int y=x; 00305 double z=x-y; 00306 double m=pow(10,numDecimals); 00307 double q=z*m; 00308 double r=round(q); 00309 return static_cast<double>(y)+(1.0/m)*r; 00310 } 00311 */ 00312 00313 /* ====================================================================== 00314 Function: getConversionValue 00315 Purpose : return the last converted value to int * 10 to have 1 digit prec. 00316 Input : float value 00317 Output : value rounded but multiplied per 10 or TH02_UNDEFINED_VALUE on err 00318 Comments: - temperature and rh raw values (*100) are stored for raw purpose 00319 - the configuration register is checked to see if last conv was 00320 a temperature or humidity conversion 00321 ====================================================================== */ 00322 int16_t TH02::getConversionValue(void) 00323 { char cMaChaine[3]; 00324 int iError; 00325 int32_t result=0 ; 00326 uint8_t config; 00327 int16_t ret = TH02_UNDEFINED_VALUE; 00328 00329 // Prepare reading address of ADC data result 00330 if ( writeCommand(TH02_DATAh, false) == 0 ) 00331 { 00332 // Read 2 bytes adc data result MSB and LSB from TH02 00333 //Wire.requestFrom( (uint8_t) _address, (uint8_t) 2); 00334 00335 00336 iError= m_I2C.read (_address,cMaChaine,2,false); 00337 00338 00339 00340 00341 // we got 2 bytes ? 00342 // if (Wire.available() == 2) 00343 if (iError == 0 ) 00344 { 00345 // convert number 00346 // result = Wire.read() << 8; 00347 // result |= Wire.read(); 00348 result=(cMaChaine[0]<<8 )|cMaChaine[1]; 00349 // Get configuration to know what was asked last time 00350 if (getConfig(&config)==0) 00351 { 00352 // last conversion was temperature ? 00353 if( config & TH02_CONFIG_TEMP) 00354 { 00355 result >>= 2; // remove 2 unused LSB bits 00356 result *= 100; // multiply per 100 to have int value with 2 decimal 00357 result /= 32; // now apply datasheet formula 00358 if(result >= 5000) 00359 { 00360 result -= 5000; 00361 } 00362 else 00363 { 00364 result -= 5000; 00365 result = -result; 00366 } 00367 00368 // now result contain temperature * 100 00369 // so 2134 is 21.34 C 00370 00371 // Save raw value 00372 _last_temp = result; 00373 } 00374 // it was RH conversion 00375 else 00376 { 00377 result >>= 4; // remove 4 unused LSB bits 00378 result *= 100; // multiply per 100 to have int value with 2 decimal 00379 result /= 16; // now apply datasheet formula 00380 result -= 2400; 00381 00382 // now result contain humidity * 100 00383 // so 4567 is 45.67 % RH 00384 _last_rh = result; 00385 } 00386 00387 // remember result value is multiplied by 10 to avoid float calculation later 00388 // so humidity of 45.6% is 456 and temp of 21.3 C is 213 00389 ret = roundInt(result/10.0f); 00390 } 00391 } // if got 2 bytes from m_I2C 00392 00393 // Ok now we have finished with m_I2C, release 00394 //Wire.endTransmission(); 00395 00396 00397 } // if write command TH02_DATAh 00398 (void) m_I2C.stop(); 00399 return ret; 00400 } 00401 00402 /* ====================================================================== 00403 Function: getConpensatedRH 00404 Purpose : return the compensated calulated humidity 00405 Input : true if we want to round value to 1 digit precision, else 2 00406 Output : the compensed RH value (rounded or not) 00407 Comments: 00408 ====================================================================== */ 00409 int16_t TH02::getConpensatedRH(bool round) 00410 { 00411 float rhvalue ; 00412 float rhlinear ; 00413 int16_t ret = TH02_UNDEFINED_VALUE; 00414 00415 // did we had a previous measure RH 00416 if (_last_rh != TH02_UNINITIALIZED_RH) 00417 { 00418 // now we're float restore real value RH value 00419 rhvalue = (float) _last_rh / 100.0 ; 00420 00421 // apply linear compensation 00422 rhlinear = rhvalue - ((rhvalue*rhvalue) * TH02_A2 + rhvalue * TH02_A1 + TH02_A0); 00423 00424 // correct value 00425 rhvalue = rhlinear; 00426 00427 // do we have a initialized temperature value ? 00428 if (_last_temp != TH02_UNINITIALIZED_TEMP ) 00429 { 00430 // Apply Temperature compensation 00431 // remember last temp was stored * 100 00432 rhvalue += ((_last_temp/100.0) - 30.0) * (rhlinear * TH02_Q1 + TH02_Q0); 00433 } 00434 00435 // now get back * 100 to have int with 2 digit precision 00436 rhvalue *= 100; 00437 00438 // do we need to round to 1 digit ? 00439 if (round) 00440 { 00441 // remember result value is multiplied by 10 to avoid float calculation later 00442 // so humidity of 45.6% is 456 00443 ret = roundInt(rhvalue/10.0f); 00444 } 00445 else 00446 { 00447 ret = (int16_t) rhvalue; 00448 } 00449 } 00450 00451 return ret; 00452 } 00453 00454 /* ====================================================================== 00455 Function: getLastRawRH 00456 Purpose : return the raw humidity * 100 00457 Input : 00458 Output : int value (ie 4123 for 41.23%) 00459 Comments: 00460 ====================================================================== */ 00461 int32_t TH02::getLastRawRH(void) 00462 { 00463 return _last_rh; 00464 } 00465 00466 /* ====================================================================== 00467 Function: getLastRawTemp 00468 Purpose : return the raw temperature value * 100 00469 Input : 00470 Output : int value (ie 2124 for 21.24 C) 00471 Comments: 00472 ====================================================================== */ 00473 int32_t TH02::getLastRawTemp(void) 00474 { 00475 return _last_temp; 00476 }
Generated on Mon Jul 18 2022 05:50:58 by
![doxygen](doxygen.png)