I’ve been using 1wire devices forever. An equipment designer and engineer I hold in high regard introduced me back in grad school and I’ve never turned back. For the 95+% of my applications where the resolution, range and poll speed limitations of 1Wire devices are acceptable, their cost, ease of use, rugged stability, and bus flexibility make them a great choice for sensing and sensor networks.
I started off using 1Wire devices on Windows machines, specifically using LabVIEW and a good old DS9490R, a USB interface that comes with some built-in applications for device location and troubleshooting. Building in device manipulation and reads turned out to be a bit more complicated, and in fact we wrote a package for LabVIEW to deal with these issues and handle some of the more complicated logging devices such as the DS1923. But that’s besides the point of this post, so I digress.
OneWire networks and *nix : OWFS
When I decided I wanted my 1wire devices on my linux boxes for homebrewing, and on my Raspberry Pi for fun projects, I discovered per usual that someone had put together a nice little package. OneWire File System (OWFS) lets me access my 1wire devices as a virtual filesystem. In its simplest implementation, you can have it bind to your physical interface and create an abstraction that is a readable filesystem. So the command
owfs -u /var/1wire
would happily bind your USB adapter (-u) to the directory
/var/1wire. There are implementations for a number of the 1wire family interfaces, so for an i2c devices like the DS2483, you could issue:
owfs --i2c=/dev/i2c-1:ALL /var/1wire
and with a directory listing you’d see something like:
pi@cupid ~ $ sudo ls /var/1wire 28.9E4FA8040000 alarm settings statistics system 28.B3CDA7040000 bus.0 simultaneous structure uncached
Each of the
28.* listings is a directory containing all of your device data. The interface autodetects, so when you attach devices, they pop up. Run a
cat on any of the temperature files within a sensor directory and you get your temp read back to you. Better yet, each resolution option offered by, say, a DS18B20, is represented by a file:
pi@cupid ~ $ sudo ls /var/1wire/28.9E4FA8040000 address errata id r_address scratchpad temperature11 temphigh alias family locator r_id temperature temperature12 templow crc8 fasttemp power r_locator temperature10 temperature9 type
Want 9-bit resolution?
sudo cat /var/1wire/28.9E4FA8040000/temperature9 13
sudo cat /var/1wire/28.9E4FA8040000/temperature12 12.8125
Anyhow, you get the point. Very neat implementation that results in data accessible by any sort of code you might write on top of it. But wait, there’s more!
OWserver, OWhttpd, and OWPython
I’ve been using owfs for quite a while, and it just works. I knew that there were additional features. I just didn’t need them. I knew you could set it up to serve your 1wire data, either locally or via a lightweight webserver. I was, however, content to just read and parse the stuff into my applications.
At some point, however, I discovered there was an owfs python library, aptly named owpython. Lo and behold, it was already built into my owfs installation (2.9p1 here). I was going to start using a more diverse set of 1Wire devices, and I really liked the idea of an object-oriented approach to discovery, aliasing, and databasing. Enough of this text-parsing stuff.
owfs, owhttpd, owpython, OR owserver can bind to the physical 1wire interface
After reading the owpython docs, I realized that could not (or at least should not) bind owpython to the 1Wire interface using the
ow.init() call. The same was true of owhttpd. We needed an arbitrator. Enter owserver. Now, if this conclusion was obvious from the documentation, I truly apologize for my density, but this concept eluded me despite all the reading I’d done. Let me repeat this: owfs, owhttpd, owpython, OR owserver can bind to the physical 1wire interface. If you initialize with and bind to the interface using owserver, you may then instruct owfs, owhttp, and owpython to talk to owserver. It will be the air traffic controller. Let me illustrate below with a functional diagram and the commands issued:
The final commands list for my DS2483 on i2c, which I locate in
/opt/owfs/bin/owserver --i2c=/dev/i2c-1:ALL -p 4304 /opt/owfs/bin/owfs -s 4304 /var/1wire/ /opt/owfs/bin/owhttpd -s 4304 -p 4305
Piece of cake. I can use owpython as I please, and check on connected sensors in raw output form at http://my.ip.add.ress:4305.
There are many other advantages of owserver, such as caching, negotiation, statistics, documented here. We’ll get to that later, along with some python examples.