Infrared Thermopile Sensor in Chip-Scale Package
Revision 4:56398c14bf1f, committed 2018-12-11
- 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 */