Raspberry Pi: Temperature Readings with DS18B20 Sensor (Python)

Learn how to interface the Raspberry Pi with the DS18B20 temperature sensor and how to get temperature readings using a Python program.

Raspberry Pi Temperature Readings with DS18B20 Sensor Python

Table of Contents

Throughout this tutorial, we’ll cover the following main topics:

Prerequisites

Before continuing with this tutorial, check the following prerequisites.

  1. Get familiar with the Raspberry Pi board—if you’re not familiar with the Raspberry Pi, you can read our Raspberry Pi Getting Started Guide here.
  2. You must know how to run and create Python files on your Raspberry Pi. We like to program our Raspberry Pi via SSH using an extension in VS Code. We have a detailed tutorial about that subject: Programming Raspberry Pi Remotely using VS Code (Remote-SSH).
  3. Know how to use the Raspberry Pi GPIOs so that you know how to wire the circuit properly. Read the following tutorial: Raspberry Pi Pinout Guide: How to use the Raspberry Pi GPIOs?

Introducing DS18B20 Temperature Sensor

The DS18B20 temperature sensor is a one-wire digital temperature sensor. This means that it just requires one data line (and GND) to communicate with your ESP32.

It can be powered by an external power supply or it can derive power from the data line (called “parasite mode”), which eliminates the need for an external power supply.

DS18B20 Temperature Sensor Pinout Pins

Each DS18B20 temperature sensor has a unique 64-bit serial code. This allows you to wire multiple sensors to the same data wire. So, you can get temperature from multiple sensors using just one GPIO.

The DS18B20 temperature sensor is also available in waterproof version.

DS18B20 Temperature Sensor Waterproof version

Here’s a summary of the most relevant specs of the DS18B20 temperature sensor:

  • Communicates over one-wire bus communication
  • Power supply range: 3.0V to 5.5V
  • Operating temperature range: -55ºC to +125ºC
  • Accuracy +/-0.5 ºC (between the range -10ºC to 85ºC)

For more information consult the DS18B20 datasheet.

Parts Required

To follow this tutorial you need the following parts:

You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!

Wiring a DS18B20 Temperature Sensor to the Raspberry Pi

The DS18B20 temperature sensor comes with three pins: GND, data, and VCC. The DS18B20 temperature sensor can be powered through the VDD pin (normal mode), or it can derive its power from the data line (parasite mode). You can choose either mode. We prefer using the normal mode.

DS18B20 Temperature Sensor Pinout Pins

If you’re using the waterproof version, you can identify each pin by its color:

  • black: GND
  • red: VDD
  • yellow: data line

The DS18B20 temperature sensor communicates using one-wire communication protocol. The Raspberry Pi supports one-wire on any GPIO pin, but the default is GPIO 4. So, we’ll wire the data pin of the sensor to GPIO 4. If you need to use another GPIO, see one of the following sections to learn how to enable the one-wire bus on a different pin.

Raspberry Pi with DS18B20 Temperature Sensor Wiring
DS18B20Raspberry Pi Pico
GNDGND
Data (DQ)Default one-wire pin ins GPIO 4
you also need to connect a 4.7KOhm resistor between the data line and VCC
VDD3V3(OUT)

Enable One-Wire Communication on the Raspberry Pi

To enable the one-wire interface, open a Terminal window on your Raspberry Pi (for example, via SSH), type the following command and press Enter.

sudo raspi-config

The following menu will open. Select Interface Options:

Enable One-Wire Communication on the Raspberry Pi

Select 1-wire.

Enable Wire one-wire interface

And enable it.

one-wire interface enabled

Finally, select Finish, and then reboot the Raspberry Pi.

one wire is enabled on Raspberry Pi

Enabling one-wire on a different GPIO (not default)

The default one-wire GPIO for the Raspberry Pi is GPIO 4. If you want to enable the one-wire bus on a different pin, you need to run the following commands.

Open and edit the config.txt file using:

sudo nano /boot/config.txt

Add the following line at the end of the file, in which x is the GPIO you want to use for one-wire:

dtoverlay=w1-gpio,gpiopin=x

