1-Wire Network

From Wiki
Jump to navigationJump to search


Front of house
Side of house

Many times I've found myself wondering how hot our attic was getting in the summer. Our house is a Cape Code design, and has an upper attic, and a side attic. The side attic is accessible through a walk-through door, while the upper attic is accessed through a drop-down set of stairs. The question of how hot the attic was getting became particularly interesting when we had a new roof installed, and added a ridge-vent system.

The original roof had 5 square vents on the backside. The roof has two peaks, with a gable vent at each end of the upper attic, and a single gable vent at the peak of the side attic. Two of these can be seen in the photograph on the right.

Unfortunately, I had not instrumented the attic prior to the new roof being installed. Installing the sensors this late in the game would only allow me to compare what effect closing off the gables would have on the ridge vent system. Leaving the gables open effectively "short-circuits" the airflow. What should happen is that air in the attic heated by the roof should rise, pulling in cooler air from the soffit vents (these are the vents that are usually just behind the rain gutters, and are parallel to the ground). When the gable vents are uncovered, the rising air would pull the majority of the air in from the gable vents, resulting in the attic not being cooled as effectively as possible.

My intent was to measure a several weeks of hot summer days, then cover the gable vents and compare several weeks of data. Because I am a slackard, I have not gotten around to actually covering the gable vents, so my data collection is extending well into the winter.

Going 1-Wire

Temperature graph

In early May of 2007 I installed 4 Dallas DS18B20 temperature sensors. These are monitored by a small EPIA 1Ghz ITX form-factor motherboard running Linux and using OWFS. A custom C program polls the sensors every 5 minutes, along with my Davis VantagePro weather station, the temperature sensor in the APC SUA2200RM2 UPS, and the temperature from the closest airport, KGVL. This data gets logged to a mySQL database, and the resulting data is displayed by a PHP script using JpGraph.

There are a lot of ways to wire a 1-wire network. Hobby Boards has a lot of nifty little kits, but quite frankly, they're a little expensive. At least, when you're as cheap as I tend to get about electronics. Being in the industry for 30 years, I know what the costs are. I also understand that companies need to make a profit to survive, but I still resent paying more than what I know it would cost.

I spent a couple days scheming a way that would result in the minimum expense, and almost as important, minimal time spent in the attic doing wiring. What I came up with was crimping the DS18B20's directly into RJ-45 connectors. I slipped a little bit of wire-wrap wire insulation over the leads to prevent shorting. Luckily, the pin ordering of widely-used RJ-45 wiring made this pretty easy. You can see the results in the picture.

Next was a way to interconnect the sensors. After hitting up the electronics wasteland that is Fry's (and, as expected, finding nothing useful), I did find these nice little RJ-45 3-way connectors from Triangle Cables. Now all I'd have to do is crimp RJ-45's in the attic, and then plug them together.

This worked out quite well. It probably took me all of an hour to pull cables, crimp RJ-45's on, plug everything together, then fire up OWFS. As hoped and expected, all four sensors immediately came up. I did build a little adapter that injects 5 volts from the USB connector on the back of the PC into the cable. The DS9097U-009 that I'd had laying around for years does not supply 5 volts on its connector, and since I wanted to be able to power a number of devices, the adapter was in order. If I hadn't had the DS9097U, I would have used a DS9490R.

So data has been collecting for a while, and it's pretty interesting looking at the trends, and see how a cloudy day can result in a much cooler attic temperatures, even if the the outside air temperature is warmer than on a sunny day.

Add Squirrels To The Mix

The trap
The trip sensor
Intended target
DS2405 (in box) and DS18B20 (right)
The 1-wire server, UPS, and a DS18B20

Sometime around November of 2008, I heard some scratching about in one of the walls. With the old roof, I knew some squirrels had gotten in, and when the roof was replaced, that area was well sealed. Somehow, they've found another way to get in. I borrowed a live-trap from a friend, baited it with some Cheerios, and left it alone. I sort of forgot about the trap for a week or two, and when I remembered to check it, there was a small dead squirrel in it. I would say I felt sorry for it, but quite frankly, they're destructive little rodents, and while they're cute in trees, they don't belong in houses. And if I was lucky, he hadn't had a chance to tell his little squirrel buddies how he found his way in.

Of course, this set me to thinking about how to monitor the trap. I decided the best way was to simply add something like a DS2405 addressable switch, and tap in to the 1-wire network that was about 2 feet away. I had some DS2405's laying about, so I tacked one to a piece of protoboard, added a screw-terminal header, and put it in a project box (see picture). Unfortunately, I failed to remember to take a picture of the protoboard before sealing the box up.

