Q: Use a Raspberry Pi to read temperature data from MCP9808
MCP9808 is a temperature sensor that uses the I2C communication standard to transmit continuous polling temperatures. It supports alarm function and standby mode to save power when needed. In this documentation, we will execute several python commands to get the temperature of the sensor.
I2C on MCP9808
Microchip uses 0x18 as the primary address on this board, with the help of 3 pins on the chip to change the address in the event of an I2C address conflict. When any register in the sensor is called, the board should write or get a double-byte response (MSB first, LSB last). I'm using the breakout board[], which already contains some forward bias resistors.
Registers to note:
0x01 : 00000000X 00011111 : X here is the alternate bit in the configuration, the default is 0, this is continuous polling mode. The temperature registers are constantly updated, but there are power consumption issues. Setting this bit to 1 will stop polling and save power.
0x05 : AAASMMMM LLLLLLLL : 该寄存器包含12位浮点温度,其中“A”为报警信息,“S”为符号位,“M”和“L”分别代表MSB和LSB。 最终输出将显示为MMMMLLLL.LLLL。
Note that in this instruction I didn't set the sign bits and alarm bits, but if you want to measure sub-zero temperatures, you'll need to.
Implementation on Raspberry PI:
The benefit of using a Raspberry Pi to connect to an I2C interface is the interactivity of the Python terminal. I'm using one with I2C enabled on a Raspbian distribution. Make sure your GPIO supports 3V3, GND, SDA and SCL supports the correct pins on the MCP9808. Open the terminal in Raspbian and execute the following three commands:
python
from smbus import SMBus
bus = SMBus(1)
This command will create a bus object to be connected, which in turn will collect the I2C data we requested. Next, ask the chip for its temperature data:
temp_binary = format(bus.read_word_data(0x18, 0x05),‘016b’)
The bus.read_byte_data (Address, Register) will retrieve the data from the sensor, and we use the closed format() function to read the information as a binary number, so that it is easy to extract these two bytes. Python generally likes to use ints or floats, but this gets in the way because the value is returned by multiple bytes. We'll index them in [0:8][8:16] order, with MSB in the bottom half of the array.
Calculated output:
We can utilize the following function to get the output value correctly
def word_To_LSB_MSB(word):
return word[0:8], word[12 :16] // note that word indices [8,9,10,11] are not used in this example.
Take a look at the image below to see what we need to output.
Finally, combine the two and add some floating-point arithmetic.
LSB, MSB = word_To_LSB_MSB(temp_binary)
float(int(MSB + LSB,2)) / 16
DIVIDE BY 16 TO CONVERT THE RESULT TO MMMMLLLL.LLLL AND GET DECIMAL PRECISION. Note that the returned results should be in Celsius. In the case shown in the image above, the temperature we calculated from the binary float number 00010111.0101 is 23.3125 degrees Celsius.
Enter the power saving mode when you're done:
If you want to turn off the device when you're done, simply set the standby position to power-saving mode:
bus.write_byte_data(0x18,0x01,0b00000001)
Since we only need to change the MSB in the MCP9809 configuration register, we write one byte, but we shorten the character so that the LSB in the register is not changed.
To return the MCP9808 to a fully functional state, the sensor must be given a power cycle or a zero-refresh mode using the register.
Microchip's datasheet remains very useful for this sensor, so be sure to check back regularly if you're going to use MCP9808. Note that some of the important features of this sensor, such as interrupts, sign bits for negative temperatures, and standby operation, are not covered in this article.
Items used:
Raspberry Pi:
Female to Male Breadboard Line: 1568-1511-ND
Adafruit breakout board for MCP9808:
Finally, if you like this article, share it with more friends! Don't forget to give it a thumbs up!