Skip to Content

← DS18B20 Temperature on Raspberry PLC via 1-Wire

Fuse test benchRaspberry PLC 19R1-WireAcquisition

DS18B20 Temperature on Raspberry PLC via 1-Wire — full example

Read a DS18B20 temperature sensor from a Raspberry PLC with the w1-gpio overlay and pure Python: sysfs parsing, CRC checks and noise filtering included.

Complete, runnable program for the Raspberry PLC 19R (ds18b20-1wire-sensor.py): wiring header, requirements and integration notes included.

Download the full project pack — freeThis example + the related ones + bill of materials

Read-only preview.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
COMPLETE EXAMPLE — DS18B20 temperature sensor over 1-Wire

Equipment: Raspberry PLC 19R (Industrial Shields)
Based on:  fuse test bench project

Wiring:
  - DS18B20 with 4.7 kOhm pull-up resistor to 3.3 V
  - Data on GPIO8 of the Raspberry PLC

Prior configuration (one time only):
  1. Add to /boot/config.txt:   dtoverlay=w1-gpio,gpiopin=8
  2. Reboot. The sensor shows up at /sys/bus/w1/devices/28-*/w1_slave

Requirements:
  No pip dependencies: it reads directly from the kernel sysfs.

Integration with the catalog:
  - The ambient temperature is recorded in the test report
    (txt-test-reports.py) and shown in the GUI
    (tkinter-gui-beacons-relays.py).
"""

import glob
import time

# --- Sensor location in the sysfs --------------------------------------------
SENSOR_GLOB = "/sys/bus/w1/devices/28-*/w1_slave"

# Bench filter: variations smaller than 0.6 °C are considered electronics
# noise and are not propagated to the display or the report.
FILTER_THRESHOLD_C = 0.6


def find_sensor():
    """Return the path of the first DS18B20 detected, or None."""
    devices = glob.glob(SENSOR_GLOB)
    return devices[0] if devices else None


def read_raw(path):
    """Read the w1_slave file and return the temperature in °C, or None.

    Kernel format (two lines):
      72 01 4b 46 7f ff 0e 10 57 : crc=57 YES
      72 01 4b 46 7f ff 0e 10 57 t=23125
    """
    try:
        with open(path) as f:
            lines = f.read().splitlines()
    except OSError:
        return None

    if len(lines) < 2 or not lines[0].endswith("YES"):
        return None  # invalid CRC: discard the reading

    pos = lines[1].find("t=")
    if pos < 0:
        return None
    return int(lines[1][pos + 2:]) / 1000.0


class FilteredTemperature:
    """Keeps the last 'good' temperature and filters out small jumps."""

    def __init__(self, threshold=FILTER_THRESHOLD_C):
        self.threshold = threshold
        self.value = None

    def update(self, reading):
        if reading is None:
            return self.value  # failed reading: keep the previous value
        if self.value is None or abs(reading - self.value) >= self.threshold:
            self.value = reading  # real change: accept
        return self.value


def main():
    path = find_sensor()
    if path is None:
        print("No DS18B20 found.")
        print("Is the overlay 'dtoverlay=w1-gpio,gpiopin=8' in /boot/config.txt?")
        return

    print("Sensor found:", path)
    temp_filter = FilteredTemperature()

    # Monitoring loop: on the real bench this temperature accompanies
    # every test, because the fusing current depends on the ambient one.
    while True:
        raw = read_raw(path)
        filtered = temp_filter.update(raw)

        if filtered is None:
            print("Invalid reading (CRC), retrying...")
        else:
            print("Raw T: %s°C  |  Filtered T (report): %.1f°C"
                  % ("%.3f" % raw if raw is not None else "----", filtered))
        time.sleep(2.0)


if __name__ == "__main__":
    main()
Download the full project pack — freeThis example + the related ones + bill of materials