www.technotes.se » Blog Archive » Getting 1-wire sensors working in Linux
Oct
23
Posted on 23-10-2010
Filed Under (1-wire, Bash scripting, Linux, Sensors) by Lonezor

The 1-wire bus system can be used to connect one or several sensors to a PC or smaller device such as a microcontroller. This may involve sensors such as thermometers, hygrometers, light sensors and barometers.

A temperature sensor connected with a 1-wire USB adapter

If connected to a PC, sensor readings can be stored in a database or some other means of storage. Then the data can be visualized using a web server and graph generating software. Below is one example of such a graph:

When using the USB adapter DS9490R it is possible to interface these sensors with a Linux FUSE filesystem driver. This makes data sampling very convenient. The FUSE driver of interest in this particular case is the OWFS driver.

Installing needed software packages
FUSE and libusb are needed in order to build OWFS. Luckily these software packages are included in most distributions (e.g. Debian and Ubuntu). The development packages are needed since header files must be available. The ‘checkinstall’ tool is used to be able to keep manually build packages within the distribution’s own package management system (i.e. to avoid having untracked files on the file system).

Install needed packages for OWFS:

$ sudo apt-get install libusb-dev
$ sudo apt-get install libfuse-dev
$ sudo apt-get install checkinstall

Note that the libusb package is the legacy library and not the current libusb under development.

Add the following entry to /etc/fuse.conf:

# Allow non-root users to specify the 'allow_other' or 'allow_root'
# mount options.
#
user_allow_other

Download and build OWFS from source code. Install it with the help of checkinstall (you may use ‘make install’ instead if you prefer that command):

$ wget http://downloads.sourceforge.net/project/owfs/owfs/2.8p2/owfs-2.8p2.tar.gz
$ tar zxvf owfs-2.8p2.tar.gz && cd owfs-2.8p2
$ ./configure --prefix=/usr --enable-owfs --enable-usb
$ make
$ sudo checkinstall --pkgname=owfs --pkgversion=owfs-2.8p2 --backup=no --deldoc=yes --default

Setting up a temperature sensor
Now, plugin the 1-Wire USB adaptor together with at least one sensor. Mount the file system:

$ sudo mkdir /mnt/1-wire
$ sudo owfs -u --allow_other /mnt/1-wire
DEFAULT: ow_usb_msg.c:DS9490_open(263) Opened USB DS9490 bus master at 6:2.
DEFAULT: ow_usb_cycle.c:DS9490_ID_this_master(191) Set DS9490 6:2 unique id to 81 E5 4B 2E 00 00 00 94

$ cd /mnt/1-wire && ls -l
drwxrwxrwx 1 root root  8 2010-10-12 21:32 10.3D4170010800
drwxrwxrwx 1 root root  8 2010-10-12 21:32 81.E54B2E000000
drwxr-xr-x 1 root root  8 2010-10-12 20:11 alarm
drwxr-xr-x 1 root root  8 2010-10-12 20:11 bus.0
drwxr-xr-x 1 root root  8 2010-10-12 20:11 settings
drwxrwxrwx 1 root root  8 2010-10-12 21:32 simultaneous
drwxr-xr-x 1 root root  8 2010-10-12 20:11 statistics
drwxr-xr-x 1 root root 30 2010-10-12 20:11 structure
drwxr-xr-x 1 root root  8 2010-10-12 20:11 system
drwxr-xr-x 1 root root  8 2010-10-12 20:11 uncached

$ cd 10.3D4170010800 && ls -l
-r--r--r-- 1 root root  16 2010-10-12 20:11 address
-r--r--r-- 1 root root 256 2010-10-12 20:11 alias
-r--r--r-- 1 root root   2 2010-10-12 20:11 crc8
drwxrwxrwx 1 root root   8 2010-10-12 21:36 errata
-r--r--r-- 1 root root   2 2010-10-12 20:11 family
-r--r--r-- 1 root root  12 2010-10-12 20:11 id
-r--r--r-- 1 root root  16 2010-10-12 20:11 locator
-r--r--r-- 1 root root   1 2010-10-12 21:36 power
-r--r--r-- 1 root root  16 2010-10-12 20:11 r_address
-r--r--r-- 1 root root  12 2010-10-12 20:11 r_id
-r--r--r-- 1 root root  16 2010-10-12 20:11 r_locator
-r--r--r-- 1 root root  12 2010-10-12 20:11 temperature
-rw-rw-rw- 1 root root  12 2010-10-12 21:36 temphigh
-rw-rw-rw- 1 root root  12 2010-10-12 21:36 templow
-r--r--r-- 1 root root  32 2010-10-12 20:11 type

$ printf "%s\n" `cat temperature`
33.125

Yes, it is very easy to use, no need to care about the inner workings of the A/D converter. You can just use commands such as ‘cat’ on the file to get the current value.

