After toying with the idea for a couple of years, I finally got started on setting up a 1-Wire network in my house to collect temperatures in each of my rooms.  The long delay in getting started with this project is almost entirely from having trouble in finding definitive information regarding what I needed, so I hope to accomplish that here.

Overview

A 1-Wire network is pretty simple: Connect a 1-Wire adapter to a PC, and connect that adapter to the network, be it a hub which connects multiple 1-Wire network segments, or a single 1-Wire run, as you can have multiple 1-Wire devices on a single run.

My setup looks like this:

Server - 1-Wire Serial Adapter - 6 Channel Hub - Two DS18S20s (one on two of the 6 channels of the hub, this leaves me room to expand 4 more channels.  You can also daisy-chain multiple sensors on a single run).

I am using standard CAT5e Eithernet cable for my 1-Wire network; the DS18S20 has 3 pins, two of which are used.  The first pin connects to the white-green wire, and the second to the blue wire.  I will add some more info here later, but it is really that simple.

Connecting it to your PC

I am running Linux on my server.  After wiring up the network and connecting it to the serial adapter, and the adapter to my PC, it was time to get started.

Install digitemp

Digitemp is used to communicate with 1-Wire networks, it has been around for a while, and it works.

sudo apt-get install digitemp

Make sure everything works

  1. We're using a DS9097U serial adapter, so I symlinked the binary for ease of use.
    ln -s /usr/bin/digitemp_DS9097U /usr/local/bin/digitemp
  2. Setup the initial config file. My serial adapter was on /dev/ttyS0, your's may be on /dev/ttyS1.
    digitemp -i -s /dev/ttyS0 -c /usr/local/etc/digitemp.conf
  3. Get some actual data.
    digitemp -c /usr/local/etc/digitemp.conf -a

That third line should produce output similar to this:

kjohnson@zm:~$ digitemp -c /usr/local/etc/digitemp.conf -a
DigiTemp v3.5.0 Copyright 1996-2007 by Brian C. Lane
GNU Public License v2.0 - http://www.digitemp.com
Dec 21 23:09:35 Sensor 0 C: 15.44 F: 59.79
Dec 21 23:09:36 Sensor 1 C: 23.75 F: 74.75

Automate it

Super! Things work.  Now I'd like to start storing this data in a database, so that I can do neat things with it later (like trending graphs).  Make sure mysql is installed (apt-get install mysql-server).  I am using cron to call a perl script which calls digitemp and stores the data in a database (apt-get install libdbi-perl libdbd-mysql-perl)

#!/usr/bin/perl

use strict;
use warnings;
use DBI;

my $dbh = DBI->connect('DBI:mysql:temperature', 'temp', 'password') or die "Could not connect to db: $DBI::errstr";

my @sensors = ( # Digitemp returns sensors numerically, so I am naming them here; the array index matches up to that which digitemp returns.
 'Workshop',
 'Computer Room'
);
my $dt = '/usr/local/bin/digitemp -q -c /usr/local/etc/digitemp.conf';
my $s = 0;      # Start at sensor 0

foreach my $sensor (@sensors) { # For each sensor
 my $date = time;               # Get the current date
 my $temp = get_temp($s);       # Assign the return value of get_temp subroutine to $temp

 insert($s, $sensor, $date, $temp);     # Call the insert subroutine with the relevant data

 $s++;  # Move on the next sensor
}

sub get_temp {
 my $sensor = $_[0];    # Sensor ID
 my $temp = "$dt -t $sensor -o 3"; # Digitemp command to call
 chomp($temp = `$temp | awk '{print \$2}'`);    # Actually call the command.  Chomp removes the new line.
 return $temp;  # Return the temperature to whatever called this subroutine.
}

sub insert {
 my $sensor_id = $_[0];
 my $sensor_name = $_[1];
 my $date = $_[2];
 my $temp = $_[3];
 my $sth = $dbh->prepare("INSERT INTO temperature (sensor_id, sensor_name, time, temperature) VALUES ($sensor_id, '$sensor_name', '$date', $temp)");
 $sth->execute();
}

Now just put this in a cronjob to be called every 5 minutes, and you're golden!

kjohnson@zm:~$ crontab -l
*/5 * * * * /home/kjohnson/1wire.pl
kjohnson@zm:~$