Infrared Thermopile Sensor in Chip-Scale Package

Files at this revision

API Documentation at this revision

Comitter:
mcm
Date:
Tue Dec 11 12:47:11 2018 +0000
Parent:
3:f632c66b30df
Commit message:
The driver was completed and tested ( NUCLEO-L152RE ), it works as expected

Changed in this revision

TMP006.cpp Show annotated file Show diff for this revision Revisions of this file
TMP006.h Show annotated file Show diff for this revision Revisions of this file
--- a/TMP006.cpp	Mon Dec 10 16:29:14 2018 +0000
+++ b/TMP006.cpp	Tue Dec 11 12:47:11 2018 +0000
@@ -502,12 +502,14 @@
  *
  * @author      Manuel Caballero
  * @date        10/December/2018
- * @version     10/December/2018   The ORIGIN
+ * @version     11/December/2018   Bug fixed. Negative values are taken into consideration
+ *              10/December/2018   The ORIGIN
  * @pre         N/A.
  * @warning     TMP006_GetRawSensorVoltage function must be called first.
  */
 TMP006::TMP006_status_t  TMP006::TMP006_CalculateSensorVoltage ( TMP006_data_t* myV_sensor  )
 {
+    uint8_t   myDataPosNeg  =   0U;
     uint16_t  aux  =   0U;
 
     aux  =   myV_sensor->SensorVoltageResultRegister;
@@ -517,12 +519,18 @@
     {
       aux   =  ~aux;
       aux  +=   1U;
+      
+      myDataPosNeg   =   1U;
     }
 
 
     /* Parse the data   */
-    myV_sensor->V_Sensor   =  (float)( aux * SVOL_1LSB / 1000000000.0 );                        
-
+    myV_sensor->V_Sensor   =  (double)( aux * SVOL_1LSB / 1000000000.0 );                        
+    
+    if ( myDataPosNeg == 1U )
+    {
+      myV_sensor->V_Sensor  *=  -1.0;
+    }
 
 
     return   TMP006_SUCCESS;
@@ -545,12 +553,14 @@
  *
  * @author      Manuel Caballero
  * @date        10/December/2018
- * @version     10/December/2018   The ORIGIN
+ * @version     11/December/2018   Bug fixed. Negative values are taken into consideration
+ *              10/December/2018   The ORIGIN
  * @pre         N/A.
  * @warning     TMP006_GetRawTemperature function must be called first.
  */
 TMP006::TMP006_status_t  TMP006::TMP006_CalculateTemperature ( TMP006_data_t* myTemperature  )
 {
+    uint8_t   myDataPosNeg  =   0U;
     uint16_t  aux  =   0U;
 
     aux  =   myTemperature->TemperatureRegister;
@@ -560,11 +570,19 @@
     {
       aux   =  ~aux;
       aux  +=   1U;
+      
+      myDataPosNeg   =   1U;
     }
 
 
     /* Parse the data   */
     myTemperature->TemperatureC   =  (float)( aux * TEMP_1LSB );                        // Celsius degrees
+    
+    if ( myDataPosNeg == 1U )
+    {
+      myTemperature->TemperatureC  *=  -1.0;
+    }
+    
     myTemperature->TemperatureK   =  (float)( myTemperature->TemperatureC + 273.15 );   // Kelvins degrees
 
 
@@ -589,27 +607,28 @@
  *
  * @author      Manuel Caballero
  * @date        10/December/2018
- * @version     10/December/2018   The ORIGIN
+ * @version     11/December/2018   Precision was increased from float to double
+ *              10/December/2018   The ORIGIN
  * @pre         N/A.
  * @warning     TMP006_CalculateTemperature and TMP006_GetRawSensorVoltage functions must be called first.
  */
 TMP006::TMP006_status_t  TMP006::TMP006_CalculateObjectTemperature ( TMP006_data_t* myObjTemperature  )
 {
-    float     s       =   0.0;
-    float     v_os    =   0.0;
-    float     f_v_obj =   0.0;
+    double     s       =   0.0;
+    double     v_os    =   0.0;
+    double     f_v_obj =   0.0;
 
     /* Claculate the sensitivity of the thermopile sensor  */
-    s  =   myObjTemperature->s0 * ( 1.0 + A1 * ( myObjTemperature->TemperatureK - T_REF ) + A2 * pow( (double)( myObjTemperature->TemperatureK - T_REF ), (double)2U ) );
+    s  =   myObjTemperature->s0 * ( 1.0 + A1 * ( myObjTemperature->TemperatureK - T_REF ) + A2 * pow( ( myObjTemperature->TemperatureK - T_REF ), (double)2U ) );
 
     /* Calculate the offset voltage  */
-    v_os   =   B0 + B1 * ( myObjTemperature->TemperatureK - T_REF ) + B2 * pow( (double)( myObjTemperature->TemperatureK - T_REF ), (double)2U );
+    v_os   =   B0 + B1 * (double)( myObjTemperature->TemperatureK - T_REF ) + B2 * pow( ( myObjTemperature->TemperatureK - T_REF ), (double)2U );
     
     /* Model the Seebeck coefficients of the thermopile  */
-    f_v_obj  =   ( myObjTemperature->V_Sensor - v_os ) + C2 * pow( (double)( myObjTemperature->V_Sensor - v_os ), (double)2U );
+    f_v_obj  =   ( myObjTemperature->V_Sensor - v_os ) + C2 * pow( ( myObjTemperature->V_Sensor - v_os ), (double)2U );
     
     /* Relates the radiant transfer of IR energy between the target object and the TMP006 and the conducted heat in the thermopile in the TMP006  */ 
-    myObjTemperature->ObjectTemperatureK    =  sqrt( sqrt( pow( (double)myObjTemperature->TemperatureK, (double)4U ) + ( f_v_obj / s ) ) );
+    myObjTemperature->ObjectTemperatureK    =  sqrt( sqrt( pow( (double)myObjTemperature->TemperatureK, (double)4U ) + (double)( f_v_obj / s ) ) );
     myObjTemperature->ObjectTemperatureC    =  ( myObjTemperature->ObjectTemperatureK - 273.15 );
 
 
--- a/TMP006.h	Mon Dec 10 16:29:14 2018 +0000
+++ b/TMP006.h	Tue Dec 11 12:47:11 2018 +0000
@@ -24,6 +24,148 @@
     Example:
 @code
 
+#include "mbed.h"
+#include "TMP006.h"
+
+TMP006 myTMP006 ( I2C_SDA, I2C_SCL, TMP006::TMP006_ADDRESS_ADR1_0_ADR0_0, 400000 );
+Serial pc       ( USBTX, USBRX );                                               // tx, rx
+
+DigitalOut  myled   ( LED1 );
+Ticker      newAction;
+
+
+
+//@brief Constants.
+ //
+
+
+//@brief Variables.
+ //
+volatile uint32_t myState;                                                      //!<   State that indicates when to perform an ADC sample    
+
+
+
+//
+  // @brief   FUNCTION PROTOTYPES
+  //
+void    changeDATA     ( void );
+
+
+
+
+//@brief FUNCTION FOR APPLICATION MAIN ENTRY.
+ //
+int main()
+{
+  TMP006::TMP006_status_t aux;
+  TMP006::TMP006_data_t   myTMP006_Data;
+
+  pc.baud ( 115200 );
+
+
+  myled   =   1;
+  wait(3);
+  myled   =   0;
+
+  // Reset the device by software  
+  aux  =   myTMP006.TMP006_SoftwareReset ();
+  
+  // Wait until the device is ready  
+  do
+  {
+    // Read configuration register  
+    aux  =   myTMP006.TMP006_ReadConfigurationRegister ( &myTMP006_Data );
+  }while ( ( myTMP006_Data.ConfigurationRegister & TMP006::RST_BIT_MASK ) != TMP006::RST_NORMAL_OPERATION );    // [TODO]       This is DANGEROUS, if something goes wrong, the uC will get stuck here!!!.
+                                                                                                                // [WORKAROUND] Insert a timeout.
+  // Turn off the device  
+  aux  =   myTMP006.TMP006_SetModeOperation ( TMP006::MOD_POWER_DOWN );
+
+  // Get manufacturer ID 
+  aux  =   myTMP006.TMP006_GetManufacturerID ( &myTMP006_Data );
+  pc.printf ( "Manufacturer ID: %02x\r\n", myTMP006_Data.ManufacturerID );
+
+  // Get device ID 
+  aux  =   myTMP006.TMP006_GetDeviceID       ( &myTMP006_Data );
+  pc.printf ( "Device ID: %02x\r\n", myTMP006_Data.DeviceID );
+  
+  // Conversion Rate: 1 conversions/sec ( 4 averaged samples )
+  aux  =   myTMP006.TMP006_SetConversionRate ( TMP006::CR_4_AVERAGED_SAMPLES );
+
+  // Disbale #DRDY pin 
+  aux  =   myTMP006.TMP006_SetnDRDY_EnableBit ( TMP006::EN_nDRDY_PIN_DISABLED );
+
+  // Turn on the device  
+  aux  =   myTMP006.TMP006_SetModeOperation ( TMP006::MOD_SENSOR_AND_DIE_CONT_CONVERSION );
+    
+    
+  myState  =   0UL;                                                             // Reset the variable
+  newAction.attach( &changeDATA, 1U );                                          // the address of the function to be attached ( changeDATA ) and the interval ( 1s )
+
+  
+  // Let the callbacks take care of everything
+  while(1) {
+      sleep();
+
+      if ( myState == 1UL ) {
+        myled = 1U;
+
+        // Wait until a new data is ready to be read  
+        do
+        {
+            // Read configuration register  
+            aux  =   myTMP006.TMP006_ReadConfigurationRegister ( &myTMP006_Data );
+        }while ( ( myTMP006_Data.ConfigurationRegister & TMP006::nDRDY_MASK ) == TMP006::nDRDY_CONVERSION_IN_PROGRESS );    // [TODO]       This is DANGEROUS, if something goes wrong, the uC will get stuck here!!!.
+                                                                                                                            // [WORKAROUND] Insert a timeout.
+        // Get raw temperature ( T_DIE ) 
+        aux  =   myTMP006.TMP006_GetRawTemperature           ( &myTMP006_Data );
+
+        // Get raw sensor voltage result ( V_SENSOR ) 
+        aux  =   myTMP006.TMP006_GetRawSensorVoltage         ( &myTMP006_Data );
+
+        // Calculate temperature ( T_DIE ) 
+        aux  =   myTMP006.TMP006_CalculateTemperature        ( &myTMP006_Data );
+
+        // Calculate object temperature ( T_OBJ ) 
+        myTMP006_Data.s0   =   S0;                                                                                          // Typical values for S0 are between 5×10^–14 and 7×10^–14
+        aux  =   myTMP006.TMP006_CalculateObjectTemperature  ( &myTMP006_Data );
+
+
+        // Transmit result through the UART  
+        pc.printf ( "T_DIE: %0.5f C | T_OBJ: %0.5f C\r\n", myTMP006_Data.TemperatureC, myTMP006_Data.ObjectTemperatureC );
+
+
+        // Reset the variables   
+        myState  =   0UL;
+        myled    =   0U;
+      }
+  }
+}
+
+
+
+//
+ // @brief       changeDATA ( void  )
+ //
+ // @details     It changes myState variable
+ //
+ // @param[in]    N/A
+ //
+ // @param[out]   N/A.
+ //
+ //
+ // @return       N/A.
+ //
+ //
+ // @author      Manuel Caballero
+ // @date        10/December/2018
+ // @version     10/December/2018   The ORIGIN
+ // @pre         N/A
+ // @warning     N/A.
+ //
+void changeDATA ( void )
+{
+  myState  =   1UL;
+}
 @endcode
 */
 
@@ -150,16 +292,16 @@
   * @brief   CONSTANS TO BE USED IN THE FORMULAS
   *           NOTE: User Guide ( sbou107.pdf ) 5.1 Equations for Calculating Target Object Temperatures, p10.
   */
-#define A1        0.00175                                               /*!<  A1                                                                */
-#define A2        -0.00001678                                           /*!<  A2                                                                */
-#define T_REF     298.15                                                /*!<  T_REF, Kelvin                                                     */
-#define B0        -0.0000294                                            /*!<  B0                                                                */
-#define B1        -0.00000057                                           /*!<  B1                                                                */
-#define B2        -0.00000000463                                        /*!<  B2                                                                */
-#define C2        13.4                                                  /*!<  C2                                                                */
-#define S0        ( ( 0.00000000000005 + 0.00000000000007 ) / 2.0 )     /*!<  Primary calibration sensitivity factor ( mean of typical values ) */
-#define TEMP_1LSB 0.03125                                               /*!<  Temperature: 1 LSB = 1 / 32°C = 0.03125                           */
-#define SVOL_1LSB 156.25                                                /*!<  Sensor voltage: 1 LSB = 156.25 nV                                 */
+#define A1        (double)0.00175                                               /*!<  A1                                                                */
+#define A2        (double)-0.00001678                                           /*!<  A2                                                                */
+#define T_REF     (double)298.15                                                /*!<  T_REF, Kelvin                                                     */
+#define B0        (double)-0.0000294                                            /*!<  B0                                                                */
+#define B1        (double)-0.00000057                                           /*!<  B1                                                                */
+#define B2        (double)-0.00000000463                                        /*!<  B2                                                                */
+#define C2        (double)13.4                                                  /*!<  C2                                                                */
+#define S0        (double)( ( 0.00000000000005 + 0.00000000000007 ) / 2.0 )     /*!<  Primary calibration sensitivity factor ( mean of typical values ) */
+#define TEMP_1LSB (double)0.03125                                               /*!<  Temperature: 1 LSB = 1 / 32°C = 0.03125                           */
+#define SVOL_1LSB (double)156.25                                                /*!<  Sensor voltage: 1 LSB = 156.25 nV                                 */
 
 
 #ifndef TMP006_VECTOR_STRUCT_H
@@ -171,8 +313,8 @@
 
     float    TemperatureK;                  /*!<  T_DIE in Kelvins degrees                                                         */
     float    TemperatureC;                  /*!<  T_DIE in Celsius degrees                                                         */
-    float    V_Sensor;                      /*!<  Sensor voltage result                                                            */
-    float    s0;                            /*!<  Primary calibration sensitivity factor ( typical values: 5×10^–14 and 7×10^–14 ) */
+    double   V_Sensor;                      /*!<  Sensor voltage result                                                            */
+    double   s0;                            /*!<  Primary calibration sensitivity factor ( typical values: 5×10^–14 and 7×10^–14 ) */
 
     uint16_t SensorVoltageResultRegister;   /*!<  V_sensor                                                                         */
     uint16_t TemperatureRegister;           /*!<  T_DIE                                                                            */