corrected TH02 sample program

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
superphil06
Date:
Fri Mar 17 10:13:49 2017 +0000
Commit message:
TH02_sample_program

Changed in this revision

.hg_archival.txt Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
th02.cpp Show annotated file Show diff for this revision Revisions of this file
th02.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hg_archival.txt	Fri Mar 17 10:13:49 2017 +0000
@@ -0,0 +1,5 @@
+repo: be9eabdeb9adf48cf15c1b93c9fd876fef657389
+node: 6e55b3b06458b51257b897bdbc17440831c79ef0
+branch: default
+latesttag: null
+latesttagdistance: 5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Mar 17 10:13:49 2017 +0000
@@ -0,0 +1,41 @@
+#include "mbed.h"
+#include "th02.h"
+
+
+
+DigitalOut myled(LED1);
+
+
+TH02 MyTH02 (p28,p27,TH02_I2C_ADDR<<1);// connect hsensor on RX2 TX2
+
+
+int main() {
+    int iTemp,iTime,iTempbrute,iRH,iRHbrute;
+    printf ("\n start reading TH02");
+  //MyTH02.startTempConv(true,true);
+    
+    
+    
+    while(1) {
+        MyTH02.startTempConv(true,true);
+       iTime= MyTH02.waitEndConversion();// wait until onversion  is done
+         printf ("\n time=%d",iTime);
+      iTempbrute= MyTH02.getConversionValue();
+        iTemp=MyTH02.getLastRawTemp();
+          printf ("\n temp value=%d  %d",iTemp,iTempbrute );
+          
+        MyTH02.startRHConv(true,true);
+       iTime= MyTH02.waitEndConversion();// wait until onversion  is done
+         printf ("\n time=%d",iTime);
+      iRHbrute= MyTH02.getConversionValue();
+        iRH=MyTH02.getLastRawRH();
+          printf ("\n RH value=%d  %d",iRH,iRHbrute );
+          
+          
+          wait_ms(1000);
+      
+      
+      
+      
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Fri Mar 17 10:13:49 2017 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/e1686b8d5b90
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/th02.cpp	Fri Mar 17 10:13:49 2017 +0000
@@ -0,0 +1,476 @@
+// **********************************************************************************
+// Driver definition for HopeRF TH02 temperature and humidity sensor
+// **********************************************************************************
+// Creative Commons Attrib Share-Alike License
+// You are free to use/extend this library but please abide with the CC-BY-SA license:
+// http://creativecommons.org/licenses/by-sa/4.0/
+//
+// For any explanation see TH02 sensor information at
+// http://www.hoperf.com/sensor/app/TH02.htm
+//
+// Code based on following datasheet
+// http://www.hoperf.com/upload/sensor/TH02_V1.1.pdf 
+//
+// Written by Charles-Henri Hallard (http://hallard.me)
+//
+// History : V1.00 2014-07-14 - First release
+//           V1.10 2015-04-13 - changed to Wire library instead of m_I2C
+//
+// All text above must be included in any redistribution.
+//
+// **********************************************************************************
+#include "th02.h"
+#include "mbed.h"
+#include "math.h"
+
+// 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
+}
+
+TH02::~TH02()
+{
+
+}
+
+
+
+/* ======================================================================
+Function: writeCommand
+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: 
+====================================================================== */
+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;
+}
+
+/* ======================================================================
+Function: writeRegister
+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: 
+====================================================================== */
+uint8_t TH02::writeRegister(uint8_t reg, uint8_t value)
+{   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){
+      
+    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;
+}
+
+/* ======================================================================
+Function: readRegister
+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: 
+====================================================================== */
+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);
+
+  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;
+} 
+
+/* ======================================================================
+Function: getId
+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));
+}
+
+/* ======================================================================
+Function: getStatus
+Purpose : Get device status register  
+Input   : pointer where the return value will be filled
+Output  : Arduino Wire library return code (0 if ok)
+Comments: 
+====================================================================== */
+uint8_t TH02::getStatus(uint8_t * pvalue)
+{
+  return (readRegister(TH02_STATUS, pvalue));
+}
+
+/* ======================================================================
+Function: isConverting
+Purpose : Indicate if a temperature or humidity conversion is in progress  
+Input   : -
+Output  : true if conversion in progress false otherwise
+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;
+}
+
+/* ======================================================================
+Function: getConfig
+Purpose : Get device configuration register  
+Input   : pointer where the return value will be filled
+Output  : Arduino Wire library return code (0 if ok)
+Comments: 
+====================================================================== */
+uint8_t TH02::getConfig(uint8_t * pvalue)
+{
+  return (readRegister(TH02_CONFIG, pvalue));
+}
+
+/* ======================================================================
+Function: setConfig
+Purpose : Set device configuration register  
+Input   : value to set
+Output  : true if succeded, false otherwise
+Comments: 
+====================================================================== */
+uint8_t TH02::setConfig(uint8_t config)
+{
+  return (writeRegister(TH02_CONFIG, config));
+}
+
+/* ======================================================================
+Function: startTempConv
+Purpose : Start a temperature conversion  
+Input   : - fastmode true to enable fast conversion
+          - heater true to enable heater
+Output  : true if succeded, false otherwise
+Comments: if heater enabled, it will not be auto disabled
+====================================================================== */
+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 ) );
+}
+
+/* ======================================================================
+Function: startRHConv
+Purpose : Start a relative humidity conversion  
+Input   : - fastmode true to enable fast conversion
+          - heater true to enable heater
+Output  : true if succeded, false otherwise
+Comments: if heater enabled, it will not be auto disabled
+====================================================================== */
+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 ) );
+}
+
+/* ======================================================================
+Function: waitEndConversion
+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);
+}
+
+/* ======================================================================
+Function: roundInt
+Purpose : round a float value to int  
+Input   : float value
+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));
+}
+
+/* to avoid math library may I need to test something
+   like that
+float TH02::showDecimals(float x, int numDecimals) 
+{
+    int y=x;
+    double z=x-y;
+    double m=pow(10,numDecimals);
+    double q=z*m;
+    double r=round(q);
+    return static_cast<double>(y)+(1.0/m)*r;
+}
+*/
+
+/* ======================================================================
+Function: getConversionValue
+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
+          - the configuration register is checked to see if last conv was
+            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 )
+  {
+    // 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);
+
+ 
+
+
+    // 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;
+        }
+        // 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);
+      }
+    } // 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  
+Input   : true if we want to round value to 1 digit precision, else 2
+Output  : the compensed RH value (rounded or not)
+Comments: 
+====================================================================== */
+int16_t TH02::getConpensatedRH(bool round)
+{
+  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);
+
+    // 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);
+    }
+    
+    // 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;
+}
+
+/* ======================================================================
+Function: getLastRawRH
+Purpose : return the raw humidity * 100  
+Input   : 
+Output  : int value (ie 4123 for 41.23%)
+Comments: 
+====================================================================== */
+int32_t TH02::getLastRawRH(void)
+{
+  return _last_rh; 
+}
+
+/* ======================================================================
+Function: getLastRawTemp
+Purpose : return the raw temperature value * 100  
+Input   : 
+Output  : int value (ie 2124 for 21.24 C)
+Comments: 
+====================================================================== */
+int32_t TH02::getLastRawTemp(void) 
+{
+  return _last_temp;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/th02.h	Fri Mar 17 10:13:49 2017 +0000
@@ -0,0 +1,122 @@
+// **********************************************************************************
+// Driver definition for HopeRF TH02 temperature and humidity sensor
+// **********************************************************************************
+// Creative Commons Attrib Share-Alike License
+// You are free to use/extend this library but please abide with the CC-BY-SA license:
+// http://creativecommons.org/licenses/by-sa/4.0/
+//
+// For any explanation see TH02 sensor information at
+// http://www.hoperf.com/sensor/app/TH02.htm
+//
+// Code based on following datasheet
+// http://www.hoperf.com/upload/sensor/TH02_V1.1.pdf 
+//
+// Written by Charles-Henri Hallard (http://hallard.me)
+//ported to mbed env by Philippe LAURENT (IUT de NICE France)
+//
+// History : V1.00 2014-07-14 - First release
+//           V1.10 2015-04-13 - changed to Wire library instead of I2C
+//
+// All text above must be included in any redistribution.
+//
+// **********************************************************************************
+#ifndef TH02_H
+#define TH02_H
+
+#include <mbed.h>            //
+
+// TH02 I2C Device address
+#define TH02_I2C_ADDR 0x40
+
+// TH02 Registers addresses
+#define TH02_STATUS 0
+#define TH02_DATAh  1
+#define TH02_DATAl  2
+#define TH02_CONFIG 3
+#define TH02_ID     17
+
+// TH02 custom error code return function
+#define TH02_I2C_ERR 0xFF
+
+// Unititialized values (arbitrary)
+#define TH02_UNINITIALIZED_TEMP 55555 // int32_t internal value 
+#define TH02_UNINITIALIZED_RH   1111  // int32_t internal value
+#define TH02_UNDEFINED_VALUE    12345 // int16_t returned value
+
+// we decide error if conversion is >= 50ms 
+#define TH02_CONVERSION_TIME_OUT  50
+
+// Bit definition of TH02 registers values
+#define TH02_STATUS_RDY    0x01
+
+#define TH02_CONFIG_START  0x01
+#define TH02_CONFIG_HEAT   0x02
+#define TH02_CONFIG_TEMP   0x10
+#define TH02_CONFIG_HUMI   0x00
+#define TH02_CONFIG_FAST   0x20
+
+// THO2 Linearization Coefficients
+#define TH02_A0   -4.7844
+#define TH02_A1    0.4008
+#define TH02_A2   -0.00393
+
+// TH02 Temperature compensation Linearization Coefficients
+#define TH02_Q0   0.1973
+#define TH02_Q1   0.00237
+
+
+
+
+
+class TH02 { 
+  public:
+            TH02(uint8_t address);
+    uint8_t getId(uint8_t * pvalue);
+    uint8_t getId(void);
+    uint8_t getStatus(uint8_t * pvalue);
+    bool isConverting(void);
+    uint8_t waitEndConversion(void);
+    uint8_t getConfig(uint8_t * pvalue);
+    uint8_t setConfig(uint8_t config);
+    uint8_t startTempConv(bool fastmode = false, bool heater = false);
+    uint8_t startRHConv(bool fastmode = false, bool heater = false);
+    int16_t roundInt(float value);
+    int16_t getConversionValue(void);
+    int16_t getConpensatedRH(bool round);
+    int32_t getLastRawRH(void);
+    int32_t getLastRawTemp(void);
+
+/**
+  * TH02 constructor
+  *
+  * @param sda  I2C data pin
+  * @param scl  I2C clock pin
+  * @param address I2C slave sensor address
+
+  */
+  TH02(PinName sda, PinName scl, uint8_t address);
+
+  /**
+  * MFRC522 destructor
+  */
+  ~TH02();
+
+
+
+  private:
+I2C             m_I2C;
+    uint8_t writeCommand(uint8_t command, bool release=true);
+    uint8_t writeRegister(uint8_t reg, uint8_t value);
+    uint8_t readRegister(uint8_t reg, uint8_t * value);
+
+    int32_t _last_temp; // Last measured temperature (for linearization)
+    int32_t _last_rh;   // Last measured RH
+    uint8_t _address;   // I2C Module Address
+
+
+
+};
+
+  
+
+#endif
\ No newline at end of file