Infrared Thermopile Sensor in Chip-Scale Package
TMP006.cpp
- Committer:
- mcm
- Date:
- 2018-12-11
- Revision:
- 4:56398c14bf1f
- Parent:
- 3:f632c66b30df
File content as of revision 4:56398c14bf1f:
/** * @brief TMP006.c * @details Infrared Thermopile Sensor in Chip-Scale Package. * Functions file. * * * @return N/A * * @author Manuel Caballero * @date 10/December/2018 * @version 10/December/2018 The ORIGIN * @pre N/A * @warning N/A * @pre This code belongs to Nimbus Centre ( http://www.nimbus.cit.ie ). All rights reserved. */ #include "TMP006.h" TMP006::TMP006 ( PinName sda, PinName scl, uint32_t addr, uint32_t freq ) : _i2c ( sda, scl ) , _TMP006_Addr ( addr ) { _i2c.frequency( freq ); } TMP006::~TMP006() { } /** * @brief TMP006_GetManufacturerID ( TMP006_data_t* ) * * @details It gets the manufacturer ID. * * @param[in] N/A * * @param[out] myManufacturerID: Manufacturer ID. * * * @return Status of TMP006_GetManufacturerID. * * * @author Manuel Caballero * @date 10/December/2018 * @version 10/December/2018 The ORIGIN * @pre N/A. * @warning N/A. */ TMP006::TMP006_status_t TMP006::TMP006_GetManufacturerID ( TMP006_data_t* myManufacturerID ) { char cmd[] = { 0U, 0U }; uint32_t aux; /* Read the register */ cmd[0] = TMP006_MANUFACTURER_ID; aux = _i2c.write ( _TMP006_Addr, &cmd[0], 1U, true ); aux = _i2c.read ( _TMP006_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ) ); /* Parse data */ myManufacturerID->ManufacturerID = ( cmd[0] << 8U ); myManufacturerID->ManufacturerID |= cmd[1]; if ( aux == I2C_SUCCESS ) { return TMP006_SUCCESS; } else { return TMP006_FAILURE; } } /** * @brief TMP006_GetDeviceID ( TMP006_data_t* ) * * @details It gets the device ID. * * @param[in] N/A. * * @param[out] myDeviceID: Device ID. * * * @return Status of TMP006_GetDeviceID. * * * @author Manuel Caballero * @date 10/December/2018 * @version 10/December/2018 The ORIGIN * @pre N/A. * @warning N/A. */ TMP006::TMP006_status_t TMP006::TMP006_GetDeviceID ( TMP006_data_t* myDeviceID ) { char cmd[] = { 0U, 0U }; uint32_t aux; /* Read the register */ cmd[0] = TMP006_DEVICE_ID; aux = _i2c.write ( _TMP006_Addr, &cmd[0], 1U, true ); aux = _i2c.read ( _TMP006_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ) ); /* Parse data */ myDeviceID->DeviceID = ( cmd[0] << 8U ); myDeviceID->DeviceID |= cmd[1]; if ( aux == I2C_SUCCESS ) { return TMP006_SUCCESS; } else { return TMP006_FAILURE; } } /** * @brief TMP006_ReadConfigurationRegister ( TMP006_data_t* ) * * @details It reads the configuration register. * * @param[in] N/A * * @param[out] myConfReg: Configuration register value. * * * @return Status of TMP006_ReadConfigurationRegister. * * * @author Manuel Caballero * @date 10/December/2018 * @version 10/December/2018 The ORIGIN * @pre N/A. * @warning N/A. */ TMP006::TMP006_status_t TMP006::TMP006_ReadConfigurationRegister ( TMP006_data_t* myConfReg ) { char cmd[] = { 0U, 0U }; uint32_t aux; /* Read the register */ cmd[0] = TMP006_CONFIGURATION; aux = _i2c.write ( _TMP006_Addr, &cmd[0], 1U, true ); aux = _i2c.read ( _TMP006_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ) ); /* Parse data */ myConfReg->ConfigurationRegister = ( cmd[0] << 8U ); myConfReg->ConfigurationRegister |= cmd[1]; if ( aux == I2C_SUCCESS ) { return TMP006_SUCCESS; } else { return TMP006_FAILURE; } } /** * @brief TMP006_SoftwareReset ( void ) * * @details It performs a software reset. * * @param[in] N/A. * * @param[out] N/A. * * * @return Status of TMP006_SoftwareReset. * * * @author Manuel Caballero * @date 10/December/2018 * @version 10/December/2018 The ORIGIN * @pre N/A. * @warning N/A. */ TMP006::TMP006_status_t TMP006::TMP006_SoftwareReset ( void ) { char cmd[] = { 0U, 0U, 0U }; uint32_t aux; /* Read the register */ cmd[0] = TMP006_CONFIGURATION; aux = _i2c.write ( _TMP006_Addr, &cmd[0], 1U, true ); aux = _i2c.read ( _TMP006_Addr, &cmd[0], 2U ); /* Mask the option and update the register */ cmd[2] = cmd[1]; cmd[1] = ( ( cmd[0] & ~RST_BIT_MASK ) | RST_SOFTWARE_RESET ); cmd[0] = TMP006_CONFIGURATION; aux = _i2c.write ( _TMP006_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); if ( aux == I2C_SUCCESS ) { return TMP006_SUCCESS; } else { return TMP006_FAILURE; } } /** * @brief TMP006_SetModeOperation ( TMP006_mod_t ) * * @details It sets mode of operation. * * @param[in] myModeOpreation: Mode of operation ( low power mode ). * * @param[out] N/A. * * * @return Status of TMP006_SetModeOperation. * * * @author Manuel Caballero * @date 10/December/2018 * @version 10/December/2018 The ORIGIN * @pre N/A. * @warning N/A. */ TMP006::TMP006_status_t TMP006::TMP006_SetModeOperation ( TMP006_mod_t myModeOpreation ) { char cmd[] = { 0U, 0U, 0U }; uint32_t aux; /* Read the register */ cmd[0] = TMP006_CONFIGURATION; aux = _i2c.write ( _TMP006_Addr, &cmd[0], 1U, true ); aux = _i2c.read ( _TMP006_Addr, &cmd[0], 2U ); /* Mask the option and update the register */ cmd[2] = cmd[1]; cmd[1] = ( ( cmd[0] & ~MOD_MASK ) | myModeOpreation ); cmd[0] = TMP006_CONFIGURATION; aux = _i2c.write ( _TMP006_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); if ( aux == I2C_SUCCESS ) { return TMP006_SUCCESS; } else { return TMP006_FAILURE; } } /** * @brief TMP006_SetConversionRate ( TMP006_cr_t ) * * @details It sets conversion rate. * * @param[in] myConversionRate: Conversion rate. * * @param[out] N/A. * * * @return Status of TMP006_SetConversionRate. * * * @author Manuel Caballero * @date 10/December/2018 * @version 10/December/2018 The ORIGIN * @pre N/A. * @warning N/A. */ TMP006::TMP006_status_t TMP006::TMP006_SetConversionRate ( TMP006_cr_t myConversionRate ) { char cmd[] = { 0U, 0U, 0U }; uint32_t aux; /* Read the register */ cmd[0] = TMP006_CONFIGURATION; aux = _i2c.write ( _TMP006_Addr, &cmd[0], 1U, true ); aux = _i2c.read ( _TMP006_Addr, &cmd[0], 2U ); /* Mask the option and update the register */ cmd[2] = cmd[1]; cmd[1] = ( ( cmd[0] & ~CR_MASK ) | myConversionRate ); cmd[0] = TMP006_CONFIGURATION; aux = _i2c.write ( _TMP006_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); if ( aux == I2C_SUCCESS ) { return TMP006_SUCCESS; } else { return TMP006_FAILURE; } } /** * @brief TMP006_SetnDRDY_EnableBit ( TMP006_en_t ) * * @details It sets conversion rate. * * @param[in] myEnableBit: Enable bit pin behaviour. * * @param[out] N/A. * * * @return Status of TMP006_SetnDRDY_EnableBit. * * * @author Manuel Caballero * @date 10/December/2018 * @version 10/December/2018 The ORIGIN * @pre N/A. * @warning N/A. */ TMP006::TMP006_status_t TMP006::TMP006_SetnDRDY_EnableBit ( TMP006_en_t myEnableBit ) { char cmd[] = { 0U, 0U, 0U }; uint32_t aux; /* Read the register */ cmd[0] = TMP006_CONFIGURATION; aux = _i2c.write ( _TMP006_Addr, &cmd[0], 1U, true ); aux = _i2c.read ( _TMP006_Addr, &cmd[0], 2U ); /* Mask the option and update the register */ cmd[2] = cmd[1]; cmd[1] = ( ( cmd[0] & ~EN_MASK ) | myEnableBit ); cmd[0] = TMP006_CONFIGURATION; aux = _i2c.write ( _TMP006_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); if ( aux == I2C_SUCCESS ) { return TMP006_SUCCESS; } else { return TMP006_FAILURE; } } /** * @brief TMP006_GetRawTemperature ( TMP006_data_t* ) * * @details It reads raw temperature ( T_DIE ) value. * * @param[in] N/A * * @param[out] myRawTemperature: Raw temperature value. * * * @return Status of TMP006_GetRawTemperature. * * * @author Manuel Caballero * @date 10/December/2018 * @version 10/December/2018 The ORIGIN * @pre N/A. * @warning N/A. */ TMP006::TMP006_status_t TMP006::TMP006_GetRawTemperature ( TMP006_data_t* myRawTemperature ) { char cmd[] = { 0U, 0U }; uint32_t aux; /* Read the register */ cmd[0] = TMP006_LOCAL_TEMPERATURE; aux = _i2c.write ( _TMP006_Addr, &cmd[0], 1U, true ); aux = _i2c.read ( _TMP006_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ) ); /* Parse the data */ myRawTemperature->TemperatureRegister = cmd[0]; myRawTemperature->TemperatureRegister <<= 8U; myRawTemperature->TemperatureRegister |= cmd[1]; /* Temperature register is configured as a 14-bit value */ myRawTemperature->TemperatureRegister >>= 2U; if ( aux == I2C_SUCCESS ) { return TMP006_SUCCESS; } else { return TMP006_FAILURE; } } /** * @brief TMP006_GetRawSensorVoltage ( TMP006_data_t* ) * * @details It reads raw sensor voltage result ( V_SENSOR ) register. * * @param[in] N/A. * * @param[out] myRawVoltage: Raw sensor voltage value. * * * @return Status of TMP006_GetRawSensorVoltage. * * * @author Manuel Caballero * @date 10/December/2018 * @version 10/December/2018 The ORIGIN * @pre N/A. * @warning N/A. */ TMP006::TMP006_status_t TMP006::TMP006_GetRawSensorVoltage ( TMP006_data_t* myRawVoltage ) { char cmd[] = { 0U, 0U }; uint32_t aux; /* Read the register */ cmd[0] = TMP006_SENSOR_VOLTAGE; aux = _i2c.write ( _TMP006_Addr, &cmd[0], 1U, true ); aux = _i2c.read ( _TMP006_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ) ); /* Parse the data */ myRawVoltage->SensorVoltageResultRegister = cmd[0]; myRawVoltage->SensorVoltageResultRegister <<= 8U; myRawVoltage->SensorVoltageResultRegister |= cmd[1]; if ( aux == I2C_SUCCESS ) { return TMP006_SUCCESS; } else { return TMP006_FAILURE; } } /** * @brief TMP006_CalculateSensorVoltage ( TMP006_data_t* ) * * @details It calculates the real sensor voltage ( V_SENSOR ) value. * * @param[in] SensorVoltageResultRegister: Raw sensor voltage value. * * @param[out] myV_sensor: Real sensor voltage value. * * * @return Status of TMP006_CalculateSensorVoltage. * * * @author Manuel Caballero * @date 10/December/2018 * @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; /* Check if the sensor voltage value is negative, MSB = 1 */ if ( ( aux & 0x8000 ) == 0x8000 ) { aux = ~aux; aux += 1U; myDataPosNeg = 1U; } /* Parse the data */ myV_sensor->V_Sensor = (double)( aux * SVOL_1LSB / 1000000000.0 ); if ( myDataPosNeg == 1U ) { myV_sensor->V_Sensor *= -1.0; } return TMP006_SUCCESS; } /** * @brief TMP006_CalculateTemperature ( TMP006_data_t* ) * * @details It calculates the real temperature ( T_DIE ) value. * * @param[in] myRawTemperature: Raw temperature value. * * @param[out] myTemperature: Real Temperature value. * * * @return Status of TMP006_CalculateTemperature. * * * @author Manuel Caballero * @date 10/December/2018 * @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; /* Check if the temperature value is negative, MSB = 1 */ if ( ( aux & 0x2000 ) == 0x2000 ) { 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 return TMP006_SUCCESS; } /** * @brief TMP006_CalculateObjectTemperature ( TMP006_data_t* ) * * @details It calculates the real temperature ( T_DIE ) value. * * @param[in] myRawTemperature: Raw temperature value. * * @param[out] myObjTemperature: Real Object Temperature value. * * * @return Status of TMP006_CalculateObjectTemperature. * * * @author Manuel Caballero * @date 10/December/2018 * @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 ) { 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( ( myObjTemperature->TemperatureK - T_REF ), (double)2U ) ); /* Calculate the offset voltage */ 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( ( 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 ) + (double)( f_v_obj / s ) ) ); myObjTemperature->ObjectTemperatureC = ( myObjTemperature->ObjectTemperatureK - 273.15 ); return TMP006_SUCCESS; }