Search code examples
cembeddedsensors

DS18B20+ digital temperature sensor: how to process data from sensor output?


I need to convert data from sensor output encoded as 16-bit sign-extended two’s complement number into float value. Below information from sensor datasheet how it looks like: enter image description here

And this is my first idea how to do that:

/*
 * Author: Jakub Standarski
 * Email: [email protected]
 *
 * Date: 03.10.2020
 *
 */

/*****************************************************************************/
/* HEADERS */
/*****************************************************************************/

#include <stdint.h>
#include <stdio.h>
#include <string.h>



/*****************************************************************************/
/* PRIVATE VARIABLES */
/*****************************************************************************/

const float temperature_conversion_table[11] = {
    0.0625f, 0.125f, 0.25f, 0.5f, 1.0f, 2.0f, 4.0f, 8.0f, 16.0f, 32.0f, 64.0f};



/*****************************************************************************/
/* PRIVATE FUNCTIONS PROTOTYPES */
/*****************************************************************************/

static float convert_raw_data_into_temperature(int16_t sensor_raw_data);



/*****************************************************************************/
/* MAIN */
/*****************************************************************************/

int main(void)
{
    float temperature_value = convert_raw_data_into_temperature(0xFE6F);
    printf("%.4f\n", temperature_value);
    return 0;
}



/*****************************************************************************/
/* PRIVATE FUNCTIONS DEFINITIONS */
/*****************************************************************************/

static float convert_raw_data_into_temperature(int16_t sensor_raw_data)
{
    float temperature_value = 0.0f;

    int bit_index = 11;
    if ((sensor_raw_data & (1 << bit_index)) == 0) {
        for (bit_index = 10; bit_index >= 0; bit_index--) {
            if ((sensor_raw_data & (1 << bit_index)) != 0) {
                temperature_value += temperature_conversion_table[bit_index];
            }
        }
    } else {
        temperature_value -= temperature_conversion_table[10];
        for (bit_index = 9; bit_index >= 0; bit_index--) {
            if ((sensor_raw_data & (1 << bit_index)) != 0) {
                temperature_value += temperature_conversion_table[bit_index];
            }
        }
    }

    return temperature_value;
}

And now the question: Does it make any sense? Is there any better idea?

What I know, it works with test values, but I would like to know, whether there is some more elegant way to do that.


Solution

  • Try

    float temperature_value;
    
    temperature_value = (float)sensor_raw_data / 16.0f;