![](/media/cache/group/default_image.jpg.50x50_q85.jpg)
corrected TH02 sample program
Dependencies: mbed
Fork of TH02_humidity_temp by
th02.cpp@0:f1951c6c9187, 2017-03-17 (annotated)
- Committer:
- superphil06
- Date:
- Fri Mar 17 10:13:49 2017 +0000
- Revision:
- 0:f1951c6c9187
- Child:
- 1:8326614f3037
TH02_sample_program
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
superphil06 | 0:f1951c6c9187 | 1 | // ********************************************************************************** |
superphil06 | 0:f1951c6c9187 | 2 | // Driver definition for HopeRF TH02 temperature and humidity sensor |
superphil06 | 0:f1951c6c9187 | 3 | // ********************************************************************************** |
superphil06 | 0:f1951c6c9187 | 4 | // Creative Commons Attrib Share-Alike License |
superphil06 | 0:f1951c6c9187 | 5 | // You are free to use/extend this library but please abide with the CC-BY-SA license: |
superphil06 | 0:f1951c6c9187 | 6 | // http://creativecommons.org/licenses/by-sa/4.0/ |
superphil06 | 0:f1951c6c9187 | 7 | // |
superphil06 | 0:f1951c6c9187 | 8 | // For any explanation see TH02 sensor information at |
superphil06 | 0:f1951c6c9187 | 9 | // http://www.hoperf.com/sensor/app/TH02.htm |
superphil06 | 0:f1951c6c9187 | 10 | // |
superphil06 | 0:f1951c6c9187 | 11 | // Code based on following datasheet |
superphil06 | 0:f1951c6c9187 | 12 | // http://www.hoperf.com/upload/sensor/TH02_V1.1.pdf |
superphil06 | 0:f1951c6c9187 | 13 | // |
superphil06 | 0:f1951c6c9187 | 14 | // Written by Charles-Henri Hallard (http://hallard.me) |
superphil06 | 0:f1951c6c9187 | 15 | // |
superphil06 | 0:f1951c6c9187 | 16 | // History : V1.00 2014-07-14 - First release |
superphil06 | 0:f1951c6c9187 | 17 | // V1.10 2015-04-13 - changed to Wire library instead of m_I2C |
superphil06 | 0:f1951c6c9187 | 18 | // |
superphil06 | 0:f1951c6c9187 | 19 | // All text above must be included in any redistribution. |
superphil06 | 0:f1951c6c9187 | 20 | // |
superphil06 | 0:f1951c6c9187 | 21 | // ********************************************************************************** |
superphil06 | 0:f1951c6c9187 | 22 | #include "th02.h" |
superphil06 | 0:f1951c6c9187 | 23 | #include "mbed.h" |
superphil06 | 0:f1951c6c9187 | 24 | #include "math.h" |
superphil06 | 0:f1951c6c9187 | 25 | |
superphil06 | 0:f1951c6c9187 | 26 | // Class Constructor |
superphil06 | 0:f1951c6c9187 | 27 | |
superphil06 | 0:f1951c6c9187 | 28 | TH02::TH02(PinName sda,PinName scl,uint8_t address): m_I2C(sda, scl) |
superphil06 | 0:f1951c6c9187 | 29 | { |
superphil06 | 0:f1951c6c9187 | 30 | _address = address; // m_I2C Module Address |
superphil06 | 0:f1951c6c9187 | 31 | _last_temp = TH02_UNINITIALIZED_TEMP; // Last measured temperature (for linearization) |
superphil06 | 0:f1951c6c9187 | 32 | _last_rh = TH02_UNINITIALIZED_RH; // Last measured RH |
superphil06 | 0:f1951c6c9187 | 33 | } |
superphil06 | 0:f1951c6c9187 | 34 | |
superphil06 | 0:f1951c6c9187 | 35 | TH02::~TH02() |
superphil06 | 0:f1951c6c9187 | 36 | { |
superphil06 | 0:f1951c6c9187 | 37 | |
superphil06 | 0:f1951c6c9187 | 38 | } |
superphil06 | 0:f1951c6c9187 | 39 | |
superphil06 | 0:f1951c6c9187 | 40 | |
superphil06 | 0:f1951c6c9187 | 41 | |
superphil06 | 0:f1951c6c9187 | 42 | /* ====================================================================== |
superphil06 | 0:f1951c6c9187 | 43 | Function: writeCommand |
superphil06 | 0:f1951c6c9187 | 44 | Purpose : write the "register address" value on m_I2C bus |
superphil06 | 0:f1951c6c9187 | 45 | Input : register address |
superphil06 | 0:f1951c6c9187 | 46 | true if we need to release the bus after (default yes) |
superphil06 | 0:f1951c6c9187 | 47 | Output : Arduino Wire library return code (0 if ok) |
superphil06 | 0:f1951c6c9187 | 48 | Comments: |
superphil06 | 0:f1951c6c9187 | 49 | ====================================================================== */ |
superphil06 | 0:f1951c6c9187 | 50 | uint8_t TH02::writeCommand(uint8_t command, bool release) |
superphil06 | 0:f1951c6c9187 | 51 | {int iError; |
superphil06 | 0:f1951c6c9187 | 52 | (void) m_I2C.start(); |
superphil06 | 0:f1951c6c9187 | 53 | //Wire.beginTransmission(_address); |
superphil06 | 0:f1951c6c9187 | 54 | iError=m_I2C.write(_address);// send adress of i2c slave |
superphil06 | 0:f1951c6c9187 | 55 | |
superphil06 | 0:f1951c6c9187 | 56 | if (iError==1) |
superphil06 | 0:f1951c6c9187 | 57 | { |
superphil06 | 0:f1951c6c9187 | 58 | // Wire.write(command) ; |
superphil06 | 0:f1951c6c9187 | 59 | iError= m_I2C.write(command); |
superphil06 | 0:f1951c6c9187 | 60 | } |
superphil06 | 0:f1951c6c9187 | 61 | if (release==true) |
superphil06 | 0:f1951c6c9187 | 62 | { m_I2C.stop();// return stop error code |
superphil06 | 0:f1951c6c9187 | 63 | } |
superphil06 | 0:f1951c6c9187 | 64 | if (iError==1) iError=0;// ack received |
superphil06 | 0:f1951c6c9187 | 65 | else iError=1;// no ack |
superphil06 | 0:f1951c6c9187 | 66 | return iError; |
superphil06 | 0:f1951c6c9187 | 67 | } |
superphil06 | 0:f1951c6c9187 | 68 | |
superphil06 | 0:f1951c6c9187 | 69 | /* ====================================================================== |
superphil06 | 0:f1951c6c9187 | 70 | Function: writeRegister |
superphil06 | 0:f1951c6c9187 | 71 | Purpose : write a value on the designed register address on m_I2C bus |
superphil06 | 0:f1951c6c9187 | 72 | Input : register address |
superphil06 | 0:f1951c6c9187 | 73 | value to write |
superphil06 | 0:f1951c6c9187 | 74 | Output : Arduino Wire library return code (0 if ok) |
superphil06 | 0:f1951c6c9187 | 75 | Comments: |
superphil06 | 0:f1951c6c9187 | 76 | ====================================================================== */ |
superphil06 | 0:f1951c6c9187 | 77 | uint8_t TH02::writeRegister(uint8_t reg, uint8_t value) |
superphil06 | 0:f1951c6c9187 | 78 | { int iError; |
superphil06 | 0:f1951c6c9187 | 79 | |
superphil06 | 0:f1951c6c9187 | 80 | bool ret = false; |
superphil06 | 0:f1951c6c9187 | 81 | |
superphil06 | 0:f1951c6c9187 | 82 | //Wire.beginTransmission(_address); |
superphil06 | 0:f1951c6c9187 | 83 | (void) m_I2C.start(); |
superphil06 | 0:f1951c6c9187 | 84 | iError=m_I2C.write(_address);// send adress of i2c slave |
superphil06 | 0:f1951c6c9187 | 85 | // Wire.write(reg); |
superphil06 | 0:f1951c6c9187 | 86 | if (iError==1){ |
superphil06 | 0:f1951c6c9187 | 87 | |
superphil06 | 0:f1951c6c9187 | 88 | iError= m_I2C.write(reg); |
superphil06 | 0:f1951c6c9187 | 89 | |
superphil06 | 0:f1951c6c9187 | 90 | // Wire.write(value); |
superphil06 | 0:f1951c6c9187 | 91 | (void) m_I2C.write(value); |
superphil06 | 0:f1951c6c9187 | 92 | } |
superphil06 | 0:f1951c6c9187 | 93 | // return Wire.endTransmission(); |
superphil06 | 0:f1951c6c9187 | 94 | m_I2C.stop();// return stop error code |
superphil06 | 0:f1951c6c9187 | 95 | if (iError==1) iError=0;// ack received |
superphil06 | 0:f1951c6c9187 | 96 | else iError=1;// no ack |
superphil06 | 0:f1951c6c9187 | 97 | return iError; |
superphil06 | 0:f1951c6c9187 | 98 | } |
superphil06 | 0:f1951c6c9187 | 99 | |
superphil06 | 0:f1951c6c9187 | 100 | /* ====================================================================== |
superphil06 | 0:f1951c6c9187 | 101 | Function: readRegister |
superphil06 | 0:f1951c6c9187 | 102 | Purpose : read a register address value on m_I2C bus |
superphil06 | 0:f1951c6c9187 | 103 | Input : register address |
superphil06 | 0:f1951c6c9187 | 104 | pointer where the return value will be filled |
superphil06 | 0:f1951c6c9187 | 105 | Output : Arduino Wire library return code (0 if ok) |
superphil06 | 0:f1951c6c9187 | 106 | Comments: |
superphil06 | 0:f1951c6c9187 | 107 | ====================================================================== */ |
superphil06 | 0:f1951c6c9187 | 108 | uint8_t TH02::readRegister(uint8_t reg, uint8_t * value) |
superphil06 | 0:f1951c6c9187 | 109 | { |
superphil06 | 0:f1951c6c9187 | 110 | uint8_t ret ; |
superphil06 | 0:f1951c6c9187 | 111 | int iAck,iRedVal,iError; |
superphil06 | 0:f1951c6c9187 | 112 | // Send a register reading command |
superphil06 | 0:f1951c6c9187 | 113 | // but DO NOT release the m_I2C bus |
superphil06 | 0:f1951c6c9187 | 114 | // (void) m_I2C.start(); |
superphil06 | 0:f1951c6c9187 | 115 | // iError=m_I2C.write(_address);// send adress of i2c slave |
superphil06 | 0:f1951c6c9187 | 116 | |
superphil06 | 0:f1951c6c9187 | 117 | //if (iError==1) |
superphil06 | 0:f1951c6c9187 | 118 | |
superphil06 | 0:f1951c6c9187 | 119 | ret = writeCommand(reg, false); |
superphil06 | 0:f1951c6c9187 | 120 | |
superphil06 | 0:f1951c6c9187 | 121 | if ( ret == 0) //if command ok |
superphil06 | 0:f1951c6c9187 | 122 | { |
superphil06 | 0:f1951c6c9187 | 123 | // Wire.requestFrom( (uint8_t) _address, (uint8_t) 1); |
superphil06 | 0:f1951c6c9187 | 124 | (void) m_I2C.start(); |
superphil06 | 0:f1951c6c9187 | 125 | iError=m_I2C.write(_address+0x01);// send adress of i2c slave in read mode |
superphil06 | 0:f1951c6c9187 | 126 | iRedVal=m_I2C.read(0);//send non ack |
superphil06 | 0:f1951c6c9187 | 127 | // if (Wire.available() != 1) |
superphil06 | 0:f1951c6c9187 | 128 | /*if (iAck != 1) |
superphil06 | 0:f1951c6c9187 | 129 | |
superphil06 | 0:f1951c6c9187 | 130 | // Other error as Wire library |
superphil06 | 0:f1951c6c9187 | 131 | ret = 4; |
superphil06 | 0:f1951c6c9187 | 132 | else |
superphil06 | 0:f1951c6c9187 | 133 | // grab the value*/ |
superphil06 | 0:f1951c6c9187 | 134 | *value = iRedVal; // return Red value by ref |
superphil06 | 0:f1951c6c9187 | 135 | |
superphil06 | 0:f1951c6c9187 | 136 | //} |
superphil06 | 0:f1951c6c9187 | 137 | |
superphil06 | 0:f1951c6c9187 | 138 | // Ok now we have finished |
superphil06 | 0:f1951c6c9187 | 139 | // Wire.endTransmission(); |
superphil06 | 0:f1951c6c9187 | 140 | |
superphil06 | 0:f1951c6c9187 | 141 | } |
superphil06 | 0:f1951c6c9187 | 142 | (void) m_I2C.stop();// return stop error code |
superphil06 | 0:f1951c6c9187 | 143 | return ret; |
superphil06 | 0:f1951c6c9187 | 144 | } |
superphil06 | 0:f1951c6c9187 | 145 | |
superphil06 | 0:f1951c6c9187 | 146 | /* ====================================================================== |
superphil06 | 0:f1951c6c9187 | 147 | Function: getId |
superphil06 | 0:f1951c6c9187 | 148 | Purpose : Get device ID register |
superphil06 | 0:f1951c6c9187 | 149 | Input : pointer where the return value will be filled |
superphil06 | 0:f1951c6c9187 | 150 | Output : Arduino Wire library return code (0 if ok) |
superphil06 | 0:f1951c6c9187 | 151 | Comments: - |
superphil06 | 0:f1951c6c9187 | 152 | ====================================================================== */ |
superphil06 | 0:f1951c6c9187 | 153 | uint8_t TH02::getId(uint8_t * pvalue) |
superphil06 | 0:f1951c6c9187 | 154 | { |
superphil06 | 0:f1951c6c9187 | 155 | return (readRegister(TH02_ID, pvalue)); |
superphil06 | 0:f1951c6c9187 | 156 | } |
superphil06 | 0:f1951c6c9187 | 157 | |
superphil06 | 0:f1951c6c9187 | 158 | /* ====================================================================== |
superphil06 | 0:f1951c6c9187 | 159 | Function: getStatus |
superphil06 | 0:f1951c6c9187 | 160 | Purpose : Get device status register |
superphil06 | 0:f1951c6c9187 | 161 | Input : pointer where the return value will be filled |
superphil06 | 0:f1951c6c9187 | 162 | Output : Arduino Wire library return code (0 if ok) |
superphil06 | 0:f1951c6c9187 | 163 | Comments: |
superphil06 | 0:f1951c6c9187 | 164 | ====================================================================== */ |
superphil06 | 0:f1951c6c9187 | 165 | uint8_t TH02::getStatus(uint8_t * pvalue) |
superphil06 | 0:f1951c6c9187 | 166 | { |
superphil06 | 0:f1951c6c9187 | 167 | return (readRegister(TH02_STATUS, pvalue)); |
superphil06 | 0:f1951c6c9187 | 168 | } |
superphil06 | 0:f1951c6c9187 | 169 | |
superphil06 | 0:f1951c6c9187 | 170 | /* ====================================================================== |
superphil06 | 0:f1951c6c9187 | 171 | Function: isConverting |
superphil06 | 0:f1951c6c9187 | 172 | Purpose : Indicate if a temperature or humidity conversion is in progress |
superphil06 | 0:f1951c6c9187 | 173 | Input : - |
superphil06 | 0:f1951c6c9187 | 174 | Output : true if conversion in progress false otherwise |
superphil06 | 0:f1951c6c9187 | 175 | Comments: |
superphil06 | 0:f1951c6c9187 | 176 | ====================================================================== */ |
superphil06 | 0:f1951c6c9187 | 177 | bool TH02::isConverting(void) |
superphil06 | 0:f1951c6c9187 | 178 | { |
superphil06 | 0:f1951c6c9187 | 179 | uint8_t status; |
superphil06 | 0:f1951c6c9187 | 180 | // Get status and check RDY bit |
superphil06 | 0:f1951c6c9187 | 181 | if ( getStatus(&status) == 0) |
superphil06 | 0:f1951c6c9187 | 182 | |
superphil06 | 0:f1951c6c9187 | 183 | { printf("\n lecture status %x",status); |
superphil06 | 0:f1951c6c9187 | 184 | if ( (status & TH02_STATUS_RDY) ==1 ) |
superphil06 | 0:f1951c6c9187 | 185 | return true; |
superphil06 | 0:f1951c6c9187 | 186 | } |
superphil06 | 0:f1951c6c9187 | 187 | return false; |
superphil06 | 0:f1951c6c9187 | 188 | } |
superphil06 | 0:f1951c6c9187 | 189 | |
superphil06 | 0:f1951c6c9187 | 190 | /* ====================================================================== |
superphil06 | 0:f1951c6c9187 | 191 | Function: getConfig |
superphil06 | 0:f1951c6c9187 | 192 | Purpose : Get device configuration register |
superphil06 | 0:f1951c6c9187 | 193 | Input : pointer where the return value will be filled |
superphil06 | 0:f1951c6c9187 | 194 | Output : Arduino Wire library return code (0 if ok) |
superphil06 | 0:f1951c6c9187 | 195 | Comments: |
superphil06 | 0:f1951c6c9187 | 196 | ====================================================================== */ |
superphil06 | 0:f1951c6c9187 | 197 | uint8_t TH02::getConfig(uint8_t * pvalue) |
superphil06 | 0:f1951c6c9187 | 198 | { |
superphil06 | 0:f1951c6c9187 | 199 | return (readRegister(TH02_CONFIG, pvalue)); |
superphil06 | 0:f1951c6c9187 | 200 | } |
superphil06 | 0:f1951c6c9187 | 201 | |
superphil06 | 0:f1951c6c9187 | 202 | /* ====================================================================== |
superphil06 | 0:f1951c6c9187 | 203 | Function: setConfig |
superphil06 | 0:f1951c6c9187 | 204 | Purpose : Set device configuration register |
superphil06 | 0:f1951c6c9187 | 205 | Input : value to set |
superphil06 | 0:f1951c6c9187 | 206 | Output : true if succeded, false otherwise |
superphil06 | 0:f1951c6c9187 | 207 | Comments: |
superphil06 | 0:f1951c6c9187 | 208 | ====================================================================== */ |
superphil06 | 0:f1951c6c9187 | 209 | uint8_t TH02::setConfig(uint8_t config) |
superphil06 | 0:f1951c6c9187 | 210 | { |
superphil06 | 0:f1951c6c9187 | 211 | return (writeRegister(TH02_CONFIG, config)); |
superphil06 | 0:f1951c6c9187 | 212 | } |
superphil06 | 0:f1951c6c9187 | 213 | |
superphil06 | 0:f1951c6c9187 | 214 | /* ====================================================================== |
superphil06 | 0:f1951c6c9187 | 215 | Function: startTempConv |
superphil06 | 0:f1951c6c9187 | 216 | Purpose : Start a temperature conversion |
superphil06 | 0:f1951c6c9187 | 217 | Input : - fastmode true to enable fast conversion |
superphil06 | 0:f1951c6c9187 | 218 | - heater true to enable heater |
superphil06 | 0:f1951c6c9187 | 219 | Output : true if succeded, false otherwise |
superphil06 | 0:f1951c6c9187 | 220 | Comments: if heater enabled, it will not be auto disabled |
superphil06 | 0:f1951c6c9187 | 221 | ====================================================================== */ |
superphil06 | 0:f1951c6c9187 | 222 | uint8_t TH02::startTempConv(bool fastmode, bool heater) |
superphil06 | 0:f1951c6c9187 | 223 | { |
superphil06 | 0:f1951c6c9187 | 224 | // init configuration register to start and temperature |
superphil06 | 0:f1951c6c9187 | 225 | uint8_t config = TH02_CONFIG_START | TH02_CONFIG_TEMP; |
superphil06 | 0:f1951c6c9187 | 226 | |
superphil06 | 0:f1951c6c9187 | 227 | // set fast mode and heater if asked |
superphil06 | 0:f1951c6c9187 | 228 | if (fastmode) config |= TH02_CONFIG_FAST; |
superphil06 | 0:f1951c6c9187 | 229 | if (heater) config |= TH02_CONFIG_HEAT; |
superphil06 | 0:f1951c6c9187 | 230 | |
superphil06 | 0:f1951c6c9187 | 231 | // write to configuration register |
superphil06 | 0:f1951c6c9187 | 232 | return ( setConfig( config ) ); |
superphil06 | 0:f1951c6c9187 | 233 | } |
superphil06 | 0:f1951c6c9187 | 234 | |
superphil06 | 0:f1951c6c9187 | 235 | /* ====================================================================== |
superphil06 | 0:f1951c6c9187 | 236 | Function: startRHConv |
superphil06 | 0:f1951c6c9187 | 237 | Purpose : Start a relative humidity conversion |
superphil06 | 0:f1951c6c9187 | 238 | Input : - fastmode true to enable fast conversion |
superphil06 | 0:f1951c6c9187 | 239 | - heater true to enable heater |
superphil06 | 0:f1951c6c9187 | 240 | Output : true if succeded, false otherwise |
superphil06 | 0:f1951c6c9187 | 241 | Comments: if heater enabled, it will not be auto disabled |
superphil06 | 0:f1951c6c9187 | 242 | ====================================================================== */ |
superphil06 | 0:f1951c6c9187 | 243 | uint8_t TH02::startRHConv(bool fastmode, bool heater) |
superphil06 | 0:f1951c6c9187 | 244 | { |
superphil06 | 0:f1951c6c9187 | 245 | // init configuration register to start and no temperature (so RH) |
superphil06 | 0:f1951c6c9187 | 246 | uint8_t config = TH02_CONFIG_START; |
superphil06 | 0:f1951c6c9187 | 247 | |
superphil06 | 0:f1951c6c9187 | 248 | // set fast mode and heater if asked |
superphil06 | 0:f1951c6c9187 | 249 | if (fastmode) config |= TH02_CONFIG_FAST; |
superphil06 | 0:f1951c6c9187 | 250 | if (heater) config |= TH02_CONFIG_HEAT; |
superphil06 | 0:f1951c6c9187 | 251 | |
superphil06 | 0:f1951c6c9187 | 252 | // write to configuration register |
superphil06 | 0:f1951c6c9187 | 253 | return ( setConfig( config ) ); |
superphil06 | 0:f1951c6c9187 | 254 | } |
superphil06 | 0:f1951c6c9187 | 255 | |
superphil06 | 0:f1951c6c9187 | 256 | /* ====================================================================== |
superphil06 | 0:f1951c6c9187 | 257 | Function: waitEndConversion |
superphil06 | 0:f1951c6c9187 | 258 | Purpose : wait for a temperature or RH conversion is done |
superphil06 | 0:f1951c6c9187 | 259 | Input : |
superphil06 | 0:f1951c6c9187 | 260 | Output : delay in ms the process took. |
superphil06 | 0:f1951c6c9187 | 261 | Comments: if return >= TH02_CONVERSION_TIME_OUT, time out occured |
superphil06 | 0:f1951c6c9187 | 262 | ====================================================================== */ |
superphil06 | 0:f1951c6c9187 | 263 | uint8_t TH02::waitEndConversion(void) |
superphil06 | 0:f1951c6c9187 | 264 | { |
superphil06 | 0:f1951c6c9187 | 265 | // okay this is basic approach not so accurate |
superphil06 | 0:f1951c6c9187 | 266 | // but avoid using long and millis() |
superphil06 | 0:f1951c6c9187 | 267 | uint8_t time_out = 0; |
superphil06 | 0:f1951c6c9187 | 268 | |
superphil06 | 0:f1951c6c9187 | 269 | // loop until conversion done or duration >= time out |
superphil06 | 0:f1951c6c9187 | 270 | while (isConverting() && time_out <= TH02_CONVERSION_TIME_OUT ) |
superphil06 | 0:f1951c6c9187 | 271 | { |
superphil06 | 0:f1951c6c9187 | 272 | ++time_out; |
superphil06 | 0:f1951c6c9187 | 273 | wait_ms(1); |
superphil06 | 0:f1951c6c9187 | 274 | } |
superphil06 | 0:f1951c6c9187 | 275 | |
superphil06 | 0:f1951c6c9187 | 276 | // return approx time of conversion |
superphil06 | 0:f1951c6c9187 | 277 | return (time_out); |
superphil06 | 0:f1951c6c9187 | 278 | } |
superphil06 | 0:f1951c6c9187 | 279 | |
superphil06 | 0:f1951c6c9187 | 280 | /* ====================================================================== |
superphil06 | 0:f1951c6c9187 | 281 | Function: roundInt |
superphil06 | 0:f1951c6c9187 | 282 | Purpose : round a float value to int |
superphil06 | 0:f1951c6c9187 | 283 | Input : float value |
superphil06 | 0:f1951c6c9187 | 284 | Output : int value rounded |
superphil06 | 0:f1951c6c9187 | 285 | Comments: |
superphil06 | 0:f1951c6c9187 | 286 | ====================================================================== */ |
superphil06 | 0:f1951c6c9187 | 287 | int16_t TH02::roundInt(float value) |
superphil06 | 0:f1951c6c9187 | 288 | { |
superphil06 | 0:f1951c6c9187 | 289 | |
superphil06 | 0:f1951c6c9187 | 290 | // check positive number and do round |
superphil06 | 0:f1951c6c9187 | 291 | if (value >= 0.0f) |
superphil06 | 0:f1951c6c9187 | 292 | value = floor(value + 0.5f); |
superphil06 | 0:f1951c6c9187 | 293 | else |
superphil06 | 0:f1951c6c9187 | 294 | value = ceil(value - 0.5f); |
superphil06 | 0:f1951c6c9187 | 295 | |
superphil06 | 0:f1951c6c9187 | 296 | // return int value |
superphil06 | 0:f1951c6c9187 | 297 | return (static_cast<int16_t>(value)); |
superphil06 | 0:f1951c6c9187 | 298 | } |
superphil06 | 0:f1951c6c9187 | 299 | |
superphil06 | 0:f1951c6c9187 | 300 | /* to avoid math library may I need to test something |
superphil06 | 0:f1951c6c9187 | 301 | like that |
superphil06 | 0:f1951c6c9187 | 302 | float TH02::showDecimals(float x, int numDecimals) |
superphil06 | 0:f1951c6c9187 | 303 | { |
superphil06 | 0:f1951c6c9187 | 304 | int y=x; |
superphil06 | 0:f1951c6c9187 | 305 | double z=x-y; |
superphil06 | 0:f1951c6c9187 | 306 | double m=pow(10,numDecimals); |
superphil06 | 0:f1951c6c9187 | 307 | double q=z*m; |
superphil06 | 0:f1951c6c9187 | 308 | double r=round(q); |
superphil06 | 0:f1951c6c9187 | 309 | return static_cast<double>(y)+(1.0/m)*r; |
superphil06 | 0:f1951c6c9187 | 310 | } |
superphil06 | 0:f1951c6c9187 | 311 | */ |
superphil06 | 0:f1951c6c9187 | 312 | |
superphil06 | 0:f1951c6c9187 | 313 | /* ====================================================================== |
superphil06 | 0:f1951c6c9187 | 314 | Function: getConversionValue |
superphil06 | 0:f1951c6c9187 | 315 | Purpose : return the last converted value to int * 10 to have 1 digit prec. |
superphil06 | 0:f1951c6c9187 | 316 | Input : float value |
superphil06 | 0:f1951c6c9187 | 317 | Output : value rounded but multiplied per 10 or TH02_UNDEFINED_VALUE on err |
superphil06 | 0:f1951c6c9187 | 318 | Comments: - temperature and rh raw values (*100) are stored for raw purpose |
superphil06 | 0:f1951c6c9187 | 319 | - the configuration register is checked to see if last conv was |
superphil06 | 0:f1951c6c9187 | 320 | a temperature or humidity conversion |
superphil06 | 0:f1951c6c9187 | 321 | ====================================================================== */ |
superphil06 | 0:f1951c6c9187 | 322 | int16_t TH02::getConversionValue(void) |
superphil06 | 0:f1951c6c9187 | 323 | { char cMaChaine[3]; |
superphil06 | 0:f1951c6c9187 | 324 | int iError; |
superphil06 | 0:f1951c6c9187 | 325 | int32_t result=0 ; |
superphil06 | 0:f1951c6c9187 | 326 | uint8_t config; |
superphil06 | 0:f1951c6c9187 | 327 | int16_t ret = TH02_UNDEFINED_VALUE; |
superphil06 | 0:f1951c6c9187 | 328 | |
superphil06 | 0:f1951c6c9187 | 329 | // Prepare reading address of ADC data result |
superphil06 | 0:f1951c6c9187 | 330 | if ( writeCommand(TH02_DATAh, false) == 0 ) |
superphil06 | 0:f1951c6c9187 | 331 | { |
superphil06 | 0:f1951c6c9187 | 332 | // Read 2 bytes adc data result MSB and LSB from TH02 |
superphil06 | 0:f1951c6c9187 | 333 | //Wire.requestFrom( (uint8_t) _address, (uint8_t) 2); |
superphil06 | 0:f1951c6c9187 | 334 | |
superphil06 | 0:f1951c6c9187 | 335 | |
superphil06 | 0:f1951c6c9187 | 336 | iError= m_I2C.read (_address,cMaChaine,2,false); |
superphil06 | 0:f1951c6c9187 | 337 | |
superphil06 | 0:f1951c6c9187 | 338 | |
superphil06 | 0:f1951c6c9187 | 339 | |
superphil06 | 0:f1951c6c9187 | 340 | |
superphil06 | 0:f1951c6c9187 | 341 | // we got 2 bytes ? |
superphil06 | 0:f1951c6c9187 | 342 | // if (Wire.available() == 2) |
superphil06 | 0:f1951c6c9187 | 343 | if (iError == 0 ) |
superphil06 | 0:f1951c6c9187 | 344 | { |
superphil06 | 0:f1951c6c9187 | 345 | // convert number |
superphil06 | 0:f1951c6c9187 | 346 | // result = Wire.read() << 8; |
superphil06 | 0:f1951c6c9187 | 347 | // result |= Wire.read(); |
superphil06 | 0:f1951c6c9187 | 348 | result=(cMaChaine[0]<<8 )|cMaChaine[1]; |
superphil06 | 0:f1951c6c9187 | 349 | // Get configuration to know what was asked last time |
superphil06 | 0:f1951c6c9187 | 350 | if (getConfig(&config)==0) |
superphil06 | 0:f1951c6c9187 | 351 | { |
superphil06 | 0:f1951c6c9187 | 352 | // last conversion was temperature ? |
superphil06 | 0:f1951c6c9187 | 353 | if( config & TH02_CONFIG_TEMP) |
superphil06 | 0:f1951c6c9187 | 354 | { |
superphil06 | 0:f1951c6c9187 | 355 | result >>= 2; // remove 2 unused LSB bits |
superphil06 | 0:f1951c6c9187 | 356 | result *= 100; // multiply per 100 to have int value with 2 decimal |
superphil06 | 0:f1951c6c9187 | 357 | result /= 32; // now apply datasheet formula |
superphil06 | 0:f1951c6c9187 | 358 | if(result >= 5000) |
superphil06 | 0:f1951c6c9187 | 359 | { |
superphil06 | 0:f1951c6c9187 | 360 | result -= 5000; |
superphil06 | 0:f1951c6c9187 | 361 | } |
superphil06 | 0:f1951c6c9187 | 362 | else |
superphil06 | 0:f1951c6c9187 | 363 | { |
superphil06 | 0:f1951c6c9187 | 364 | result -= 5000; |
superphil06 | 0:f1951c6c9187 | 365 | result = -result; |
superphil06 | 0:f1951c6c9187 | 366 | } |
superphil06 | 0:f1951c6c9187 | 367 | |
superphil06 | 0:f1951c6c9187 | 368 | // now result contain temperature * 100 |
superphil06 | 0:f1951c6c9187 | 369 | // so 2134 is 21.34 C |
superphil06 | 0:f1951c6c9187 | 370 | |
superphil06 | 0:f1951c6c9187 | 371 | // Save raw value |
superphil06 | 0:f1951c6c9187 | 372 | _last_temp = result; |
superphil06 | 0:f1951c6c9187 | 373 | } |
superphil06 | 0:f1951c6c9187 | 374 | // it was RH conversion |
superphil06 | 0:f1951c6c9187 | 375 | else |
superphil06 | 0:f1951c6c9187 | 376 | { |
superphil06 | 0:f1951c6c9187 | 377 | result >>= 4; // remove 4 unused LSB bits |
superphil06 | 0:f1951c6c9187 | 378 | result *= 100; // multiply per 100 to have int value with 2 decimal |
superphil06 | 0:f1951c6c9187 | 379 | result /= 16; // now apply datasheet formula |
superphil06 | 0:f1951c6c9187 | 380 | result -= 2400; |
superphil06 | 0:f1951c6c9187 | 381 | |
superphil06 | 0:f1951c6c9187 | 382 | // now result contain humidity * 100 |
superphil06 | 0:f1951c6c9187 | 383 | // so 4567 is 45.67 % RH |
superphil06 | 0:f1951c6c9187 | 384 | _last_rh = result; |
superphil06 | 0:f1951c6c9187 | 385 | } |
superphil06 | 0:f1951c6c9187 | 386 | |
superphil06 | 0:f1951c6c9187 | 387 | // remember result value is multiplied by 10 to avoid float calculation later |
superphil06 | 0:f1951c6c9187 | 388 | // so humidity of 45.6% is 456 and temp of 21.3 C is 213 |
superphil06 | 0:f1951c6c9187 | 389 | ret = roundInt(result/10.0f); |
superphil06 | 0:f1951c6c9187 | 390 | } |
superphil06 | 0:f1951c6c9187 | 391 | } // if got 2 bytes from m_I2C |
superphil06 | 0:f1951c6c9187 | 392 | |
superphil06 | 0:f1951c6c9187 | 393 | // Ok now we have finished with m_I2C, release |
superphil06 | 0:f1951c6c9187 | 394 | //Wire.endTransmission(); |
superphil06 | 0:f1951c6c9187 | 395 | |
superphil06 | 0:f1951c6c9187 | 396 | |
superphil06 | 0:f1951c6c9187 | 397 | } // if write command TH02_DATAh |
superphil06 | 0:f1951c6c9187 | 398 | (void) m_I2C.stop(); |
superphil06 | 0:f1951c6c9187 | 399 | return ret; |
superphil06 | 0:f1951c6c9187 | 400 | } |
superphil06 | 0:f1951c6c9187 | 401 | |
superphil06 | 0:f1951c6c9187 | 402 | /* ====================================================================== |
superphil06 | 0:f1951c6c9187 | 403 | Function: getConpensatedRH |
superphil06 | 0:f1951c6c9187 | 404 | Purpose : return the compensated calulated humidity |
superphil06 | 0:f1951c6c9187 | 405 | Input : true if we want to round value to 1 digit precision, else 2 |
superphil06 | 0:f1951c6c9187 | 406 | Output : the compensed RH value (rounded or not) |
superphil06 | 0:f1951c6c9187 | 407 | Comments: |
superphil06 | 0:f1951c6c9187 | 408 | ====================================================================== */ |
superphil06 | 0:f1951c6c9187 | 409 | int16_t TH02::getConpensatedRH(bool round) |
superphil06 | 0:f1951c6c9187 | 410 | { |
superphil06 | 0:f1951c6c9187 | 411 | float rhvalue ; |
superphil06 | 0:f1951c6c9187 | 412 | float rhlinear ; |
superphil06 | 0:f1951c6c9187 | 413 | int16_t ret = TH02_UNDEFINED_VALUE; |
superphil06 | 0:f1951c6c9187 | 414 | |
superphil06 | 0:f1951c6c9187 | 415 | // did we had a previous measure RH |
superphil06 | 0:f1951c6c9187 | 416 | if (_last_rh != TH02_UNINITIALIZED_RH) |
superphil06 | 0:f1951c6c9187 | 417 | { |
superphil06 | 0:f1951c6c9187 | 418 | // now we're float restore real value RH value |
superphil06 | 0:f1951c6c9187 | 419 | rhvalue = (float) _last_rh / 100.0 ; |
superphil06 | 0:f1951c6c9187 | 420 | |
superphil06 | 0:f1951c6c9187 | 421 | // apply linear compensation |
superphil06 | 0:f1951c6c9187 | 422 | rhlinear = rhvalue - ((rhvalue*rhvalue) * TH02_A2 + rhvalue * TH02_A1 + TH02_A0); |
superphil06 | 0:f1951c6c9187 | 423 | |
superphil06 | 0:f1951c6c9187 | 424 | // correct value |
superphil06 | 0:f1951c6c9187 | 425 | rhvalue = rhlinear; |
superphil06 | 0:f1951c6c9187 | 426 | |
superphil06 | 0:f1951c6c9187 | 427 | // do we have a initialized temperature value ? |
superphil06 | 0:f1951c6c9187 | 428 | if (_last_temp != TH02_UNINITIALIZED_TEMP ) |
superphil06 | 0:f1951c6c9187 | 429 | { |
superphil06 | 0:f1951c6c9187 | 430 | // Apply Temperature compensation |
superphil06 | 0:f1951c6c9187 | 431 | // remember last temp was stored * 100 |
superphil06 | 0:f1951c6c9187 | 432 | rhvalue += ((_last_temp/100.0) - 30.0) * (rhlinear * TH02_Q1 + TH02_Q0); |
superphil06 | 0:f1951c6c9187 | 433 | } |
superphil06 | 0:f1951c6c9187 | 434 | |
superphil06 | 0:f1951c6c9187 | 435 | // now get back * 100 to have int with 2 digit precision |
superphil06 | 0:f1951c6c9187 | 436 | rhvalue *= 100; |
superphil06 | 0:f1951c6c9187 | 437 | |
superphil06 | 0:f1951c6c9187 | 438 | // do we need to round to 1 digit ? |
superphil06 | 0:f1951c6c9187 | 439 | if (round) |
superphil06 | 0:f1951c6c9187 | 440 | { |
superphil06 | 0:f1951c6c9187 | 441 | // remember result value is multiplied by 10 to avoid float calculation later |
superphil06 | 0:f1951c6c9187 | 442 | // so humidity of 45.6% is 456 |
superphil06 | 0:f1951c6c9187 | 443 | ret = roundInt(rhvalue/10.0f); |
superphil06 | 0:f1951c6c9187 | 444 | } |
superphil06 | 0:f1951c6c9187 | 445 | else |
superphil06 | 0:f1951c6c9187 | 446 | { |
superphil06 | 0:f1951c6c9187 | 447 | ret = (int16_t) rhvalue; |
superphil06 | 0:f1951c6c9187 | 448 | } |
superphil06 | 0:f1951c6c9187 | 449 | } |
superphil06 | 0:f1951c6c9187 | 450 | |
superphil06 | 0:f1951c6c9187 | 451 | return ret; |
superphil06 | 0:f1951c6c9187 | 452 | } |
superphil06 | 0:f1951c6c9187 | 453 | |
superphil06 | 0:f1951c6c9187 | 454 | /* ====================================================================== |
superphil06 | 0:f1951c6c9187 | 455 | Function: getLastRawRH |
superphil06 | 0:f1951c6c9187 | 456 | Purpose : return the raw humidity * 100 |
superphil06 | 0:f1951c6c9187 | 457 | Input : |
superphil06 | 0:f1951c6c9187 | 458 | Output : int value (ie 4123 for 41.23%) |
superphil06 | 0:f1951c6c9187 | 459 | Comments: |
superphil06 | 0:f1951c6c9187 | 460 | ====================================================================== */ |
superphil06 | 0:f1951c6c9187 | 461 | int32_t TH02::getLastRawRH(void) |
superphil06 | 0:f1951c6c9187 | 462 | { |
superphil06 | 0:f1951c6c9187 | 463 | return _last_rh; |
superphil06 | 0:f1951c6c9187 | 464 | } |
superphil06 | 0:f1951c6c9187 | 465 | |
superphil06 | 0:f1951c6c9187 | 466 | /* ====================================================================== |
superphil06 | 0:f1951c6c9187 | 467 | Function: getLastRawTemp |
superphil06 | 0:f1951c6c9187 | 468 | Purpose : return the raw temperature value * 100 |
superphil06 | 0:f1951c6c9187 | 469 | Input : |
superphil06 | 0:f1951c6c9187 | 470 | Output : int value (ie 2124 for 21.24 C) |
superphil06 | 0:f1951c6c9187 | 471 | Comments: |
superphil06 | 0:f1951c6c9187 | 472 | ====================================================================== */ |
superphil06 | 0:f1951c6c9187 | 473 | int32_t TH02::getLastRawTemp(void) |
superphil06 | 0:f1951c6c9187 | 474 | { |
superphil06 | 0:f1951c6c9187 | 475 | return _last_temp; |
superphil06 | 0:f1951c6c9187 | 476 | } |