1

I am trying to communicate with AT30TS75A-MA8M-T with below code, the problem is converting the 16 bit output to float so I can read temp:

Base on data sheet enter image description here I suppose to remove first 5 bit in order to read correctly but I am not converting it correctly.

Ex: (0b001001001100000 AND 0 b0111111111100000) = 0b1001001100000 0b1001001100000 >> 5 = 0b10010011 = 147

    void Atemp::begin()
{

    Wire.begin();

    // Check if sensor temp sensor is avilable

    // if (mySensor.beginI2C() == false)
    // {
    //     data[9] = 5; // Error Code
    // }
    // Set registor for two decimal
    Wire.beginTransmission(_i2cAddress);
    Wire.write(1);
    Wire.write(0b01100000);
    Wire.endTransmission();
}

void Atemp::read()
{
    Wire.beginTransmission(_i2cAddress);
    Wire.write(0);
    result = Wire.endTransmission();
    // result is 0-4
    if (result != 0)
    {
        data[9] = 5; // Error Code
    }

    result = Wire.requestFrom(_i2cAddress, (uint8_t)2);
    if (result != 2)
    {
        data[9] = 5; // Error Code
    }
    else
    {
        uint8_t part1 = Wire.read();
        uint8_t part2 = Wire.read();
        
        data[7] = part1;
         data[8] = part2;
        int16_t rawval = (part1 << 8 | part2) ;
        // rawval >>= 6;
        float temp = rawval / 256.0f;
        floatconv(temp);
    }
}

2 Answers 2

3

You need to do two things:

  1. Right-shift the data to align it to the right of the variable, and
  2. Multiply it by the value of one bit.

When right shifting be sure to do it in a signed data type so that C will sign extend the value and retain any negativeness to the value.

So taking the 12-bit examples from the datasheet you right shift 4 bits, so

SDDDDDDDDDDD0000

becomes

SSSSSDDDDDDDDDDD

(where S is the sign bit and D is a valid data bit, and 0 is padding)

Then simply multiply the value by 0.0625 to get the actual temperature.

In code that might look like:

int16_t rawval = part1 << 8 | part2;
rawval >>= 4; // Do this in the int16_t to preserve the sign
float temperature = rawval * 0.0625;

For different resolutions right shift by different amounts and multiply by the appropriate single-bit value for that resolution (hint: 11 bit is double the value of 12 bit, 10 bit is double the value of 11 bit, etc).

1
  • @Shahreza Page 10 of the datasheet. The resolution of the temperature measurement data can be configured to 9, 10, 11, or 12 bits which corresponds to temperature increments of 0.5̊C, 0.25̊C, 0.125̊C, and 0.0625̊C, respectively.
    – Majenko
    Aug 18 at 21:33
3

Just a complement to Majenko's answer. The temperature register is set in such a way that you can interpret it in the same way irrespective of the selected resolution:

int16_t rawval = part1 << 8 | part2;
float temperature = rawval * (1/256.0);
1
  • Good plan - didn't think of that ;)
    – Majenko
    Aug 18 at 21:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.