I2C -- 7 bit to 16 bit

Note: I2c, IIC, TWI is the same thing. They rely on two wires: SDA, and SCL.
If you have no idea what IIC but knows how to combine bytes to short, you can read along.
If you know what is IIC but you don’t know how to combine bytes to short, maybe consider the voltage problem at the bottom.
Anyway, on the datasheet of the sensor here:

(note: the following is not a homework. It’s just a small project I throwed in during thanksgiving since I can find zero operational thermometer in my home)

On this pdf (you can click on it, it’s a safe pdf file), there is the datasheet (of course) that give me the values that I must know in order to send commands to it (which I had done in my first rudimentary “environment scan”).
Go to page 13. I had questions with section 4.12 and 4.13 and I wanted to make certain that what I am thinking is correct.

In section 4.12, the checksum is used to evaluate the integrity of the data. How that CRC-8 is carried out (as in, mathematical operations), I do not know. It’d be glad if there is some … diagrams or the sort. Or I could sort it out myself later.

In sections 4.13, the … raw values from the sensor will be plugged into that described formula.
In various other places it also describe the data as “16 bit”. Unfortunately due to IIC-7 protocol the values are actually 7 +7 bits, which is 14 bit value instead of 16.
So how do I convert that?
Assume the first (of the two) values are 1011101 and the second one 1010110, I assume this is what that looks like for a 16 bit integer (that represent the actual value):
0x00 1011101 1010110 (except the spaces in between)
correct me if I am wrong.
I also assume that the compiler will convert 10011101 into 0x010011101 and not 0x100111010.

I had (and used) the following bit of code from Stackoverflow (which might be wrong):

byte c = Wire.read();    // receive a byte as character
byte d = Wire.read();    // receive a byte as character
short e = ((c & 0xFF) << 8) | (d &0xFF);

And when I did that the sensor gave me … something like -23012 (decimal number).
Of course it couldn’t be negative thousands of degrees (either Fahrenheit or Celsius), so I put it in a programming calculator and >> 1, and I got 21373.
The trailing bit was 0, so we can left shift it by one and got my original value, -22790.
Assuming the first bit (of data) received is AAAAAAA, and second bit is BBBBBBB, I assume what I did in that case is this:


which means that no matter which way I put it it should be a positive number!
But it wasn’t, and I got a erroneous value (which I turned into a still-wrong one by right shift once)
I assume I will have to do this (and ignore the whatever 0xFF Stackoverflow had mentioned):

e = (c << 7) | d;

But I don’t think this is right, either.

Irrelevant: Previously I had operated this sensor on 5V on Arduino Leonardo. I had switched to 3v3 for use with my DUE board, but tell me what should I do. The voltage tolerance for the sensor is 2.8V to 5.5V.

Install a library for your sensor via Arduino IDE library manager, and use the library examples to read the sensor data.

Looking at the library source code will answer your questions re. reading raw values and evaluating the CRC.

For example check the library for the SHT31 here:


Install a library for your sensor via Arduino IDE
Why do I have to do that if I can do everything in my sketch, I have the datasheet right in front of me
Not including a library also means other people that don’t have that library can just download and upload the code to do the things. And if the code is reasonably formatted (at least, with some comments on the command values, for example), I don’t think it will be a hassle for someone else to modify the values anyway.

And, in fact, I had sorted it out myself. The link for the library will still be somewhat helpful, but now that I had already done it myself I don’t need to know the “how”.

The values are in fact 7 bit. It’s 7 bit unsigned integer and therefore just put them together. unsigned short e = (c << 8) | d; is what I used.