Crawl Space Monitor (aka: No More Frozen Pipes!!)




Introduction: Crawl Space Monitor (aka: No More Frozen Pipes!!)

Water to my house comes from my well through an unheated crawl space. All of the kitchen and bathroom plumbing runs through this space as well. (Indoor plumbing was a slap-on afterthought in the mid 70s on this house!) I've been using heat lamps on "stock tank" thermostatic plugs to maintain a temperature above freezing. There were a couple significant problems with this arrangement:

1 - No visibility. The first indication of burned out bulbs is frozen pipes!
2 - Sometimes the plugs wouldn't shut off. That made for nasty surprises come the electric bill.
3 - No granularity. I kept 3 bulbs "online"(750 watts total) and it was an all or nothing solution. (2 bulbs wouldn't always handle it.)

After being introduced to Arduino, and seeing some of the things other people were doing with it, I decided I would give it a whirl. I will admit right out of the chute that I have shamelessly snagged and tweaked sample code from other people's projects to make this work, though ultimately I have re-written most everything.

Initially, I built this "WiFi Weather Station" that I found on and modified it. Instead of updating a web site, I used Amazon Web Services to send me SMS status updates. I also added the control of some 110V relays ( I then got "smart" and decided to "ruggedize" it -- well -- something shorted something and I got a puff of the magic blue smoke. Everything fried... Not having another CC3000 WiFi breakout, I did things differently this time. I built it to be interactively monitored via serial interface and then added an EZ-Link Bluetooth FTDI interface. (No more dragging the laptop under the house for software updates!!!) I also built a Python interface that connects to the unit via the Bluetooth, queries it regularly, and displays status information on my Mac. (There is also a "human interface" that can be accessed by any terminal emulation software.)

As a result of the re-write and removing all the WiFi and RTC code, the project has shrunk in size from over 29K to barely 10K. It has also improved reliability to the extent that the hardware watchdog hasn't triggered at all in the couple weeks it's been running and I've been tweaking.

2/17/16 Update/note: In an attempt to get proper formatting on some of the code (especially the indenting of the Python code), things went from ugly to unusable. I am sure the issue is on my end somewhere, and I will endeavor to figure it out. Until then, I have added links to the code files through DropBox. They should be accessible to anyone. If not, please let me know so I can get them to you another way!

Step 1: Problems to Solve

The system needed to do the following things for me:

1 - monitor the temperature in the crawl space.
2 - turn on heat lamps as needed to maintain the temperature above freezing.
3 - when not operating, periodically test the bulbs and give me visibility of their status.
4 - give me visibility of the temperature and system status, including:
- is the system running?
- what is the temperature NOW?
- what is the coldest the temperature got?
- how many bulbs ran?
- how many bulbs test good?
- what is my total time in "light minutes" (aka "burn time")?
5 - do all of the above without me needing to crawl under the house!!!

I decided that the easiest way to test for bulb operation was with a light sensor.

Some other issues I wanted to address was the cycle time on the lights. Too slow, and I am burning unnecessary electricity. Too fast, and I run the risk of burning them out from all the switching on & off with the related heating up and cooling off.

Step 2: The Hardware

2 250 watt heat lamps
1 500 watt work lamp (one of my heat lamps disappeared, so this is a stand-in)
Arduino Uno
DHT22 Temperature/Humitidy sensor
GA1A12S202 light sensor
PowerSwitch 110V relays
Bluefruit EZ-Link Serial Interface & Programmer
High-tech case (sandwich sized Rubbermaid tub)
Cable gland
1/2 sized breadboard
Acrylic plate for breadboard and Arduino
Assorted jumper wires.
Coleman 5-outlet "workshop strip"

I also used an Adafruit Trinket as a hardware watchdog, but it has proven to be unneeded (jinx, of course!) and I wrote a separate instructable about it so I won't repeat that here. The Coleman pigtail was a a nice find, as it gave me 4 outlets for my heat lamps PLUS an outlet for the Arduino power supply without any additional splitters or power strips involved. Rated at a full 15 Amps with a switch and an internal breaker, it could handle everything I could pull through a single outlet.

Step 3: The Approach

While the system is application built to sit around waiting, and to do some things relatively slowly, what I didn't want to do was build a system where the controller was sitting in delay() cycles being unresponsive. I also wanted to be able to change the configuration parameters as close to on-the-fly as I could get -- certainly not in a manner that required re-writing code or doing mass search-and-replace operations on the source.

I found Bill Earl's most excellent articles on "Multitasking the Arduino" (start here: and got busy. By creating "timer" and "heater" classes I was able to do all the timing functions I wanted without using delay() (with only a couple exceptions) and configure the bulbs ("heaters") with a single line of code for each one.

Step 4: Wiring It Up.

The Fritzing diagram does not include the Bluefruit EZ-Link

Arduino 5V & Ground to the breadboard bus
DHT22 pin 1 to 5V bus
DHT22 pin 2 to Arduino pin 7
DHT22 pin 4 to Ground bus
10K resistor between DHT22 pins 1 and 2
GA1A12S202 VCC pin to 5V bus
GA1A12S202 GND pin to Ground bus
GA1A12S202 OUT pin to Arduino A0
Arduino 3V pin to Arduino AREF pin
Relay Ground leads to Ground bus
Relay 1 power lead to Arduino A1
Relay 2 power lead to Arduino A2
Relay 3 power lead to Arduino A3
Relay 4 power lead to Arduino A4

Most of these connections can be rearranged as you want. The only one that is critical is the OUT lead on the light sensor needs to go to an analog pin. This pin-out will work with my code as-written.

If you are using the hardware watchdog, you will see my code puts the heartbeat out on Arduino pin 2.

Step 5: The Arduino Code, Main Sketch

Step 6: Notes on the Code

The following lines of code create the instances of the heater and define the operating parameters:

// Heater(relayPin, onTemp(f), offTemp(f), minMinutes, testInterval(minutes), luxDelta)
Heater heater1 = Heater(A1, 38, 43, 20, 1440, 5);
Heater heater2 = Heater(A2, 36, 41, 20, 1440, 5);
Heater heater3 = Heater(A3, 34, 39, 20, 1440, 5);
Heater heater4 = Heater(A4, 32, 37, 20, 1440, 5);

(And yes, I defined all 4 heaters even though I am only running 3 at the moment. I would still need to get another relay, but then adding the 4th heater would be as simple as plugging it in.)

I stagger their trigger temperatures, starting at 38 degrees for the first and ending at 32 for the non-existent 4th. One of the things I found when I first started cobbling this together was that I needed to give a range on the temperature as well as define a minimum "burn time", or I was cycling lights on and off like crazy. Here I give each of them a 5 degree spread as well as a 20 minute minimum burn time. I set the test interval to 24 hours and set 5 lux as the minimum light reading I needed to determine a bulb was still working. Pretty much everything that needs configuring is right here in these 4 lines of code.

Step 7: The Arduino Code, Classes

I created 3 classes for this project. They were "timer", "heater" and "accumulator". With a little more thought I should be able to fold accumulator into timer, but I haven't yet. Here they are in full:




Step 8: Monitoring the System

I created a single interface to two separate monitors. It is an interactive session over the serial console. In my case I am using the Bluefruit EZ-Link so I can access the system without crawling under the house or trying to snake a USB cable in between the floor joists! An added benefit of the EZ-Link is that I can upload new program code to the Arduino over the Bluetooth as well.

The "human" interface can be accessed (Bluetooth or physical cable) with any terminal emulation software, including the Arduino IDE's serial monitor. When you initially connect, there is no response, but the key presses "u" (for "update") and "t" (for "test") will get you the output shown in the screen shot. "m" ("monitor") and "s" ("sys check") get you the same data but in a much less readable format. These are intended to be "scraped" by another program for automatic display. I put together a Python script that does just that. Any other key garners the error message displayed.

You will see a value for "burn time" -- think of this like "bulb minutes" -- 1 bulb for 10 minutes = 10 minutes, 3 bulbs for 10 minutes = 30 minutes.

Step 9: The Python Script

Step 10: Still to Do...

It may not be pretty, or perfect, but it's effective and proving itself to be reliable. AND, I have not had any frozen pipe issues yet this winter!!!

I have a hit-list of things to do. Of course, now that it works, I may or may not ever get around to accomplishing most of these items:

Get Bluetooth running on one of my Raspberry Pi's so I can create a dedicated monitor.
Learn some more Python - then clean up the Python interface. That separation of elements is not on purpose and I don't understand why it is there.
Add an interface to something like Adafruit's IO service so I can monitor it from anywhere.
Add text message alerting.
Move to a smaller controller (possibly a Metro Mini or a Trinket Pro?), less expensive relays, and better packaging.
Get it off a breadboard and onto a "Perma Proto" board.
Configuration parameters in EEPROM.
A more granular interface that will indicate -which- bulbs are good, and possibly even burn time for the individual bulbs.

As I get them done I will come back and update this Instructable.

Step 11: Update 3/16, "permanent" Build

Getting a good break in the cold weather, I have retrieved the unit and moved it to a smaller controller (I had intended to use a Trinket Pro, but had an Adafruit Metro Mini sitting around unclaimed by any other project), soldered it up on a Perma-Proto board, and put it all in a better case. Based on how reliable it has been, I did not put the hardware watchdog back on it. I am still only using 3 lamps/relays where the system will handle 4. The Bluetooth module is on a soldered header, so can be removed if I need it somewhere else. There were no code changes necessary to move to the new controller - a simple recompile and load had me up and running in a matter of minutes. (The Metro Mini has an identical pinout as the Arduino Uno and is also an ATMega328 processor.)

Step 12: Update 12/1/2018 - Welcome to the IoT!

The system has worked flawlessly for us. After two rather severe winters, NO frozen pipes. In fact, the system was able to maintain the pipes without ever burning more than 2 bulbs. Having the 3rd bulb online was nice insurance, but we have not ever needed it to-date.

Coming into year 3 for the system, the Bluetooth module failed. We also built a new house, so the monitoring system is well outside of Bluetooth range. (The old house is staying up for a while, but not forever.) In the intervening time, I have been doing a lot with the ESP8266 WiFi enabled processor; both in Adafruit Feather format and in the open-source "NodeMCU" format. The NodeMCU can generally be found on Amazon for around $5 - much less if you buy in bulk and/or from someone like AliExpress.

This new version maintains the serial interface, so it could still be used with a Bluetooth module or direct USB serial connection and the previous python script, however, the new version has a web-page interface. As written, it includes the following feature:

A WiFi network manager to eliminate hard-coding WiFi credentials.

The ability to update the firmware over-the-air using the Arduino IDE (as long as you are on the same WiFi network -- note that after doing a USB upload to the device, a reset is needed before OTA updates will work). PLEASE change the OTA password on line 6 to be unique to you!!

A web page that displays the same data the python script does, with an automatic refresh every minute. I did not put any kind of security on the page, because it is display-only.

You can find the new code here. Do note that the pin names change when moving to the NodeMCU.

1 Person Made This Project!


  • Microcontroller Contest

    Microcontroller Contest
  • Plywood Contest

    Plywood Contest
  • Halloween Contest

    Halloween Contest



5 years ago

I somehow came across your instructible. I will volunteer a completely different solution. Its expensive heating air, you only need to warm the pipes! If you are willing to shell out some money then you can duplicate the pipes, wrap good insulation around them along the length, add a pump (one way valve in parallel to reduce stale water, pump pushes downstream) that periodically creates a flow in the loop. Then have thermometers on both sides and if it notices that the loop is getting a little too cool, have them turn on a heater and the pump until the whole loop is warmer. The heater only needs to outrun the cooling of the loop (now reduced due to the insulation), so perhaps it may drop your consumption to just 30W. Use a pelter and coolsink it to add extra heating capacity for your watt.


Reply 5 years ago

Since a water pump is a bit too much effort, do the same but with insulation around PVC pipe which around the water pipe in question, and use a PC fan to circulate the air through the PVC loop. Yes this is warming air, but you are not warming the walls, ceiling or the air flowing past the house.


Reply 5 years ago

Good ideas, but sounds like diminishing returns on both the work and cost involved. My current solution has reduced the electricity cost of the system to just a couple dollars per month. I just built a smaller system to heat an enclosure with a single bulb & LED feedback instead of the serial monitor feedback -- designed/built/coded/debugged/installed in about 1/2 a day with a cost (including the enclosure!) of under $75 (USD) -- considering the materials for the enclosure was wood remnants from other projects, my true cost was closer to $20.


6 years ago

@jonfrei, I am looking for someone with more knowledge than me in helping me with a project of my own. would you be interested in offering me some advice and pointing me in the right direction?


Reply 6 years ago

I don't know that I'm that knowledgeable - I'm pretty good at following and adapting other peoples examples... What kind of project are you talking about?


Reply 6 years ago

I want to use something I found on Kickstarter called Wio Link to control the garage door opener at work with relays using an app on my phone. I thought you might be knowledgeable enough because you were similarly using small scale voltages/Currents with the computer stuff and monitoring/controlling larger scale voltages of a house. I am just very new to the micro controller world.

Currently trying to figure out how to attach photos... do u feel comfortable sharing your email address with me?


Reply 6 years ago

I looked at the device -- I have no experience with the REST API, so I don't think I would be much help to you.


6 years ago

why did you build the circuit on breadboard


Reply 6 years ago

I've done the update/rebuild -- look at the new step 11 to see it on a Perma-Proto board in a nice case...


Reply 6 years ago

I also want to move it to a smaller controller before I start soldering...


Reply 6 years ago

Because I cobbled it together (after frying the 1st one) in a hurry ahead of the freezing weather. I will move it to a more permanent assembly as soon as I get a break in the weather. With a waking temp outside of 7 (F), I'm glad it was there in ANY form factor!


6 years ago

Nice job ~ thanks for sharing this! [about 10 years ago, while running a new 1" pvc line from pumphouse into-the-residence...under the "crawlspace"... I added a 3/4" Carlon conduit into the trench, complete with pull-line. I expected {i.e., "hoped"} to one day add a sensor and alarm to tell me when I needed to flip the switch to turn on the heat-lamp out there. Never did get that far...(!) The conduit remains empty; but, I just might DO this, now that I am playing with an Arduino and a "Pi".


Reply 6 years ago

We just went through some single digit temperatures here & it was awesome peace of mind to have this under the house. It will also be nice come electric bill time -- things are running at about a 1/6 duty cycle (compared to 3 bulbs on all the time).