Automated sampling
The next step is to automate sensor sampling using a script called sensor_read.sh:

#!/bin/sh

DB_DIR=$1
SENSOR_FILE=$2

sensor_value=`cat $SENSOR_FILE | awk '{print $1; }'`
timestamp=`date +%H:%M`
date=`date +%Y-%m-%d`

echo "Time: $date $timestamp"
echo "Sensor value: $sensor_value"
echo "$timestamp $sensor_value" >> $DB_DIR/$date

Together with a cron job the PC can take samples every 5th minute every day of the year (five minute snapshots is probably enough resolution for most uses):

*/5 * * * *     /usr/bin/sensor_read.sh /var/sensors/indoor_temp /mnt/1-wire/26.946E8C000000/temperature
*/5 * * * *     /usr/bin/sensor_read.sh /var/sensors/hygrometer /mnt/1-wire/26.946E8C000000/humidity
*/5 * * * *     /usr/bin/sensor_read.sh /var/sensors/outdoor_temp /mnt/1-wire/10.D5A392010800/temperature

This will generate files like this:

$ ls -l /var/sensors/outdoor_temp/
-rw-r--r-- 1 root root 3560 2010-09-28 23:55 2010-09-28
-rw-r--r-- 1 root root 3597 2010-09-29 23:55 2010-09-29
-rw-r--r-- 1 root root 3538 2010-09-30 23:55 2010-09-30
-rw-r--r-- 1 root root 3601 2010-10-01 23:55 2010-10-01
-rw-r--r-- 1 root root 3592 2010-10-02 23:55 2010-10-02
-rw-r--r-- 1 root root 3630 2010-10-03 23:55 2010-10-03
-rw-r--r-- 1 root root 3677 2010-10-04 23:55 2010-10-04
-rw-r--r-- 1 root root 3735 2010-10-05 23:55 2010-10-05
-rw-r--r-- 1 root root 3773 2010-10-06 23:55 2010-10-06
-rw-r--r-- 1 root root 3778 2010-10-07 23:55 2010-10-07
-rw-r--r-- 1 root root 3709 2010-10-08 23:55 2010-10-08
-rw-r--r-- 1 root root 3606 2010-10-09 23:55 2010-10-09
-rw-r--r-- 1 root root 3490 2010-10-10 23:55 2010-10-10
-rw-r--r-- 1 root root 3559 2010-10-11 23:55 2010-10-11
-rw-r--r-- 1 root root 3229 2010-10-12 21:45 2010-10-12

cat /var/sensors/outdoor_temp/2010-10-10
22:35 6.625
22:40 6.5
22:45 6.4375
22:50 6.3125
22:55 6.125
23:00 6
23:05 5.9375
23:10 5.875
23:15 5.8125
23:20 5.6875
23:25 5.6875
23:30 5.5
23:35 5.5
23:40 5.4375
23:45 5.375
23:50 5.25
23:55 5.1875

Disconnecting the 1-wire filesystem
Disconnecting the FUSE filesystem can either be in the form of killing the owfs process or by umounting the direcory:

$
sudo umount /mnt/1-wire

Next steps
It is also possible to connect to a database server such as MySQL or Sqlite and store the data in a way that enables more advanced handling. Using the SQL syntax for search queries has its advantage over parsing raw data in your own program code. You can check out the guide “1-wire sensor logging with MySQL” for information about this.

Also, for graph generation there are different alternatives, e.g.
rrdtool
open flash chart
gnuplot

(6) Comments    Read More   

Comments

Joe P. on 16 May, 2011 at 13:31 #

Followed your instructions for getting a basic 1-wire temperature sensor going. Worked perfectly! Thanks for taking the time to do the write-up.


Thomas W. on 30 November, 2011 at 17:36 #

Nice graph! I’m using RRDtool to generate graphs but they don’t look like your graph at all. What tool are you using?


Lonezor on 3 December, 2011 at 18:42 #

The graph is created with Open Flash Chart:
http://teethgrinder.co.uk/open-flash-chart/gallery.php

One nice feature is that the graph’s values can be seen by hovering with the mouse cursor over the curve in the browser.


Jose on 12 April, 2012 at 10:48 #

Perfect


Fredrik Andersson on 5 June, 2012 at 09:21 #

Hello
How much memory do I need to store data from one 1wire sensor? I use a SD card to store the data.
Kind Regards Fredrik Andersson


Lonezor on 24 July, 2012 at 21:29 #

Hi!

Memory required is a couple of bytes for each entry. The value is stored as an ASCII string. If storage is a concern it can be encoded in binary format taking 1-4 bytes. Also how often you take values can be adjusted. No problem with SD card storage unless a lot of sampling is needed.


Post a Comment
Name:
Email:
Website:
Comments:
*