For example, if you want to enable one-wire on GPIO22, it would be as follows:

dtoverlay=w1-gpio,gpiopin=22

Press CTRL-X, then press Y and Enter to save the changes.

Reboot your Raspberry Pi with:

sudo reboot

Testing the DS18B20 Temperature Sensor

With the sensor wired to your Raspberry Pi, let’s just test that it can find the sensor and report the readings before writing the Python code.

ds18b20 temperature sensor with raspberry pi

Run the following commands on a terminal window:

This command loads the w1-gpio kernel module, which is responsible for enabling the GPIO pin for one-wire communication:

sudo modprobe w1-gpio

Then, the following line loads the w1-therm kernel module, which adds support for DS18B20-specific features, such as reading temperature data from the sensor.

sudo modprobe w1-therm

Then, change the current working directory to /sys/bus/w1/devices/. In this directory, it exposes information about connected one-wire devices, including the DS18B20 sensor (if it can find the sensor).

cd /sys/bus/w1/devices/

Finally, list the contents of the devices folder that should show one or more directories, each representing a one-wire device.

ls

In the case of the DS18B20 temperature sensor, you’ll see a folder like 28-xxxxxxxxxxxx, where xxxxxxxxxxxx is the unique address of your DS18B20 sensor.

discover one-wire for ds18b20

Navigate to the directory representing the DS18B20 sensor. For example, in my case it’s as follows (use the directory of your sensor):

cd 28-03173311a0ff

After navigating to the directory representing the DS18B20 sensor, you can use the cat command to read the contents of the w1_slave file. This file contains the raw temperature data in a specific format.

cat w1_slave

The contents of the w1_slave file will look something as shown in the next screenshot (first line contains the status of the reading: YES means a valid reading, and the second line shows the temperature (you need to divide by 1000 to get it in degrees Celsius).

find one wire slave

If everything went smoothly until now, you are ready to write the Python program to get the readings.

Raspberry Pi with DS18B20 – Getting Temperature Readings (Python Script)

The following script prints temperature readings in the shell from the DS18B20 temperature sensor. The readings are printed both in Celsius and Fahrenheit degrees.

Create a new Python file called temp-ds18b20.py and copy the following code.

# Complete Project Details: https://RandomNerdTutorials.com/raspberry-pi-ds18b20-python/

# Based on the Adafruit example: https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Raspberry_Pi_DS18B20_Temperature_Sensing/code.py

import os
import glob
import 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(read_temp())	
	time.sleep(1)

View raw code

How the Code Works

In this code, we’ll basically reproduce the previous steps on the Python script to get the readings, and we’ll display them on the Python shell.

Start by importing the required libraries:

import os
import glob
import time

The os library allows you to interact with the operating system, and in this code, it’s used to execute system commands (os.system) to load the required kernel modules for 1one-wire communication with the DS18B20 sensor (similar to what we did on the Terminal before).

The glob library helps find files or directories that match a specific pattern, and it’s used here to locate the directory representing the DS18B20 sensor based on its unique address prefix.

The time library is used to introduce delays in the code to give enough time for the sensor to get valid readings.

Next, load the following kernel modules (w1-gpio and w1-therm) to interface with the DS18B20 sensor via one-wire communication protocol. These commands use the os.system function to execute shell commands within Python

os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')

The following lines set up paths and filenames for reading the temperature data:

base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '28*')[0]
device_file = device_folder + '/w1_slave'
  • base_dir represents the directory where the one-wire devices are located under the /sys filesystem.
  • device_folder is obtained using the glob.glob function, which searches for directories matching the pattern ’28*’. The DS18B20 sensors typically have a unique address starting with 28. This ensures that the code finds the correct folder representing the DS18B20 sensor connected to the Raspberry Pi.
  • device_file represents the path to the w1_slave file that contains the raw temperature data.

The function read_temp_raw() gets the temperature readings from the w1_slave file (that’s the place where those are stored). This function opens the w1_slave file, reads its contents line by line, and then returns a list containing the lines.

def read_temp_raw():
    f = open(device_file, 'r')
    lines = f.readlines()
    f.close()
    return lines

