46

What can I connect to the RPi to measure temperature? I think devices connected to the I²C or SPI would make most sense.

Here is a question about DHT-22 and other 1-wire devices. But at this stage it seems that 1-wire is difficult on the RPi due to the critical timings

John La Rooy
  • 11,847
  • 9
  • 46
  • 74
  • I'm planning on following [this tutorial from the Univ of Cambridge](http://www.cl.cam.ac.uk/freshers/raspberrypi/tutorials/temperature/) –  Jan 27 '13 at 01:11

6 Answers6

40

Here's how to connect a MCP9804.

enter image description here

You can use it like this:

root@raspberrypi:~# modprobe i2c-dev
root@raspberrypi:~# modprobe i2c-bcm2708 
root@raspberrypi:~# i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 1f 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         
root@raspberrypi:~# i2cget -y 0 0x1f 0x5 w
0x67c1

Converting 0x67c1 to a temperature is a little convoluted. The MSB is 0xc1 and the LSB is 0x67

The first 4 bits of the MSB are dropped and which leaves the temperature in 16ths of a degree

(0xc1&0xf)*16+0x67/16.0 = 22.4375 degrees 

Python Example
In addition to loading the i2c modules above, you'll need to install the python-smbus package. You can reduce self-heating by shutting down the MCP9804 between readings.

#!/usr/bin/env python
import time
from smbus import SMBus

class MCP9804(object):
    def __init__(self, bus, addr):
        self.bus = bus
        self.addr = addr

    def wakeup(self):
        self.bus.write_word_data(self.addr, 1, 0x0000)

    def shutdown(self):
        self.bus.write_word_data(self.addr, 1, 0x0001)

    def get_temperature(self, shutdown=False):
        if shutdown:
            self.wakeup()
            time.sleep(0.26) # Wait for conversion

        msb, lsb =  self.bus.read_i2c_block_data(self.addr, 5, 2)

        if shutdown:
            self.shutdown()

        tcrit = msb>>7&1
        tupper = msb>>6&1
        tlower = msb>>5&1

        temperature = (msb&0xf)*16+lsb/16.0
        if msb>>4&1:
            temperature = 256 - temperature
        return temperature



def main():
    sensor = MCP9804(SMBus(0), 0x1f)
    while True:
        print sensor.get_temperature()
        time.sleep(1)


if __name__ == "__main__":
    main()
John La Rooy
  • 11,847
  • 9
  • 46
  • 74
  • What version of this IC did you use? I have a similar IC (the MCP9808T) but the local electronics store only has the DFN package version. I have no idea how to solder that on anything without making it one big short. – ikku Sep 24 '12 at 14:44
  • @ikku, I had the 8-pin MSOP – John La Rooy Sep 24 '12 at 21:20
13

You may use the Raspberry Pi built in serial port, and connect it to a digital thermometer IC (e.g. DS1620)

You can find out serial port interfacing of Raspberry Pi here

enter image description here

  • P1 (LEFT BOTTOM) - 3.3V
  • P6 - GND
  • P8 GPIO14 - TX
  • P10 GPIO15 - RX

Important: Remember the RPi UART runs at TTL 3.3V - Be careful not to use High Voltage 5v/12volt Uart direct to the RPi. It will cause damage!

Piotr Kula
  • 17,168
  • 6
  • 63
  • 103
JeeShen Lee
  • 1,405
  • 2
  • 10
  • 10
  • It seems to use a 3-wire interface, so not just a matter of using the serial port the usual way, but seems compatible with the GPIOs – John La Rooy Jul 23 '12 at 02:43
  • AFAIK, it's normal for serial port to have Tx, Rx, and CLK. I think SPI need 3 wires too SDO, SDO, and SCLK. Refer this for the SPI variant - DS1722 [link](http://datasheets.maxim-ic.com/en/ds/DS1722.pdf). – JeeShen Lee Jul 23 '12 at 02:49
  • But the DS1620 uses !RST, CLK and DQ. The !RST is high for the entire transfer, CLK is the clock and DQ is bidirectional data, so it's different to a UART – John La Rooy Jul 23 '12 at 03:52
  • 3
    I like your alterantive answer and imporooved it a bit for you JeeSehn. Also i added warning for non technical users to be careful that the UART on RPi is 3.3v TTL and that other USB to Serial might use 5v/12v! Damge the RPI! – Piotr Kula Jul 31 '12 at 09:25
