LM75 sensor/The reading/03. Degrees in two bytes
The reading · 03 of 9

Degrees in two bytes

Ask the chip for register 0 and it sends two bytes: the whole degrees, then the fraction. Read together as one signed 16-bit number they are 256 times the temperature, above zero and below it. The common way of reading them loses the sign on a 32-bit board and reports frost as 250 degrees.

What the chip sends

The LM75B keeps four registers. Register 0 is the temperature, and at power-up it is the one selected, so a read with no request first gets it. The sketch asks for it by name anyway: one byte, 0x00, then a request for two bytes back.

Degrees in two bytes
0x1580
Temperature21.500 °C
Read it as
Bytes
0x15 0x80
Sketch prints
21.500 °C
Sign bit
0
21.500 °C. The first byte is the whole degrees and the second is the fraction, so the two together are 256 times the temperature. Divide by 256 and it is degrees, at whatever resolution the chip has.

The first byte is whole degrees, the second is the fraction. Bit 8 is one degree, bit 7 half a degree, bit 5 an eighth. Below that the chip sends zeros.

One line of arithmetic

Put the two bytes side by side and the result is 256 times the temperature. So the whole conversion is:

uint8_t hi = Wire.read();                 // whole degrees
uint8_t lo = Wire.read();                 // the fraction
int16_t raw = (int16_t)((hi << 8) | lo);  // signed: 256 x the temperature
float c = raw / 256.0;

Read the two bytes into two variables first. Written as one expression, (Wire.read() << 8) | Wire.read(), C++ is free to call the second read first.

21.5 °C arrives as 0x15 0x80: 5504, and 5504 over 256 is 21.5. The same line works at any resolution, because both makers send the unused low bits as 0.

Below zero

The top bit is the sign. At −4 °C the bytes are 0xFC 0x00, which is −1024 as a signed 16-bit number: −4 exactly.

The int16_t is what makes it signed. The code on the page this book replaces put the bytes in an int, shifted them right by five and multiplied by 0.125. On an Uno, whose int is 16 bits, that works. On an ESP32 or a Pico an int is 32 bits, the top bit of the temperature is just bit 15 of a positive number, and −4 °C prints as 252 °C. Press the second button in the figure to see it.

A room never goes below zero, so the mistake survives until the sensor goes into a freezer or outside in winter.

When it does not work

Below zero my sketch prints about 250 °C.

The two bytes went into an int and were shifted right by five. On an ESP32 or a Pico an int is 32 bits, so the sign bit is just a large positive bit. Put them in an int16_t and divide by 256.0, as the book's sketch does. On an Uno the old code works, because its int is 16 bits.

Why does it only ever change in steps of 0.125?

That is the chip's resolution: eleven bits, an eighth of a degree a step, on NXP's LM75B. UMW's datasheet for the fitted part claims twelve bits, a sixteenth; dividing by 256 gives whichever the chip actually has, with no change to the sketch.

Can I read just one byte?

Yes. The first byte alone is the temperature in whole degrees, as a signed 8-bit number, and NXP says the LM75B handles a one-byte read without locking the bus. You lose the fraction.

Where this goes next

How often the number changes, and what reading faster buys.

Ten readings a second →

Edit this page — content/books/lm75/degrees-in-two-bytes.mdx

Community

Questions about this product

See what other owners have asked, and read their solutions.

Ask a question ↗

LM75 Temperature Sensor

Loading discussions…

Discuss this article

Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.

Browse Modules and blocks on the forum →