In this user guide, we will learn how to use a DS18B20 temperature sensor with Raspberry Pi Pico in MicroPython. This is a comprehensive article in which we will discuss the sensor and how to access temperature readings through a single sensor. Additionally, we will also display the temperature readings on an SSD1306 OLED display.
Before we start this lesson make sure you are familiar with and have the latest version Python 3 in your system, have set up MicoPython in Raspberry Pi Pico, and have a running Integrated Development Environment(IDE) in which we will be doing the programming. We will be using the same Thonny IDE as we have done previously when we learned how to blink and chase LEDs in micro-python. If you have not followed our previous tutorial, you check here:
If you are using uPyCraft IDE, you can check this getting started guide:
It is a temperature sensor that is single wire programmable in nature. It is widely used to measure the temperature of chemical solutions and substances which are present in a hard environment. One of the advantages of using this sensor is that we only require a single pin of our Raspberry Pi Pico boards to transfer data. Thus, it is extremely convenient to use with the micro-controller as we can measure multiple temperatures by using the least number of pins on our development board.
The table below shows some key characteristics of the ds18b120 sensor.
|Temperature Range||-55°C to +125°C|
|Output Resolution||9bit to 12bit|
A waterproof version of this sensor is also available in the market. The following figures show the pinout of the DS18B20 sensors.
The following diagram shows the pinout of normal DS18B20 temperature sensor.
The table below lists the pin configurations:
|VCC||This is the pin that powers up the sensor. 3.3V for Raspberry Pi Pico boards|
|Data||This pin gives the temperature value|
|Ground||This pin is connected with the ground|
This temperature sensor also comes in a single package module which contains a sensor and a pull-up resistor. If you are using a module, you do not need to connect an external 4.7K ohm resistor. Because the module already has an onboard pull-up resistor.
DS18B20 Parasite vs Normal Mode
The DS18B20 sensor can be powered in two different modes.
Normal Mode: The sensor is powered through an external source through the VDD pin and 4.7K ohm pull-up resistor.
Parasite Mode: The sensor obtains the power from its own data line. Hence, no external power supply is required.
We will now learn how to connect the temperature sensor with Raspberry Pi Pico. We will need the following components.
- Raspberry Pi Pico
- DS18B20 sensor
- 4.7k ohm resistor
- Connecting Wires
Raspberry Pi Pico with DS18B20 Schematic Diagram
As you can see in the schematic diagram below, we have used DS10B20 in normal mode and powered the sensor with its VCC pin from 3.3V pin of Raspberry Pi Pico board.
Connect Raspberry Pi Pico with DS18B20 as shown in the schematic diagram below:
As you can see above, we have powered the sensor using the normal mode. The DS18B20 sensor has three terminals which we saw above in the pinout. The first terminal is grounded with the Raspberry Pi Pico board. The data line of the sensor, which is the middle terminal, is connected through GP2 through a pull-up resistor of 4.7k-ohm. We can choose any other GPIO pin as well. The third terminal is powered by 3.3V from the Raspberry Pi Pico.
You can use any other GPIO pin of Raspberry Pi Pico to connect with the data pin as well. You can refer to this post to know more about Raspberry Pi Pico GPIO pins:
Installing DS18B20 Libraries
For this project we will require two libraries: ds18x20.py and onewire.py. Copy both of these libraries and save them in your Raspberry Pi Pico with the respective file names. Open a new file in Thonny. Copy the libraries given below. Save them to Raspberry Pi Pico with names ds18x20.py and onewire.py under the lib folder.
# DS18x20 temperature sensor driver for MicroPython. # MIT license; Copyright (c) 2016 Damien P. George from micropython import const _CONVERT = const(0x44) _RD_SCRATCH = const(0xBE) _WR_SCRATCH = const(0x4E) class DS18X20: def __init__(self, onewire): self.ow = onewire self.buf = bytearray(9) def scan(self): return [rom for rom in self.ow.scan() if rom in (0x10, 0x22, 0x28)] def convert_temp(self): self.ow.reset(True) self.ow.writebyte(self.ow.SKIP_ROM) self.ow.writebyte(_CONVERT) def read_scratch(self, rom): self.ow.reset(True) self.ow.select_rom(rom) self.ow.writebyte(_RD_SCRATCH) self.ow.readinto(self.buf) if self.ow.crc8(self.buf): raise Exception("CRC error") return self.buf def write_scratch(self, rom, buf): self.ow.reset(True) self.ow.select_rom(rom) self.ow.writebyte(_WR_SCRATCH) self.ow.write(buf) def read_temp(self, rom): buf = self.read_scratch(rom) if rom == 0x10: if buf: t = buf >> 1 | 0x80 t = -((~t + 1) & 0xFF) else: t = buf >> 1 return t - 0.25 + (buf - buf) / buf else: t = buf << 8 | buf if t & 0x8000: # sign bit set t = -((t ^ 0xFFFF) + 1) return t / 16
# 1-Wire driver for MicroPython # MIT license; Copyright (c) 2016 Damien P. George import _onewire as _ow class OneWireError(Exception): pass class OneWire: SEARCH_ROM = 0xF0 MATCH_ROM = 0x55 SKIP_ROM = 0xCC def __init__(self, pin): self.pin = pin self.pin.init(pin.OPEN_DRAIN, pin.PULL_UP) def reset(self, required=False): reset = _ow.reset(self.pin) if required and not reset: raise OneWireError return reset def readbit(self): return _ow.readbit(self.pin) def readbyte(self): return _ow.readbyte(self.pin) def readinto(self, buf): for i in range(len(buf)): buf[i] = _ow.readbyte(self.pin) def writebit(self, value): return _ow.writebit(self.pin, value) def writebyte(self, value): return _ow.writebyte(self.pin, value) def write(self, buf): for b in buf: _ow.writebyte(self.pin, b) def select_rom(self, rom): self.reset() self.writebyte(self.MATCH_ROM) self.write(rom) def scan(self): devices =  diff = 65 rom = False for i in range(0xFF): rom, diff = self._search_rom(rom, diff) if rom: devices += [rom] if diff == 0: break return devices def _search_rom(self, l_rom, diff): if not self.reset(): return None, 0 self.writebyte(self.SEARCH_ROM) if not l_rom: l_rom = bytearray(8) rom = bytearray(8) next_diff = 0 i = 64 for byte in range(8): r_b = 0 for bit in range(8): b = self.readbit() if self.readbit(): if b: # there are no devices or there is an error on the bus return None, 0 else: if not b: # collision, two devices with different bit meaning if diff > i or ((l_rom[byte] & (1 << bit)) and diff != i): b = 1 next_diff = i self.writebit(b) if b: r_b |= 1 << bit i -= 1 rom[byte] = r_b return rom, next_diff def crc8(self, data): return _ow.crc8(data)
MicroPython Raspberry Pi Pico DS18B20 : Getting Temperature values
After uploading the two libraries mentioned above to our Raspberry Pi Pico, let us program our board with ds18b20 sensor.
Let’s now look at an example to show the working of the sensor. We will connect our ds18b20 sensor with the Raspberry Pi Pico as shown above in the connection diagram. We will see a MicroPython script code and after uploading it to our board, we will see current readings of temperature printed on the MicroPython shell terminal.
DS18B20 MicroPython Code
Now let’s look at the MicroPython script for DS18b20 to get sensor readings. Copy the following code to the main.py file and upload the main.py file to Raspberry Pi Pico.
This MicroPython script reads Temperature values from DS18B20 and prints them on the MicroPython shell console.
import machine, onewire, ds18x20 from time import sleep ds_pin = machine.Pin(2) ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin)) roms = ds_sensor.scan() print('Found DS devices') print('Temperature (°C)') while True: ds_sensor.convert_temp() sleep(1) for rom in roms: print(ds_sensor.read_temp(rom)) sleep(3)
How the Code Works?
Firstly, we will be importing the machine module. We also import the sleep module so that we will be able to add a delay in between our readings. Also, import one wire and ds18x20 libraries that we just uploaded to our board.
import machine, onewire, ds18x20 from time import sleep
Next, we will create an instance of Pin class with an object name of ds_pin and set GP2 as the DS18B20 data line pin. The DS18X20() method
ds_pin = machine.Pin(2) ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin))
The scan() method scans all DS18B20 sensors connected to the ds_sensor pin and saves the 64-bit address of each sensor in a list variable that is “roms”. Later, we will use these addresses to read temperature from the sensor one by one.
roms = ds_sensor.scan() print('Found DS devices')
After that call the object on convert_temp() method before reading the temperature from the sensor using its unique address.
To read the temperature, use read_temp() procedure on ds_sensor object and pass an address which is stored in roms list. The DS18B20 temperature sensor provides data output in float data type. The current temperature readings will be printed in the shell terminal after every 3 seconds.
while True: ds_sensor.convert_temp() sleep(1) for rom in roms: print(ds_sensor.read_temp(rom)) sleep(3)
To test the MicroPython script for DS18B20 with Raspberry Pi Pico, upload the main.py file to your board.
You will see the Temperature values on the shell console constantly updating to new values after every 3 seconds.
Raspberry Pi Pico Display DS18B20 Sensor values on OLED Display
In this section, we will see how to display DS18B20 Temperature values on a 0.96 SSD1306 OLED display using MicroPython and Raspberry Pi Pico.
You may also like to read:
SSD1306 OLED Display MicroPython Library
For an OLED display, we will need to upload a library to Raspberry Pi Pico.
- To successfully do that, open your Thonny IDE with your Raspberry Pi Pico plugged in your system. Go to Tools > Manage Packages. This will open up the Thonny Package Manager.
- Search for “ssd1306” in the search bar by typing its name and clicking the button ‘Search on PyPI.’
- From the following search results click on the one highlighted below: micropython-ssd1306
Install this library.
After a few moments this library will get successfully installed. Now we are ready to program our Raspberry Pi Pico with OLED display.
Connecting SSD1306 OLED Display with Raspberry Pi Pico and DS18B20
We will need the following components to connect our Raspberry Pi Pico with the OLED Display and DS18B20.
- Raspberry Pi Pico
- DS18B20 Sensor
- SSD1306 OLED Display
- Connecting Wires
The OLED display has 4 terminals which we will connect with the Raspberry Pi Pico. As the OLED display requires an operating voltage in the range of 3.3-5V hence we will connect the VCC terminal with 3.3V which will be in common with the board and the sensor. SCL of the display will be connected with the SCL pin of the module and the SDA of the display will be connected with the SDA of the module. The ground of all three devices will be held common.
Raspberry Pi Pico I2C Pins
Raspberry Pi Pico has two I2C controllers. Both I2C controllers are accessible through GPIO pins of Raspberry Pi Pico. The following table shows the connection of GPIO pins with both I2C controllers. Each connection of the controller can be configured through multiple GPIO pins as shown in the figure. But before using an I2C controller, you should configure in software which GPIO pins you want to use with a specific I2C controller.
|I2C Controller||GPIO Pins|
|I2C0 – SDA||GP0/GP4/GP8/GP12/GP16/GP20|
|I2C0 – SCL||GP1/GP5/GP9/GP13/GP17/GP21|
|I2C1 – SDA||GP2/GP6/GP10/GP14/GP18/GP26|
|I2C1 – SCL||GP3/GP7/GP11/GP15/GP19/GP27|
The connections between the three devices which we are using can be seen below.
We have used the same connections as specified in the table above. However you can use other combinations of SDA/SCL pins as well.
|SSD1306 OLED Display||Raspberry Pi Pico|
|SDA||GP0 (I2C0 SDA)|
|SCL||GP1 (I2C0 SCL)|
|DS18B20||Raspberry Pi Pico|
Schematic Raspberry Pi Pico with OLED and DS18B20
Follow the schematic diagram below connect them accordingly.
MicroPython Code: Displaying DS18B20 readings on OLED Display
import machine, onewire, ds18x20 from machine import Pin, I2C from time import sleep from ssd1306 import SSD1306_I2C i2c=I2C(0,sda=Pin(0), scl=Pin(1), freq=400000) oled = SSD1306_I2C(128, 64, i2c) ds_pin = machine.Pin(2) ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin)) roms = ds_sensor.scan() print('Found DS devices') print('Temperature (°C)') while True: ds_sensor.convert_temp() sleep(1) for rom in roms: print(ds_sensor.read_temp(rom)) oled.fill(0) oled.text("Temperature (C)", 0, 16) oled.text(str(ds_sensor.read_temp(rom)), 0, 35) oled.show() sleep(3)
How does the code work?
In the section, we will explain the MicroPython code which is used to display sensor values on OLED.
We will import the ssd1306 which is the OLED display library that we installed earlier. This will help us in accessing all the functions defined inside it.
from ssd1306 import SSD1306_I2C
The SCL and SDA pin data gets saved in the object ‘i2c’ which will connect to the I2C bus and help in the communication between the two devices
Now, we will create an object ‘oled’ of SSD1306_I2C which uses the width, height, and the i2c object as parameters.
oled = SSD1306_I2C(128, 64, i2c)
Clears the OLED display with led.fill() routine.
Take DS18B20 sensor temperature samples and print them in the shell terminal.
ds_sensor.convert_temp() sleep(1) for rom in roms: print(ds_sensor.read_temp(rom))
Finally, display the text along with sensor reading on OLED.
oled.text("Temperature (C)", 0, 16) oled.text(str(ds_sensor.read_temp(rom)), 0, 35)
At the end, call the show() method on oled method for changes to show on OLED. Add a delay of 3 seconds between each reading.
Upload the above code as a .py file to Raspberry Pi Pico. Press the run button to upload the code to your Raspberry Pi Pico module. You will see DS18B20 temperature values on the OLED display as follows:
We have other guides with popular sensors:
- DHT11 DHT22 with Raspberry Pi Pico using MicroPython
- HC-SR04 Ultrasonic Sensor with Raspberry Pi Pico using MicroPython
- MPU6050 with Raspberry Pi Pico (Accelerometer, Gyroscope, and Temperature)
- BME280 with Raspberry Pi Pico using MicroPython
Related DS18B20 tutorials and projects:
- ESP8266 NodeMCU DS18B20 Web Server with Arduino IDE
- ESP32 DS18B20 Temperature Sensor Web Server with Arduino IDE
- MicroPython: DS18B20 Web Server with ESP32/ESP8266(Weather Station)
- Single and Multiple DS18B20 with ESP32: Display Readings on OLED
- DS18B20 with ESP8266 NodeMCU (Single/Multiple): Display Readings on OLED