4

A simple, cheap USB "HID TEMPer" thermometer also works, and is much easier to connect for those who are yet to fiddle with UARTs or GPIO, like me.

HID TEMPer USB thermometer

My RPi provides enough power to drive it directly from the USB port without a hub.

To set this up with Raspbian Wheezy, I followed these instructions which were written for Ubuntu (disclaimer: link is for a post on my own blog). For the Raspberry Pi, I only had to make one small tweak to set LIBUSB_LIBDIR when installing the Device::USB perl module so it could find libusb in the non-standard arm location. The complete instructions follow.

To get a simple reading without any of the munin stuff, install the dependencies as follows (as root):

apt-get install libusb-dev
export LIBUSB_LIBDIR=/usr/lib/arm-linux-gnueabihf
cpan Inline::MakeMaker
cpan Device::USB::PCSensor::HidTEMPer

Create readtemp.pl:

#!/usr/bin/perl
use strict;
use Device::USB::PCSensor::HidTEMPer;

my $pcsensor = Device::USB::PCSensor::HidTEMPer->new();
my @devices = $pcsensor->list_devices();
foreach my $device (@devices) {
    print $device->internal()->celsius()."\n" if defined $device->internal();
}

And run that as root to see the output. In my case, it's a little chilly in the garage this evening:

day@pi:~$ sudo ./readtemp.pl 
16.5
Day
  • 1,133
  • 1
  • 8
  • 14
3

I've tried two approaches to temperature sensing. For I2C, I used a TMP102 module which is similar to what gnibbler describes. Here's my post on that:

For 1-wire, Adafruit recently released there own image, and it contains 1-wire support. I was able to read a DS18B20 1-wire temp sensor with it. More details in this post:

Finally, another approach is to use analog temp sensor and an external ADC. Adafruit has a nice tutorial on this.

John La Rooy
  • 11,847
  • 9
  • 46
  • 74
pdp7
  • 161
  • 2
2

The one I'm currently using is the DS18B20.

First open the Pi and type:

sudo leafpad /etc/apt/sources.list.d/raspi.list

Then add the word untested after main.

Then type:

sudo apt-get update
sudo apt-get upgrade

In my case it took a long time, though it depends on your wifi/ethernet speed. After that, you reboot:

sudo reboot now

Connect the white wire to GPIO4, The red wire to 3V3, and the black to GND. You also connect a 4.7K resistor between the white and red wires.

You can read it by doing the following commands:

sudo modprobe w1-gpio
sudo modprobe w1-therm
cd /sys/bus/w1/devices/
ls

Then is should list the serial number of the temperature sensor, followed by w1_bus_master1

Then go:

cd serial-number-here
cat w1_slave

And then it should show 2 lines of code, where the 5 digits at the end of the second line are the temperature.

This utilizes something called the "Dallas One-Wire Temperature Sensor Protocol", or something.

techraf
  • 4,254
  • 10
  • 29
  • 41
Kachamenus
  • 749
  • 6
  • 26
1

I'm currently reading this book and like it. Going that route my vision is that you'd have a temperature sensor, an arduino, and an xbee radio glued together. That's your remote sensor which could be anywhere as long as it's in range of the home station. Then for the home station have a rasberry and another xbee. I'm guessing that it might be easier to also have the home station xbee on an arduino, and then have the arduino and rasberry talk to each other. With that you could have multiple remote sensors, and different types of sensors.

lumpynose
  • 281
  • 2
  • 7
  • Interesting. I'd like more details on this. See my question: http://raspberrypi.stackexchange.com/questions/38711/any-remote-sensors-for-the-rasperry-pi and please reply there :-) – Davide Nov 28 '15 at 15:12