DS18B20


Sensor DS18B20 breadboard.jpg

The DS18B20 is a temperature sensor by Maxim Integrated (previously Dallas Semiconductor) with digital output suitable for directly connecting to a digital controller. There are three pins: VDD for connecting the supply voltage, which must be between 3 and 5.5 V, DQ for connecting a controller that programs the sensor and reads the temperature values, and finally, GND for ground. DQ must also be connected to the supply voltage via a 4.7 kΩ pull-up resistor.


Operating with an Arduino

The DallasTemperature software library by Miles Burton handles both the 1-Wire protocol for communicating with 1-Wire devices as well as the specifics of getting temperature data from the DS18B20. You can install the library via the Arduino IDE.

#include <OneWire.h>
#include <DallasTemperature.h>

OneWire oneWire(9); // using digital I/O #9
DallasTemperature sensors(&oneWire);
DeviceAddress thermometer;

void setup()
{
  Serial.begin(9600);
  sensors.begin();
  sensors.getAddress(thermometer, 0);   
  sensors.setResolution(thermometer, 12);
}

void loop()
{
  static unsigned long sensortime = 0;

  unsigned long now = millis();
  if(sensortime < now)
  {    
    sensortime = now + 60000l; // schedule next readout for 60 seconds later
    sensors.requestTemperatures();
    float temperature = sensors.getTempC(thermometer); // read temperature in Celsius
    temperature = round(10.0*temperature)/10.0;
    Serial.print("temperature at ");
    Serial.print(now / 1000 / 60);
    Serial.print(" minutes after launch: ");
    Serial.println(temperature, 1); // show only 1 place after the decimal
  }
  else
  {
    delay(2000); // pause for 2 seconds
  }
}



Operating with a Raspberry Pi

To set up 1-Wire data communication on a certain pin you need to edit /boot/config.txt and add the line

dtoverlay=w1-gpio,gpiopin=4,pullup=on


where we assume that the DQ pin of the sensor is connected to GPIO4, which is header pin #7. In order for the system to load the kernel modules for 1-Wire communication and for communicating with 1-Wire temperature sensors we edit /etc/modules by adding the following two lines:

w1-gpio pullup=1
w1-therm


The kernel module w1-therm creates a new folder under /sys/bus/w1/devices and the device file w1_slave inside the folder. The device file contains the last reading from the sensor and the folder name is the ID of the 1-Wire device. We use this ID in the Python program below, which periodically reads the sensor data.

#!/usr/bin/python

import re, os, time, datetime
import RPi.GPIO as GPIO
pin_temp_sensor = 12 # corresponds to GPIO18 of SOC
sensorid = "28-000007351a0d" # This ID is specific to the device!!!

def readTemperature(path):
  temperature = None
  try:
    GPIO.output(pin_temp_sensor, GPIO.LOW)
    f = open(path, "r")
    line = f.readline()
    if re.match(r"([0-9a-f]{2} ){9}: crc=[0-9a-f]{2} YES", line):
      line = f.readline()
      m = re.match(r"([0-9a-f]{2} ){9}t=([+-]?[0-9]+)", line)
      if m:
        temperature = float(m.group(2))/1000
    f.close()
  except IOError:
    print("sensor error")
  return temperature

if __name__ == '__main__':
  GPIO.setwarnings(False)
  GPIO.setmode(GPIO.BOARD)
  GPIO.setup(pin_temp_sensor, GPIO.OUT)
  deviceFilePath = "/sys/bus/w1/devices/%s/w1_slave" % sensorid # sensorid is the folder name
  nextUpdateTime = datetime.datetime.min
  while True:
    now = datetime.datetime.now()
    if nextUpdateTime < now:
      nextUpdateTime = now + datetime.timedelta(minutes=1)
      t = readTemperature(deviceFilePath)
      if t != None:
        print("the temperature at " + now.strftime("%H:%M") + " is %.1f" % t)
    time.sleep(2)