Finally, the read_temp() function reads the temperature data.

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

First, it checks if it can find a “YES” in the first line as we’ve seen previously. If the data is not valid, it waits for 0.2 seconds and retries until a valid reading is obtained.

while lines[0].strip()[-3:] != 'YES':
    time.sleep(0.2)
    lines = read_temp_raw()
    equals_pos = lines[1].find('t=')

The function then extracts the temperature value from the second line after t= and converts it to Celsius (temp_c) and Fahrenheit (temp_f). It returns both temperature values. As we’ve seen previously, we need to divide by 1000 to get the temperature in Celsius degrees. Then, we just need to convert that value to Fahrenheit.

temp_c = float(temp_string) / 1000.0
temp_f = temp_c * 9.0 / 5.0 + 32.0
return temp_c, temp_f

Finally, we have a loop (while True) that calls the read_temp() function to get the temperature in Celsius and Fahrenheit, then prints the values with two decimal places. The loop runs indefinitely, with a one-second delay between each temperature reading.

while True:
    temperature_celsius, temperature_fahrenheit = read_temp()
    print(f'Temperature: {temperature_celsius:.2f} °C')
    print(f'Temperature: {temperature_fahrenheit:.2f} °F')
    print('')
    time.sleep(1)

Demonstration

Save your Python file. Then run it on your Raspberry Pi. Run the following command on the directory of your project file (use the name of your file):

python temp_ds18b20.py

After running the script, new temperature readings will be published in the Python shell every second. Touch the sensor to see the temperature increasing. It will display the readings both in Celsius and Fahrenheit degrees.

demonstration temperature ds18b20 raspberry pi

Wrapping Up

In this tutorial, you learned how to get temperature readings from the DS18B20 and print the results on the Python shell.

We hope you found this tutorial useful. We have tutorials for other popular sensors:

You can check all our Raspberry Pi projects on the following link:

Thanks for reading.



Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Recommended Resources

Build a Home Automation System from Scratch » With Raspberry Pi, ESP8266, Arduino, and Node-RED.

Home Automation using ESP8266 eBook and video course » Build IoT and home automation projects.

Arduino Step-by-Step Projects » Build 25 Arduino projects with our course, even with no prior experience!

What to Read Next…


Enjoyed this project? Stay updated by subscribing our newsletter!

7 thoughts on “Raspberry Pi: Temperature Readings with DS18B20 Sensor (Python)”

  1. I have modified the code to read multiple sensors. The trouble is the function randomly returns a value of 85c. Any suggestions?

    #!/usr/bin/python3
    import os
    import glob
    import time
    base_dir = ‘/sys/bus/w1/devices/’

    os.system(‘modprobe w1-gpio’)
    os.system(‘modprobe w1-therm’)

    device_folder = glob.glob(base_dir + ’28‘)
    NumDev=(len(glob.glob(base_dir + ’28
    ‘)))
    #values=range(NumDev)

    def read_temp_raw(device):
    f = open(device, ‘r’)
    lines = f.readlines()
    f.close()
    return lines

    def read_temp(device):
    global temp_c
    lines = read_temp_raw(device)
    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

    #list comprehension
    device_file = [x + ‘/w1_slave’ for x in device_folder]\

    print(‘Found ‘,NumDev,’Sensors’)

    for a in device_file:
    print(read_temp(a))

    #print(read_temp(device))

    Reply
    • Hi.
      Yes. I tried, but I get better results with “normal” mode.
      You can try both ways and see which one works best for your scenario.
      Regards,
      Sara

      Reply
  2. Hi,

    ended up here following the comments of one of my students. Great work, I especially like the description of the hardware setup.

    I think the code has a possible pitfall: when the RPi has seen two sensors of the same family, this code might return the the data of a sensor that has been removed (e.g. replaced due to damage). This is not a scenario where two sensor are on the bus, but a maintenance scenario when only one sensor is deployed.

    Furthermore, for people who are just interested in getting things done, pypi.org/project/w1thermsensor/ might be a better starting point.

    Reply

Leave a Comment

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.