This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

LAUNCHXL-F28027 ADC calculations

Hello,

Can anyone help me to understand the following factors used in the example program for LaunchXL-28027 Example_F2802x0controlPadDemo.c.

The ADC calculations are 

// Useful definitions
#define ADC_FP_SCALE 32768 //Scale factor for Q15 fixed point numbers (2^15)
#define ADC_FP_ROUND ADC_FP_SCALE/2 //Added to Q15 numbers before converting to integer to round the number

// Amount to add to Q15 fixed point numbers to shift from Celsius to Kelvin
// (Converting guarantees number is positive, which makes rounding more efficient)
#define ADC_KELVIN 273
#define ADC_KELVIN_OFF (ADC_FP_SCALE * ADC_KELVIN)

// The folloing pointers to function calls are:
//Slope of temperature sensor (deg. C / ADC code). Stored in fixed point Q15 format.
#define ADC_getTempSlope() (*(int (*)(void))0x3D7E80)()
//ADC code corresponding to temperature sensor output at 0 deg. C
#define ADC_getTempOffset() (*(int (*)(void))0x3D7E83)()

//! \brief Converts a temperature sensor sample into a temperature in Celcius
//! \param[in] adcHandle The analog-to-digital converter (ADC) object handle
//! \return Temperature in degrees Celcius
inline int16_t ADC_getTemperatureC(ADC_Handle adcHandle, int16_t sensorSample)
{
return ((sensorSample - ADC_getTempOffset())*(int32_t)ADC_getTempSlope() + ADC_FP_ROUND + ADC_KELVIN_OFF)/ADC_FP_SCALE - ADC_KELVIN;
}

//! \brief Converts a temperature sensor sample into a temperature in Kelvin
//! \param[in] adcHandle The analog-to-digital converter (ADC) object handle
//! \return Temperature in degrees Kelvin
inline int16_t ADC_getTemperatureK(ADC_Handle adcHandle, int16_t sensorSample)
{
return ((sensorSample - ADC_getTempOffset())*(int32_t)ADC_getTempSlope() + ADC_FP_ROUND + ADC_KELVIN_OFF)/ADC_FP_SCALE;

Please help me to understand the calculations involved in details.

  • A quick sketch of how the calculations work is attached.  Essentially the sensor is being modeled as being linear with increasing ADC conversion results.  

    Everything is done in Q15 math, which essentially involves everything being multiplied by 2^15.  This is to give resolution after the decimal point.  e.g. if the slope is 0.12345, truncating it to an integer gives 0, which loses pretty much all the information.  Multiplying by 2^15, then truncating gives 4045, then dividing by 2^15 gives .123444, which is an acceptable amount of error.  

    To round in binary, you just add 1 to the bit below the decimal point.  If the bit is set, the fractional part is 0.5 or greater, and adding 1 will cause next highest bit to be incremented. If the bit is zero, the fractional part is less than 0.5, and the addition doesn't propagate.  

      

  • Hello Devin,

    Thanks for the reply. It was indeed helpful to understand the calculations. However I have some few basic questions.

    1) How is the temperature slope value calculated? #define ADC_getTempSlope() (*(int (*)(void))0x3D7E80)()

    How do you get #define 0x3D7E80)()

    2) How is the temperature offset value received to be 0x3D7E83

    3) I understand that to round up you are adding 0.5 to the number. Please explain this.

    4) Why is Q15 format chosen and not any other? Is it for the integer and mantissa part requirement?

  • Both the slope and offset are stored in OTP, with a wrapper function that returns the slope or offset value.  The getTempSlope is  a pointer to a function that returns and integer.  0x3D7E80 and 0x3D7E83 are the physical memory addresses of the slope and offset functions.  

    During production test of the device, at two different test insertions at two different temperatures, a sensor reading is taken and the actual temperature is logged.  From these two temperature points + sensor readings, the tester produces a slope and offset for the device and stores it in OTP along with the wrapper function.

    Adding binary 1 to the bit below the decimal point will round up or down, if the fractional part is >= 0.5 or <0.5, respectively.  You can convince yourself of this by working through converting some fixed point numbers to binary, adding the bit, and then converting back.  

    Q15 was chosen based on the possible range of the slope values.