Holooly Plus Logo

Question 12.9: You want to measure temperature using an accurate digital se......

You want to measure temperature using an accurate digital sensor.

Step-by-Step
The 'Blue Check Mark' means that this solution was answered by an expert.
Learn more on how do we answer questions.

Use the DS18B20 digital temperature sensor. This device is more accurate than the TMP36 used in Recipe 12.7 and uses a one-wire digital interface, so it doesn’t require an ADC chip.

Although called one-wire, this just refers to the data pin. You do need at least one other wire to connect to a one-wire device.

To make this recipe, you will need:

• Breadboard and jumper wires (see “Prototyping Equipment” on page 380)
• DS18B20 temperature sensor (see “Integrated Circuits” on page 381)
• 4.7kΩ resistor (see “Resistors and Capacitors” on page 380)

Fit the components onto the breadboard as shown in Figure 12-16. Make sure that you get the DS18B20 the right way around.

Both Occidentalis and newer versions of Raspbian have support for the one-wire interface used by the DS18B20 enabled. If the upcoming program doesn’t work, then try:

$ sudo apt-get upgrade

Open an editor (nano or IDLE) and paste in the following code. As with all the program examples in this book, you can also download the program from the Code section of the Raspberry Pi Cookbook website, where it is called temp_DS18B20.py.

import os, glob, time
os.system(‘modprobe w1-gpio’)
os.system(‘modprobe w1-therm’)
base_dir = ‘/sys/bus/w1/devices/’
device_folder = glob.glob(base_dir + ’28*’)[0]
device_file = device_folder + ‘/w1_slave’
def read_temp_raw():
f = open(device_file, ‘r’)
lines = f.readlines()
f.close()
return lines
def read_temp():
lines = read_temp_raw()
while lines[0].strip()[-3:] != ‘YES’:
time.sleep(0.2)
lines = read_temp_raw()
equals_pos = lines[1].find(‘t=’)
if equals_pos != -1:
temp_string = lines[1][equals_pos+2:]
temp_c = float(temp_string) / 1000.0
temp_f = temp_c * 9.0 / 5.0 + 32.0
return temp_c, temp_f
while True:
print(“temp C=%f\ttemp F=%f” % read_temp())
time.sleep(1)

When the program is run, it will report the temperature once a second in both degrees Celsius and Fahrenheit:

$ python temp_DS18B20.py
temp C=25.187000 temp F=77.336600
temp C=25.125000 temp F=77.225000
temp C=25.062000 temp F=77.111600
temp C=26.312000 temp F=79.361600
temp C=27.875000 temp F=82.175000
temp C=28.875000 temp F=83.975000

Discussion

At first sight, the program looks a little odd. The interface to the DS18B20 uses a file-like interface. The file interface for the device will always be in the folder /sys/bus/w1/devices/ and the name of the file path will start with 28, but the rest of the file path will be different for each sensor. The code assumes that there will only be one sensor and finds the first folder starting with 28. Within that folder will be a file called w1_slave, which is opened and read to find the temperature.

The sensor actually returns strings of text like this:

81 01 4b 46 7f ff 0f 10 71 : crc=71 YES
81 01 4b 46 7f ff 0f 10 71 t=24062

The remainder of the code extracts the temperature part of this message. This appears after t= and is the temperature in one-thousandths of a degree Celsius.

The read_temp function calculates the temperature in degrees Fahrenheit and returns both.

Besides the basic chip version of the DS18B20, you can also buy a version encapsulated in a rugged and waterproof probe.

See Also

To find out about logging readings, see Recipe 12.12.

This recipe is heavily based on an Adafruit tutorial.

To measure temperature using a less accurate TMP36 analog sensor, see Recipe 12.7.

Take a look at the datasheet for the DS18B20.

Table A-3. Prototyping equipment
Description Suppliers
M-M jumper wires SparkFun: PRT-08431, Adafruit: 759
M-F jumper wires SparkFun: PRT-09140, Adafruit: 825
F-F jumper wires SparkFun: PRT-08430, Adafruit: 794
Half-sized breadboard SparkFun: PRT-09567 Adafruit: 64
Pi Cobbler Adafruit: 1105
Table A-6. Integrated circuits
7805 voltage regulator SparkFun: COM-00107
L293D motor driver SparkFun: COM-00315, Adafruit: 807
ULN2803 Darlington driver IC SparkFun: COM-00312, Adafruit: 970
DS18B20 temperature sensor SparkFun: SEN-00245, Adafruit: 374
MCP3008 eight-channel ADC IC Adafruit: 856
TMP36 temperature sensor SparkFun: SEN-10988, Adafruit: 165
Table A-4. Resistors and capacitors
270Ω 0.25W resistor Mouser: 293-270-RC
470Ω 0.25W resistor Mouser: 293-470-RC
1kΩ 0.25W resistor Mouser: 293-1k-RC
3.3kΩ 0.25W resistor Mouser: 293-3.3k-RC
4.7kΩ 0.25W resistor Mouser: 293-4.7k-RC
10 kΩ trimpot Adafruit: 356, SparkFun: COM-09806, Mouser: 652-3362F-1-103LF
Photoresistor Adafruit: 161, SparkFun: SEN-09088
220nF capacitor MCM: 31-0610, Mouser: 80-C322C224M5U5HA
12.16

Related Answered Questions

Question: 12.11

Verified Answer:

Use the Tkinter library to open a window and write...
Question: 12.10

Verified Answer:

Use a low cost SR-04 rangefinder. These devices ne...
Question: 12.12

Verified Answer:

Write a Python program that writes the data to a f...
Question: 12.7

Verified Answer:

Use an MCP3008 ADC chip. However, unless you need ...
Question: 12.8

Verified Answer:

Use an analog accelerometer with a MCP3008 ADC chi...
Question: 12.6

Verified Answer:

Use a potential divider with one fixed resistor an...
Question: 12.2

Verified Answer:

Use the same basic recipe and code as Recipe 12.1,...
Question: 12.3

Verified Answer:

Low-cost resistive gas sensors are available that ...
Question: 12.4

Verified Answer:

The Raspberry Pi GPIO connector has only digital i...
Question: 12.5

Verified Answer:

Use a pair of resistors to act as a voltage divide...