Triladers Tech Blog

Measuring Temperature Using 1wire Sensors and a RaspberryPi

This posting is my attempt at documenting the temperature measurement system I built in June using DS18S20 1wire temperature sensors and my RaspberryPi.

The software I used for this is rrdtool to draw graphs, lighttpd to serve the images and cron to automate the process.

After the break there are some more images and the script I use to collect the data.

This picture shows the “base board” which is connected to the RaspberryPi via an old floppy cable of which I shortened the connector. The other PCB in the picture is an epoch RTC based on the DS1307 chip which is also made my Maxim Integrated. This picture of the board is a bit out of date, as I have recently added two more bus connectors to it and moved the sensor on the board to an extra PCB connected with a length of ribbon cable to move it away from the floor and hopefully get a more representative temperature reading of the room.
The problem with having the sensor near the floor was that in my case the sensor always reacted to opening and closing the door to the kitchen and also showed the ambient heat from being stuck in a corner with a lot of other electronic devices such as the printer and router.

'RaspberryPi "extension board", I²C RTC and living-room temperature sensor' The next picture shows the sensor which is mounted near the ceiling in the kitchen. To connect the sensor in the kitchen to the Pi in the living-room I used 16 pin ribbon cable which I cut into 3 wires each and soldered the pieces together to form a long cable. The sensor mounting “PCB” is a piece of stripe-board with a socket and two headers soldered to it. The headers are for easier maintenance and extensibility in the future. I also installed a sensor on the balcony but I haven’t yet taken a picture of it so I can’t show you that. The sensor is connected like the kitchen one but the mounting PCB for it is different as it only has one bus connector as I don’t plan to install more outdoor sensors in that direction of the bus.

In the future I want to add more temperature sensors (I currently have four additional sensor laying in my parts drawer, waiting to be installed) to the system and also humidity sensors so my system can monitor the humidity outside, in the kitchen and in the bathroom.

This is the script I use to update my temperature graphs once per minute via a cronjob. This script is a modified version of the script from Christoph which I improved somewhat and also added the feature of adding the capability to specify aliases for the sensors which get displayed in the graphs.

update-temperature.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#!/bin/bash

basedir=/srv/http/
data_dir=devrrd
image_dir=devimg
alias_dir=devalias
rrddata="$basedir$data_dir"
rrdimg="$basedir$image_dir"
rrdalias="$basedir$alias_dir"

if [[ ! -d "/sys/bus/w1/devices/w1_bus_master1/" ]]; then
  echo "Can't find w1_bus_master1. Maybe you need to load the kernel modules?"
  echo "  modprobe wire; modprobe w1_gpio; modprobe w1_therm"
  exit 1
fi
if [[ ! -e "/usr/bin/rrdtool" ]]; then
  echo "rrdtool not installed"
  exit 1
fi

for dev in /sys/bus/w1/devices/w1_bus_master1/10*; do
  dev=${dev##*/}
  if [[ ! -e "$rrddata/$dev.rrd" ]]; then
      echo "Creating new rrd storage: $rrddata/$dev.rrd"
      if [ ! -d "$rrddata" ]; then
          mkdir -p "$rrddata"
      fi
      rrdtool create "$rrddata/$dev.rrd" --step 60 \
          DS:celsius:GAUGE:600:U:U \
          RRA:AVERAGE:0.5:1:2880 \
          RRA:AVERAGE:0.5:60:700
          RRA:AVERAGE:0.5:240:720 \
          RRA:AVERAGE:0.5:1440:730 || exit 1
  fi

  data=$(cat "/sys/bus/w1/devices/w1_bus_master1/$dev/w1_slave")
  echo "$data" | grep -q YES
  crc=$?
  temp=$(echo "$data" | grep t= | cut -d= -f2)
  if [[ $crc -eq 0 ]]; then
      /usr/bin/rrdupdate "$rrddata/$dev.rrd" N:$temp
  fi

  if [[ ! -d $rrdimg ]]; then
      mkdir -p "$rrdimg"
  fi
  if [[ ! -d $rrdalias ]]; then
      mkdir -p "$rrdalias"
  fi

  devalias="$dev"
  if [[ -e "$rrdalias/$dev" ]]; then
      devalias=$(cat "$rrdalias/$dev")
  fi
  /usr/bin/rrdtool graph "$rrdimg/$devalias.png" -a PNG -D -w 786 -h 256 -s -2days -v "Temperature: $devalias" \
      "DEF:c=$rrddata/$dev.rrd:celsius:AVERAGE" \
      "CDEF:gc=c,1024,/" "AREA:gc#0080FF" \
      "GPRINT:gc:LAST:Last\: %3.2lf°C" \
      "GPRINT:gc:AVERAGE:Average\: %3.2lf°C" \
      "GPRINT:gc:MIN:Min\: %3.2lf°C" \
      "GPRINT:gc:MAX:Max\: %3.2lf°C"
done

exit 0

If you want you can have a look at my current setup here which at the moment only has the three sensors described in the post above. In the graphs you can also see the alias mechanism in action.

Comments