I used a standard magnetic alarm contact on the trap. When the magnet is near the the switch, the switch is closed, and pulls the 100K ohm resistor to ground. This causes the DS2405 to report the PIO pin as 0, indicating the trap is armed. When the trap fires, the switch goes open, the 100K ohm resistor pulls the PIO line to +5, and the DS2405 reports a 1.

Wiring the trap up so that the switch is closed when armed also helps with detecting failures in the cable. Mostly likely, these would be caused by the tree rat chewing through the wire, but it might become unplugged, or the magnet could move too far from the sensor for some reason. In any of these failure modes, the line will no longer be grounded, and it will appear as if the trap has fired.

The monitoring program, unfortunately, logged everything every 5 minutes. I really didn't need thousands of records of 0's in the trap database table, so the program was modified to only write a new trap record when the state changed, regardless if it was from zero to one, or one to zero. The monitor program has a configuration table it reads that tells it what the sensor 1-wire address is, what class (temperature, I/O, lightning, whatever), physical location, what table to update with the data, etc. I added a column to indicate if the sensor in that record should only be updated when it changes, or every time it's read.

So now the monitor program takes care of writing the trap records, and only when they change. But what to do about monitoring for those changes? I didn't want to implement a web page I'd have to constantly monitor, nor did I want to manually issue SQL commands to read the table. No, a good program knows how to send email...

mySQL Is Great, Except When It Sucks

I use mySQL for most of my database work. It's fast, it's small enough, easy to maintain, there's modules for Perl, C, PHP, etc.

But allow me to divert for a moment: When I added the trap monitoring support to the monitor program, I didn't want to change the table structure that I used for the other data tables. The temperature table, lightning table (an extension I did for a friend to monitor his lightning detector), and the trap table all have the same schema.

For an external program to monitor the trap table and send e-mail, I'd have add a flag to indicate whether the email had already been sent or not. I didn't want to have to maintain an additional table or external file that indicated when the program had last sent an email, and all the mess that goes with that. In a flash of inspiration (and partly because it's cool, and I hadn't used it before), I decided I could use a SQL trigger condition to send an email when an insert operation was performed on the trap table (i.e., a new record was added).

Some quality time was spent with Google. mySQL doesn't allow executing external programs as part of a trigger. At best, you can write to a file, using the SELECT ... INTO OUTFILE statement. An external program would have to watch for the file to come into existence, send it via the system mail command, then delete it. OK, that seems workable. A trigger was written, and a file was created. Except... That if the file already exists, you can't overwrite it, nor append to it. So if two triggers occur back to back (say because a 2nd trap was being monitored), I'd miss an event. OK, let's use a variable for the file name, and we'll add a unique number to the name. Except that mySQL doesn't support using a variable for a file name, so SELECT ... INTO OUTFILE @name doesn't work.

Grrr.... More Googling. An example is found using dynamic SQL. This is basically putting the contents of an SQL statement into a variable, then executing the variable using PREPARE and EXECUTE. Except mySQL doesn't support dynamic SQL inside triggers. Now I'm getting mad. Time to fall back to "tractor technology", i.e., doing it the uncool, no-fun, non-modern techology way.

The final solution was to use a trigger that runs when the trap table has a record inserted. An email address table ('TriggerAddresses') was created that contains the 1-wire sensor address, a "to" email address, a "from" email address, a subject line and a body message. The trigger extracts those fields from the record that matches the 1-wire address that triggered the trap, and writes those to another table ('SendEmail') that includes a "sent" flag. By default it's 0, so when the record is created by the trigger, that email is marked as unsent.

A Perl program was written that scans the 'SendEmail' table for all records that have a "sent" flag of 0. The email is then sent through MIME::Lite, and the "sent" flag updated to 1. By using the flag and not deleting the record, I also have a history of any emails sent.

Tractor technology, but it works. If I used postGres, I could have avoided most, if not all, of these problems. However, I have mySQL installed and working, and dozens of other programs are using it. I didn't really want to install another database system and learn how to administrate it, just for one little program.

(A user in irc.freenode.net/#irc happened to mention he had a similar problem, and worked around it with user variables. [1])

End Result

So far the trap monitor has been running for a few weeks, but no squirrels have been caught. I've manually fired the trap a couple times to make sure emails are sent, and all that works rather nicely.

I think the next project is to monitor the garage door, to make sure it's been closed before we go to bed. Another possibility is adding some monitoring to the two HVAC systems, to record the return temperature, air handler temperature, fan and compressor status, current draw and humidity. It'd be a lot of neat data, although I'm not sure what I'd do with it...