corrected TH02 sample program

Dependencies:   mbed

Fork of TH02_humidity_temp by bazot-laurent

Revision:
1:8326614f3037
Parent:
0:f1951c6c9187
--- a/th02.cpp	Fri Mar 17 10:13:49 2017 +0000
+++ b/th02.cpp	Mon Oct 21 09:10:15 2019 +0000
@@ -9,7 +9,7 @@
 // http://www.hoperf.com/sensor/app/TH02.htm
 //
 // Code based on following datasheet
-// http://www.hoperf.com/upload/sensor/TH02_V1.1.pdf 
+// http://www.hoperf.com/upload/sensor/TH02_V1.1.pdf
 //
 // Written by Charles-Henri Hallard (http://hallard.me)
 //
@@ -26,10 +26,12 @@
 // Class Constructor
 
 TH02::TH02(PinName sda,PinName scl,uint8_t address): m_I2C(sda, scl)
-{           
-  _address = address; // m_I2C Module Address
-  _last_temp = TH02_UNINITIALIZED_TEMP;  // Last measured temperature (for linearization)
-  _last_rh = TH02_UNINITIALIZED_RH;      // Last measured RH
+{
+    _address = address; // m_I2C Module Address
+    _last_temp = TH02_UNINITIALIZED_TEMP;  // Last measured temperature (for linearization)
+    _last_rh = TH02_UNINITIALIZED_RH;      // Last measured RH
+//m_I2C.frequency(10000); //set 10khz i2c frequency
+
 }
 
 TH02::~TH02()
@@ -41,179 +43,185 @@
 
 /* ======================================================================
 Function: writeCommand
-Purpose : write the "register address" value on m_I2C bus 
+Purpose : write the "register address" value on m_I2C bus
 Input   : register address
           true if we need to release the bus after (default yes)
 Output  : Arduino Wire library return code (0 if ok)
-Comments: 
+Comments:
 ====================================================================== */
 uint8_t TH02::writeCommand(uint8_t command, bool release)
- {int iError; 
- (void) m_I2C.start();
-  //Wire.beginTransmission(_address);
- iError=m_I2C.write(_address);// send adress of i2c slave
-  
- if (iError==1)
- { 
- // Wire.write(command) ;
-    iError= m_I2C.write(command);
-  }
-  if (release==true)
- { m_I2C.stop();// return stop error code
- }
-  if (iError==1) iError=0;// ack received
-  else iError=1;// no ack
-  return iError;
+{
+    int iError;
+    (void) m_I2C.start();
+    //Wire.beginTransmission(_address);
+    iError=m_I2C.write(_address);// send adress of i2c slave
+
+    if (iError==1) { // ack received
+// Wire.write(command) ;
+        iError= m_I2C.write(command);
+
+
+        if (release==true) {
+            m_I2C.stop();// return stop error code
+        }
+    }
+
+    if (iError==1) iError=0;// ack received
+    else iError=1;// no ack
+    return iError;
 }
 
 /* ======================================================================
 Function: writeRegister
-Purpose : write a value on the designed register address on m_I2C bus 
+Purpose : write a value on the designed register address on m_I2C bus
 Input   : register address
           value to write
 Output  : Arduino Wire library return code (0 if ok)
-Comments: 
+Comments:
 ====================================================================== */
 uint8_t TH02::writeRegister(uint8_t reg, uint8_t value)
-{   int iError; 
- 
-  bool ret = false;
+{
+    int iError;
+
+    bool ret = false;
+
+    //Wire.beginTransmission(_address);
+    (void) m_I2C.start();
+    iError=m_I2C.write(_address);// send adress of i2c slave
+// Wire.write(reg);
+    if (iError==1) {
 
-  //Wire.beginTransmission(_address);   
-  (void) m_I2C.start();
-  iError=m_I2C.write(_address);// send adress of i2c slave
- // Wire.write(reg);
-  if (iError==1){
-      
-    iError= m_I2C.write(reg);
-  
- // Wire.write(value);
-  (void) m_I2C.write(value);
-  }
- // return Wire.endTransmission();  
+        iError= m_I2C.write(reg);
+
+// Wire.write(value);
+        (void) m_I2C.write(value);
+    }
+// return Wire.endTransmission();
     m_I2C.stop();// return stop error code
-     if (iError==1) iError=0;// ack received
-  else iError=1;// no ack
-  return iError;
+    if (iError==1) iError=0;// ack received
+    else iError=1;// no ack
+    wait_ms(1);
+    return iError;
 }
 
 /* ======================================================================
 Function: readRegister
-Purpose : read a register address value on m_I2C bus 
+Purpose : read a register address value on m_I2C bus
 Input   : register address
           pointer where the return value will be filled
 Output  : Arduino Wire library return code (0 if ok)
-Comments: 
+Comments:
 ====================================================================== */
 uint8_t TH02::readRegister(uint8_t reg, uint8_t * value)
 {
-  uint8_t ret ;
-  int iAck,iRedVal,iError;
-  // Send a register reading command
-  // but DO NOT release the m_I2C bus
- // (void) m_I2C.start();
- // iError=m_I2C.write(_address);// send adress of i2c slave
-  
-  //if (iError==1)
-  
-  ret = writeCommand(reg, false);
+    uint8_t ret ;
+    int iAck,iRedVal,iError;
+    // Send a register reading command
+    // but DO NOT release the m_I2C bus
+// (void) m_I2C.start();
+    //iError=m_I2C.write(_address);// send adress of i2c slave
+
+    //if (iError==1) // ack received
+    //{
+    ret = writeCommand(reg, false);// no stop
 
-  if ( ret == 0) //if command ok
-  {
-   // Wire.requestFrom( (uint8_t) _address, (uint8_t) 1);
-   (void) m_I2C.start();
-  iError=m_I2C.write(_address+0x01);// send adress of i2c slave in read mode  
-iRedVal=m_I2C.read(0);//send non ack
-   // if (Wire.available() != 1)
-      /*if (iAck != 1)
-     
-      // Other error as Wire library
-      ret = 4;
-    else
-      // grab the value*/
-      *value = iRedVal; // return Red value by ref 
-       
-  //} 
-    
-  // Ok now we have finished
- // Wire.endTransmission();
- 
- }
- (void) m_I2C.stop();// return stop error code
-  return ret;
-} 
+    if ( ret == 0) { //if command ok
+        // Wire.requestFrom( (uint8_t) _address, (uint8_t) 1);
+        (void) m_I2C.start();
+        iError=m_I2C.write(_address+0x01);// send adress of i2c slave in read mode
+        *value =m_I2C.read(0);//send non ack
+        // if (Wire.available() != 1)
+        /*if (iAck != 1)
+
+        // Other error as Wire library
+        ret = 4;
+        else
+        // grab the value*/
+        //   *value = iRedVal; // return Red value by ref
+
+        //}
+
+        // Ok now we have finished
+// Wire.endTransmission();
+
+    }
+    (void) m_I2C.stop();// return stop error code
+    wait_ms(1);
+    return ret;
+}
 
 /* ======================================================================
 Function: getId
-Purpose : Get device ID register  
+Purpose : Get device ID register
 Input   : pointer where the return value will be filled
 Output  : Arduino Wire library return code (0 if ok)
 Comments: -
 ====================================================================== */
 uint8_t TH02::getId(uint8_t * pvalue)
 {
-  return (readRegister(TH02_ID, pvalue));
+    return (readRegister(TH02_ID, pvalue));
 }
 
 /* ======================================================================
 Function: getStatus
-Purpose : Get device status register  
+Purpose : Get device status register
 Input   : pointer where the return value will be filled
 Output  : Arduino Wire library return code (0 if ok)
-Comments: 
+Comments:
 ====================================================================== */
 uint8_t TH02::getStatus(uint8_t * pvalue)
 {
-  return (readRegister(TH02_STATUS, pvalue));
+    return (readRegister(TH02_STATUS, pvalue));
 }
 
 /* ======================================================================
 Function: isConverting
-Purpose : Indicate if a temperature or humidity conversion is in progress  
+Purpose : Indicate if a temperature or humidity conversion is in progress
 Input   : -
 Output  : true if conversion in progress false otherwise
-Comments: 
+Comments:
 ====================================================================== */
 bool TH02::isConverting(void)
 {
-  uint8_t status;
-  // Get status and check RDY bit
-  if ( getStatus(&status) == 0)
-    
-    { printf("\n lecture status %x",status);
-    if ( (status & TH02_STATUS_RDY) ==1 )
-      return true;
-}
-  return false;
+    uint8_t status;
+    // Get status and check RDY bit
+    if ( getStatus(&status) == 0)
+
+    {
+       // printf("\n lecture status %x",status);
+        if ( (status & TH02_STATUS_RDY) ==1 )
+            return true;
+    }
+    return false;
 }
 
 /* ======================================================================
 Function: getConfig
-Purpose : Get device configuration register  
+Purpose : Get device configuration register
 Input   : pointer where the return value will be filled
 Output  : Arduino Wire library return code (0 if ok)
-Comments: 
+Comments:
 ====================================================================== */
 uint8_t TH02::getConfig(uint8_t * pvalue)
 {
-  return (readRegister(TH02_CONFIG, pvalue));
+    return (readRegister(TH02_CONFIG, pvalue));
 }
 
 /* ======================================================================
 Function: setConfig
-Purpose : Set device configuration register  
+Purpose : Set device configuration register
 Input   : value to set
 Output  : true if succeded, false otherwise
-Comments: 
+Comments:
 ====================================================================== */
 uint8_t TH02::setConfig(uint8_t config)
 {
-  return (writeRegister(TH02_CONFIG, config));
+    return (writeRegister(TH02_CONFIG, config));
 }
 
 /* ======================================================================
 Function: startTempConv
-Purpose : Start a temperature conversion  
+Purpose : Start a temperature conversion
 Input   : - fastmode true to enable fast conversion
           - heater true to enable heater
 Output  : true if succeded, false otherwise
@@ -221,20 +229,20 @@
 ====================================================================== */
 uint8_t TH02::startTempConv(bool fastmode, bool heater)
 {
-  // init configuration register to start and temperature
-  uint8_t config = TH02_CONFIG_START | TH02_CONFIG_TEMP;
-  
-  // set fast mode and heater if asked
-  if (fastmode) config |= TH02_CONFIG_FAST;
-  if (heater)   config |= TH02_CONFIG_HEAT;
-  
-  // write to configuration register
-  return ( setConfig( config ) );
+    // init configuration register to start and temperature
+    uint8_t config = TH02_CONFIG_START | TH02_CONFIG_TEMP;
+
+    // set fast mode and heater if asked
+    if (fastmode) config |= TH02_CONFIG_FAST;
+    if (heater)   config |= TH02_CONFIG_HEAT;
+
+    // write to configuration register
+    return ( setConfig( config ) );
 }
 
 /* ======================================================================
 Function: startRHConv
-Purpose : Start a relative humidity conversion  
+Purpose : Start a relative humidity conversion
 Input   : - fastmode true to enable fast conversion
           - heater true to enable heater
 Output  : true if succeded, false otherwise
@@ -242,64 +250,63 @@
 ====================================================================== */
 uint8_t TH02::startRHConv(bool fastmode, bool heater)
 {
-  // init configuration register to start and no temperature (so RH)
-  uint8_t config = TH02_CONFIG_START;
-  
-  // set fast mode and heater if asked
-  if (fastmode) config |= TH02_CONFIG_FAST;
-  if (heater)   config |= TH02_CONFIG_HEAT;
-  
-  // write to configuration register
-  return ( setConfig( config ) );
+    // init configuration register to start and no temperature (so RH)
+    uint8_t config = TH02_CONFIG_START;
+
+    // set fast mode and heater if asked
+    if (fastmode) config |= TH02_CONFIG_FAST;
+    if (heater)   config |= TH02_CONFIG_HEAT;
+
+    // write to configuration register
+    return ( setConfig( config ) );
 }
 
 /* ======================================================================
 Function: waitEndConversion
-Purpose : wait for a temperature or RH conversion is done  
-Input   : 
-Output  : delay in ms the process took. 
+Purpose : wait for a temperature or RH conversion is done
+Input   :
+Output  : delay in ms the process took.
 Comments: if return >= TH02_CONVERSION_TIME_OUT, time out occured
 ====================================================================== */
 uint8_t TH02::waitEndConversion(void)
 {
-  // okay this is basic approach not so accurate
-  // but avoid using long and millis()
-  uint8_t time_out = 0;
-  
-  // loop until conversion done or duration >= time out
-  while (isConverting() && time_out <= TH02_CONVERSION_TIME_OUT )
-  {
-    ++time_out;
-    wait_ms(1);
-  }
-  
-  // return approx time of conversion
-  return (time_out);
+    // okay this is basic approach not so accurate
+    // but avoid using long and millis()
+    uint8_t time_out = 0;
+
+    // loop until conversion done or duration >= time out
+    while (isConverting() && (time_out <= TH02_CONVERSION_TIME_OUT) ) {
+        ++time_out;
+        wait_ms(2);
+    }
+
+    // return approx time of conversion
+    return (time_out);
 }
 
 /* ======================================================================
 Function: roundInt
-Purpose : round a float value to int  
+Purpose : round a float value to int
 Input   : float value
-Output  : int value rounded 
-Comments: 
+Output  : int value rounded
+Comments:
 ====================================================================== */
 int16_t TH02::roundInt(float value)
-{  
+{
 
-  // check positive number and do round
-  if (value >= 0.0f)
-    value = floor(value + 0.5f);
-  else
-    value = ceil(value - 0.5f);
-    
-  // return int value
-  return (static_cast<int16_t>(value));
+    // check positive number and do round
+    if (value >= 0.0f)
+        value = floor(value + 0.5f);
+    else
+        value = ceil(value - 0.5f);
+
+    // return int value
+    return (static_cast<int16_t>(value));
 }
 
 /* to avoid math library may I need to test something
    like that
-float TH02::showDecimals(float x, int numDecimals) 
+float TH02::showDecimals(float x, int numDecimals)
 {
     int y=x;
     double z=x-y;
@@ -310,9 +317,10 @@
 }
 */
 
+
 /* ======================================================================
 Function: getConversionValue
-Purpose : return the last converted value to int * 10 to have 1 digit prec.  
+Purpose : return the last converted value to int * 10 to have 1 digit prec.
 Input   : float value
 Output  : value rounded but multiplied per 10 or TH02_UNDEFINED_VALUE on err
 Comments: - temperature and rh raw values (*100) are stored for raw purpose
@@ -320,157 +328,152 @@
             a temperature or humidity conversion
 ====================================================================== */
 int16_t TH02::getConversionValue(void)
-{ char cMaChaine[3];
-int iError;
-  int32_t result=0 ;
-  uint8_t config;
-  int16_t  ret = TH02_UNDEFINED_VALUE;
- 
-  // Prepare reading address of ADC data result
-  if ( writeCommand(TH02_DATAh, false) == 0 )
-  {
+{
+    char cMaChaine[4];
+    int iError;
+    int32_t result=0 ;
+    uint8_t config;
+    int16_t  ret = TH02_UNDEFINED_VALUE;
+
+    // Prepare reading address of ADC data result
+    /*if ( writeCommand(TH02_DATAh, false) == 0 ) // no stop
+    {*/
     // Read 2 bytes adc data result MSB and LSB from TH02
     //Wire.requestFrom( (uint8_t) _address, (uint8_t) 2);
-    
-    
-iError= m_I2C.read (_address,cMaChaine,2,false);
+    writeCommand(TH02_DATAh, false);
 
- 
+    // read of two register
+    (void) m_I2C.start();
+    iError=m_I2C.write(_address+1);// send adress of i2c slave read mode
+    if (iError==1) {
+        cMaChaine[0]= m_I2C.read(1);// read first byte with ack
+        cMaChaine[1]=m_I2C.read(0);// read first byte without ack
+       
+      m_I2C.stop();// rperform stop
+
 
 
-    // we got 2 bytes ?
-   // if (Wire.available() == 2)
-   if (iError == 0   )
-    {
-      // convert number
-     // result  = Wire.read() << 8;
-     //   result |= Wire.read();
-result=(cMaChaine[0]<<8 )|cMaChaine[1];
-      // Get configuration to know what was asked last time
-      if (getConfig(&config)==0)
-      {
-        // last conversion was temperature ?
-        if( config & TH02_CONFIG_TEMP)
-        {
-          result >>= 2;  // remove 2 unused LSB bits
-          result *= 100; // multiply per 100 to have int value with 2 decimal
-          result /= 32;  // now apply datasheet formula
-          if(result >= 5000)
-          {
-            result -= 5000;
-          }
-          else
-          {
-            result -= 5000;
-            result = -result;
-          }
-          
-          // now result contain temperature * 100
-          // so 2134 is 21.34 C
-          
-          // Save raw value 
-          _last_temp = result;
+        //iError= m_I2C.read (_address,cMaChaine,4,false);// send stop at end
+       // printf (" \n\r lecture I2C: %02x %02x",cMaChaine[0],cMaChaine[1]);
+      //}
+       result=(cMaChaine[0]<<8 )|cMaChaine[1];
+        // Get configuration to know what was asked last time
+       
+        if (getConfig(&config)==0) {
+            // last conversion was temperature ?
+            if( config & TH02_CONFIG_TEMP) {
+                result >>= 2;  // remove 2 unused LSB bits
+                result *= 100; // multiply per 100 to have int value with 2 decimal
+                result /= 32;  // now apply datasheet formula
+                if(result >= 5000) {
+                    result -= 5000;
+                } else {
+                    result -= 5000;
+                    result = -result;
+                }
+
+                // now result contain temperature * 100
+                // so 2134 is 21.34 C
+
+                // Save raw value
+                _last_temp = result;
+            }
+            // it was RH conversion
+            else {
+                result >>= 4;  // remove 4 unused LSB bits
+                result *= 100; // multiply per 100 to have int value with 2 decimal
+                result /= 16;  // now apply datasheet formula
+                result -= 2400;
+
+                // now result contain humidity * 100
+                // so 4567 is 45.67 % RH
+                _last_rh = result;
+            }
+
+            // remember result value is multiplied by 10 to avoid float calculation later
+            // so humidity of 45.6% is 456 and temp of 21.3 C is 213
+        ret = roundInt(result/10.0f);
         }
-        // it was RH conversion
-        else
-        {
-          result >>= 4;  // remove 4 unused LSB bits
-          result *= 100; // multiply per 100 to have int value with 2 decimal
-          result /= 16;  // now apply datasheet formula
-          result -= 2400;
-
-          // now result contain humidity * 100
-          // so 4567 is 45.67 % RH
-          _last_rh = result;
-        }
+     }   
+     
+     else{
+         
+      m_I2C.stop();// rperform stop
+      }
+    return ret;
+}
 
-        // remember result value is multiplied by 10 to avoid float calculation later
-        // so humidity of 45.6% is 456 and temp of 21.3 C is 213
-        ret = roundInt(result/10.0f);
-      }
-    } // if got 2 bytes from m_I2C
+
 
-    // Ok now we have finished with m_I2C, release
-    //Wire.endTransmission();
-    
 
-  } // if write command TH02_DATAh
-(void) m_I2C.stop();
-  return ret;
-}
 
 /* ======================================================================
 Function: getConpensatedRH
-Purpose : return the compensated calulated humidity  
+Purpose : return the compensated calulated humidity
 Input   : true if we want to round value to 1 digit precision, else 2
 Output  : the compensed RH value (rounded or not)
-Comments: 
+Comments:
 ====================================================================== */
 int16_t TH02::getConpensatedRH(bool round)
 {
-  float rhvalue  ;
-  float rhlinear ;
-  int16_t  ret = TH02_UNDEFINED_VALUE;
+    float rhvalue  ;
+    float rhlinear ;
+    int16_t  ret = TH02_UNDEFINED_VALUE;
 
-  // did we had a previous measure RH
-  if (_last_rh != TH02_UNINITIALIZED_RH)
-  {
-    // now we're float restore real value RH value
-    rhvalue = (float) _last_rh / 100.0 ;
-    
-    // apply linear compensation
-    rhlinear = rhvalue - ((rhvalue*rhvalue) * TH02_A2 + rhvalue * TH02_A1 + TH02_A0);
+    // did we had a previous measure RH
+    if (_last_rh != TH02_UNINITIALIZED_RH) {
+        // now we're float restore real value RH value
+        rhvalue = (float) _last_rh / 100.0 ;
+
+        // apply linear compensation
+        rhlinear = rhvalue - ((rhvalue*rhvalue) * TH02_A2 + rhvalue * TH02_A1 + TH02_A0);
+
+        // correct value
+        rhvalue = rhlinear;
 
-    // correct value
-    rhvalue = rhlinear;
-    
-    // do we have a initialized temperature value ?
-    if (_last_temp != TH02_UNINITIALIZED_TEMP )
-    {
-      // Apply Temperature compensation
-      // remember last temp was stored * 100
-      rhvalue += ((_last_temp/100.0) - 30.0) * (rhlinear * TH02_Q1 + TH02_Q0);
+        // do we have a initialized temperature value ?
+        if (_last_temp != TH02_UNINITIALIZED_TEMP ) {
+            // Apply Temperature compensation
+            // remember last temp was stored * 100
+            rhvalue += ((_last_temp/100.0) - 30.0) * (rhlinear * TH02_Q1 + TH02_Q0);
+        }
+
+        // now get back * 100 to have int with 2 digit precision
+        rhvalue *= 100;
+
+        // do we need to round to 1 digit ?
+        if (round) {
+            // remember result value is multiplied by 10 to avoid float calculation later
+            // so humidity of 45.6% is 456
+            ret = roundInt(rhvalue/10.0f);
+        } else {
+            ret = (int16_t) rhvalue;
+        }
     }
-    
-    // now get back * 100 to have int with 2 digit precision
-    rhvalue *= 100;
-    
-    // do we need to round to 1 digit ?
-    if (round)
-    {
-      // remember result value is multiplied by 10 to avoid float calculation later
-      // so humidity of 45.6% is 456
-      ret = roundInt(rhvalue/10.0f);
-    }
-    else
-    {
-      ret = (int16_t) rhvalue;
-    }
-  }
-  
-  return ret;
+
+    return ret;
 }
 
 /* ======================================================================
 Function: getLastRawRH
-Purpose : return the raw humidity * 100  
-Input   : 
+Purpose : return the raw humidity * 100
+Input   :
 Output  : int value (ie 4123 for 41.23%)
-Comments: 
+Comments:
 ====================================================================== */
 int32_t TH02::getLastRawRH(void)
 {
-  return _last_rh; 
+    return _last_rh;
 }
 
 /* ======================================================================
 Function: getLastRawTemp
-Purpose : return the raw temperature value * 100  
-Input   : 
+Purpose : return the raw temperature value * 100
+Input   :
 Output  : int value (ie 2124 for 21.24 C)
-Comments: 
+Comments:
 ====================================================================== */
-int32_t TH02::getLastRawTemp(void) 
+int32_t TH02::getLastRawTemp(void)
 {
-  return _last_temp;
+    return _last_temp;
 }