Electronic – Microchip 9808 temperature sensor – Incorrect calculation result

ci2cmicrochiptemperature

I am using a Microchip MCP9808 I2C temperature sensor (https://learn.adafruit.com/adafruit-mcp9808-precision-i2c-temperature-sensor-guide/overview).

I'm having problems being able to calculate the temperature using the values I'm reading from the sensor.

The temperature is 13 bits wide. According to the datasheet, I need to send two read commands, the first read to return the upper byte and the second read will return the lower byte. 3 of the remaining bits are used to indicate temperature alarms, and 1 bit is used to indicate the sign of the reading (positive or negative).

I'm able to read the two bytes, by using the sample code from the datasheet as a starting point. However, the values I'm getting from it are incorrect. I'm also unable to get negative temperatures, so I think my code has something wrong with it.

I'm using a USB->I2C adaptor, and I've written a C# implementation of the datasheet sample code to calculate the temperature.

enter image description here

And then my code (which apart from some extra necessary castings due to the way C# handles data types) I think is identical.

    public static double CalculateAmbientTemperature(byte upperByte, byte lowerByte)
    {
        const byte ALERT_MASK_VALUE = 0x1F;
        const byte CLEAR_SIGN_MASK = 0x0F;

        double temperature = 0.00;

        upperByte = (byte)(upperByte & ALERT_MASK_VALUE);

        // Ambient temperature less than 0 degrees
        if((upperByte & (byte)(upperByte & 0x10)) == 0x10)
        {
            upperByte = (byte)(upperByte & CLEAR_SIGN_MASK);
            temperature = 256.0 - ((double)upperByte * 16.0 + (double)lowerByte / 16.0);
        }
        else
        {
            temperature = ((double)upperByte * 16.0 + (double)lowerByte / 16.0);
        }

        return temperature;
    }

So to test the code, I've been sending the bytes: START_BIT 0x3E (the address) 0x05 (the address of the temperature register) This tells the sensor to point the register pointer at the temperature register, so that when I send the two read commands, it reads from that register.

And when I read the data back, I'm getting 0xC1 0x24. When I pass these values to the function, I'm getting 17.0625 degrees C. Bearing in mind, I'm holding an ice cube on the sensor. (Currently don't have a more precise way). So basically, my calculation is faulty but I don't know where to begin with fixing it.

Any help would be appreciated.

(EDIT: To check I'm able to read the chip correctly, I read the Manufacturer ID register and get back the expected 0x54)

Best Answer

I've run into this problem myself recently. The error originates from the manufacturer's datasheet. When the 'negative' flag is set the proper computation is:

temp -= 256;  // correct!

instead of

temp = 256 - temp;  // incorrect! But this is the example in the datasheet!

Here are a couple examples of control code for the MCP9808 on Github:

lexruee/mcp9808

adafruit/Adafruit_MCP9808_Library