MacWhiz Blog Macs, customer service, and other musings Sun, 01 Feb 2015 16:46:10 +0000 en-US hourly 1 Raspberry Pi-powered Oil Tank Monitor, Part 4: Theory of Operation; Cost Sun, 01 Feb 2015 16:46:10 +0000 So how does the tank monitor actually work?


The Parallax Ping))) uses one pin, SIG, for both triggering the ping and receiving the resulting pulse. It also uses 5-volt logic. Therefore, we need a voltage divider to reduce the 5-volt pulse down to the 3.3 volts that the Raspberry Pi can handle. But we don’t want to reduce the 3.3-volt pulse from the Pi that will trigger the Ping))); the Schottky diode allows our trigger pulse to pass reasonably unimpeded while blocking the 5V from the Ping))). The Ping))) will accept a 3.3-volt pulse as a trigger. As an added precaution, a 3.3V Zener diode protects the Pi from overvoltage in case something goes wrong with the resistive voltage divider.

Our sensor code sends the trigger pulse, and then changes the GPIO pin from an output to an input. It then waits for the Ping))) to drive the pin high, while keeping track of the current time. If it doesn’t see the pin go high within 0.02 seconds, the measurement times out—that’s a longer delay than any ping within the Ping)))’s rated distance.

Next, we wait for the Ping))) to drive the GPIO pin back low—the end of the voltage pulse. That time is also noted. Simple subtraction provides the length of the pulse.

This is where the Pi is not ideally suited to the task at hand. Because the Pi is running Linux, a preemptively-scheduled multitasking operating system, the Pi may be busy doing other things instead of running our code when the pin goes high or low. That introduces timing error, which means measurement error. Python isn’t well-suited to reducing this error; it should be possible to write code in C that can leverage the Linux kernel’s real-time scheduling mode, which minimizes the chances of being interrupted by another process. In the meantime, the following things reduce the chances of measurement error:

  • Overclocking the Pi. Faster processor speeds mean more frequent checks of the GPIO pin. Also, competing tasks will complete more quickly.
  • Avoiding running other processes on the Pi. Using the Pi for anything else—even a web user interface for the oil tank monitor—will increase the chances of resource contention and therefore measurement error.
  • Running the oil tank measurement process at the highest user priority. Using “nice -n -20″ (which requires superuser privileges or the CAP_SYS_NICE capability) will reduce contention from other userland processes, but won’t help much with kernel interrupts.

With the duration of the Ping)))’s voltage pulse at hand, it’s simple math to determine the distance. The key number is the speed of sound in air. This varies depending on the temperature of the air. At 70°F, it’s 343.963 meters per second. In a 62° basement, it’s 341.355 m/s; at 32°, it’s 331.395 m/s. If the basement and oil tank is very well temperature controlled, one could just plug in a hard-coded value. But oil tanks are usually connected to outdoor air via a vent pipe, and basement temperatures can fluctuate as the furnace cycles on and off. So, I incorporated a temperature sensor to detect the air temperature near the Ping))) sensor. My code uses the approximation

V ? 331.4 + (0.6 × T)

where V is the velocity of sound in air and T is the temperature in degrees Celsius. This approximation is technically for “dry air;” the speed of sound also varies somewhat based on humidity. For now, I’m ignoring the humidity part of the calculation; it’s certainly possible to incorporate a temperature-and-humidity sensor and do more math for an even more precise calculation. On the Pi, that might start to exceed the accuracy of the timing…

Between the inherent limitations of acoustics and the limitations of the Pi, occasionally our sensor result will be way off. Commonly, it will return slightly different answers if you make two measurements right after the other. To minimize this effect, my code takes a number of samples, and then discards the highest third and lowest third of the samples. It averages the remaining samples and rounds the result to the nearest centimeter. (The Ping))) sensor is only rated for 1cm accuracy, so retaining additional “precision” is not useful.) This is a place where I wish I had a better understanding of statistics, to further improve the handling of outliers.

Finally, we subtract a “fudge factor,” which corrects any measurement error. The Ping))) is actually pretty accurate. But there is one measurement error of importance in this design: The distance between the plane of the top of the oil tank and the plane of the Ping))) sensor. It’s unlikely that the sensor will seat so far into the tank that the Ping))) is exactly even with the tank’s top. The fudge factor allows me to compensate for this. Before installing the sensor in the tank, I measured the actual oil level with a stick. I could then easily calculate the fudge factor required to obtain an accurate reading that matches the stick.

The result from the sensor code is the distance from the Ping))) to the oil—the height of the air in the oil tank.

Now we need the dimensions of the inside of the oil tank. There’s a little inaccuracy here, because it’s really difficult to get inside and measure; instead, I measured the outside of the tank and the visible thickness of the tank material, and used that to estimate the inside dimensions. I have tanks that have an oval cross-section with flat sides, vertically oriented (short side of the oval up). To calculate volumes inside such a tank, I need the height of the tank at its widest point, the depth of the tank at the flat part of the sides, and the width of the tank.

Given the height of the tank, I can subtract the height of the air inside the tank (obtained from the sensor) to determine the height of the oil inside the tank.

I found a website that has formulas for calculating volumes inside various types of tanks. For my style of tank, you can calculate the volume by thinking of it as if it were two tanks: A perfectly square tank with a height equal to the distance between the curved parts of the oval end, and a perfectly round tank with a radius equal to the radius of the curved parts of the oval end. (The oval ends are each a semicircle; imagine cutting them off and welding them together to make a full cylinder. The leftover tank bits would make a rectangular solid.)

So, to calculate the full volume of the tank, I calculate the volume of the cylinder and of the rectangular solid and add them up. For my tanks, I find that it comes out a bit less than the nominal capacity of the tank. Somehow, I’m not surprised.

What about the radius of the curve? Well, because the tank doesn’t have a flat spot at the top—it’s a perfect semicircle—I don’t need to measure the radius. I know that the diameter of the imaginary cylinder will be equal to the depth of the tank, because that semicircle has to mate up to the rectangular portion of the side. The radius is half the diameter… or half of the tank’s depth.

As for the volume of oil in the tank, the calculation changes depending on how full the tank is.

  • If the oil level is in the rounded bottom portion of the tank, pretend it’s in a cylindrical tank. Imagine you’re looking at the end of the tank. Draw a line across the circle of the tank to represent the oil level. Then use trigonometry to determine the area of the circle beneath that line. Multiply by the length of the tank and you have volume.
  • If the oil level is somewhere in the straight-sided middle of the tank, first calculate the volume of a half-full cylinder. Then subtract the radius of that cylinder from the oil height. Now calculate the volume of oil in a rectangular tank that’s filled to that height. That’s a simple HxWxL calculation. Add the two together and you have the volume of oil in the tank.
  • If the oil is in the top rounded portion of the tank, it’s easier to calculate the volume of air in the tank and subtract that from the volume of a full tank. As with the first case, this is done by imagining the top part of the tank as a perfect cylinder, and using trigonometry to calculate the area filled with air.

Note that all this math is done using the metric system. The TMP102 sensor returns the temperature in degrees Celsius. That makes it easiest to calculate the speed of sound as meters per second, resulting in a distance measurement in centimeters. Therefore, our volume calculations are in cubic centimeters. I use a simple formula to convert cubic centimeters to U.S. gallons.

My sample code also has a very basic time estimate. All oil furnaces have a rated gallons-per-hour fuel consumption; it’s typically printed on the furnace’s specifications plate. With that value, it’s easy to calculate how many hours of furnace running time are remaining based on the current oil level. I also make a rough guess of how many days worth of heating that runtime equates to, based on an average number of running hours per day. I hard-coded that value based on the last week’s data from my Nest thermostat. Future revisions will monitor daily oil consumption and use that to estimate days remaining. (Unfortunately, Nest does not currently provide furnace runtime in their Works With Nest API, so I can’t get this data directly from the thermostat.)


So what did this project cost me?

The single most expensive part of my build was the Ping))) sensor, at $30. However, I expect one could build a similar unit using the HC-SR04, which costs between $2 and $5 depending on quantity. The HC-SR04 uses separate pins to trigger the pulse and return the result, so using it would require minor changes to the interface circuitry and possibly the code.

The next most expensive part was the Raspberry Pi. I used a Model A+, which has a suggested retail price of $20. However, I found it cheaper to buy on Amazon at $25, because I have Prime shipping. The few retailers with the Model A+ in stock at $20 wanted an average of $6 for shipping.

The plumbing parts cost $14.60. If you’ve got spare PVC parts knocking about, you can economize here. You could also use a simple 2″ cap and glue it in place instead of using the 2″ to 3″ parts and cleanout. You’d have to unscrew the whole thing to clean the sensor, and you’d need to rebuild it if serious repairs were needed but it would cut the cost of pipe in half. I don’t recommend using thinner pipe, because the unit needs to withstand the pressures introduced when the tank is refilled. Care should be taken with alternate materials; some plastics can be dissolved by fuel oil. I chose PVC and acrylic because they both have good resistance to diesel oils.

I used a network adapter that I had on hand. I figure a new adapter off Amazon would cost about $8, for either wired or Wi-Fi.

Not including a case to hold the Pi and the interface board—you can order a suitable project case, or find something to reuse like I did—the approximate cost of the materials to build this project the same way I did is $109. Using an HC-SR04 would probably reduce that to about $81. If you have worked with PVC pipe before and know how to solder, it can be built and installed in a weekend or less.

For comparison, the closest commercial sensor system I’ve found costs $129, and it only provides a 10-segment bar graph. It doesn’t connect to the Internet, and therefore can’t be programmed to send you alerts when your oil is low, adjust your thermostat to conserve oil when the level is critical, provide daily reports on oil levels and consumption, give a close estimate in gallons of remaining fuel or days of oil remaining at current usage, or any of the other things my homebuilt unit can do. The same site offers an Internet-connected controller with an ultrasonic sensor and temperature sensor for $928, which doesn’t appear to offer even as much functionality as my demo program.

]]> 0
Raspberry Pi-powered Oil Tank Monitor, Part 3: Basic Software Sun, 01 Feb 2015 04:06:25 +0000 Now that I’ve got a sensor unit for measuring the heating oil left in my tank and the interface board and Raspberry Pi needed to do something with it, it’s time to write software that can actually do something with all this hardware!

As a preface, let me say I’ve not written anything in Python before I got my first Pi for Christmas. Perl, sure. Shell script, yep. But I hadn’t had need to learn Python yet. The GPIO libraries for Perl on the Pi aren’t all that great, so Python it is. People who program Python for a living, please be kind.

Temperature Sensor

First, I wrote a very quick and dirty module for reading the temperature sensor:

# A python module for interfacing with a SparkFun TMP102 breakout module
# or other implementation of a TMP102 chip via I2C bus
import smbus
# Default definitions
module_address = 0x48
system_i2cbus = 1
def read():
	# Reads the temperature from the Pi's default i2c bus using a
	# TMP102 set at the default i2c address. Returns decimal temperature
	# in Celsius.
	# Create an object for reading from the system i2c bus
	bus = smbus.SMBus(system_i2cbus)
	# Read the temperature data block from the TMP102 module
	data = bus.read_i2c_block_data(module_address, 0)
	# Extract the least and most significant bytes from the data block
	msb = data[0]
	lsb = data[1]
	# Return the decimal value

Tank Calculations

Next, a basic program for reading the tank sensor and calculating how much oil is left:

# Oil Tank Monitor Script
import time
import math
import RPi.GPIO as GPIO
import signal
import atexit
import tmp102
timeout = 0.020         # Longest time to wait for a ping response (sec)
gpio_pin = 7            # Pin where the Ping))) is connected (Board numbering)
num_pings = 40         # Number of times to read the distance
fudge_factor = 2        # Distance to subtract from measurement (cm)
tank_width = 68         # Width of one tank in centimeters
tank_height = 111.5     # Height of one tank in centimeters
tank_length = 151       # Length of one tank in centimeters
num_tanks = 2           # Number of tanks in system
oil_burn_rate = 1       # Rate at which oil is burned (gal/hr)
daily_runtime = 5       # Average daily hours of operation 
# The oil burn rate is defined by the nozzle used on the oil burner.
# The furnace documentation should list the rated nozzle size in GPH
# (gallons per hour).
def cleanup():
    print "Cleaning up GPIO."
def termhandler(signum, frame):
    print "Terminating script."
    global shutdown_flag
    shutdown_flag = True
def add(x,y): return x+y
def init_sensor():
    """ Prepares the Ping))) sensor for use """
    GPIO.setup(gpio_pin, GPIO.OUT)
    GPIO.output(gpio_pin, 0)
def read_distance():
    Determines the distance from the sensor to the oil in the tank.
    # For improved accuracy, we will take many measurements:
    distances = []
    for ping_number in range(1, num_pings):
        while not successful:
            # Signal the Ping))) to send a pulse
            GPIO.setup(gpio_pin, GPIO.OUT)
            GPIO.output(gpio_pin, 0)
            GPIO.output(gpio_pin, 1)
            GPIO.output(gpio_pin, 0)
            # Wait for the Ping))) to send back a timing pulse on the GPIO pin
            GPIO.setup(gpio_pin, GPIO.IN)
            goodread=True       # Assume a good read until we learn otherwise
            while GPIO.input(gpio_pin)==0 and goodread:
                if (starttime-watchtime > timeout):
                    # Bad read - timed out
            # Okay, we now have detected the start of the timing pulse and 
            # noted the time it was received. Now look for the end of the pulse
            # so we can determine the overall length of the pulse.
            if goodread:
                while GPIO.input(gpio_pin)==1 and goodread:
                    if (endtime-watchtime > timeout):
                        # Bad read - timed out
                # Timed out before we saw the start of the timing pulse
                # Try again...
            # We've detected the end of the timing pulse (or a timeout);
            # if it was a timeout, try another measurement.
            if not goodread:
            if goodread:
                # Get the current air temperature. The speed of sound in air
                # varies according to temperature, so having an accurate 
                # temperature allows us to calculate distance accurately.
                # Calculate the current speed of sound 
                c_air_m_s=331.5 + (0.6 * air_temp)
                # Calculate duration of the return pulse from the Ping)))
                duration=endtime-starttime      # seconds
                # Calculate the distance in centimeters
                # The duration is multiplied by the speed of sound in air
                # (as meters per second), then divided by two (because the
                # ping is there-and-back, so the pulse had to travel twice
                # the distance we're measuring), and then multiply by 100
                # to convert from meters to centimeters.
                distance=((duration * c_air_m_s )/2)*100
                # Add the distance to our array of reads
                # If we got this far, we had a good measurement
    # Okay, at this point we should have sixty "good" measurements.
    # Some may be outliers. This is where some real statistics math would
    # come in handy. For now, we'll simply take the median.
    twothirds=onethird * 2
    tank_air_space=(reduce(add, mid_distances)) / len(mid_distances)
    # Round it off, this thing has 1cm resolution anyway
    tank_air_space = tank_air_space - fudge_factor
    print "Adjusted air space in tank is ", tank_air_space, " cm"
    return tank_air_space
def get_fill_height():
    """ Returns the height of oil in the tank. """
    air_space = read_distance()
    oil_level = tank_height - air_space
    print "Oil level calculated as ", oil_level, " cm"
    return oil_level
def get_tank_volume():
    Returns the total volume of one vertical oval oil tank 
    Math in this section courtesy of:
    # The radius of the curved parts of the tank will be equal to
    # one-half the width of the tank. (Radius = diameter / 2; the diameter
    # of the curved part of the tank is necessarily the width of the widest
    # part of the tank.)
    # The height of the section of tank that isn't curved will be equal to
    # the height of the tank minus the height of the curved sections.
    # The curved section at the top and the bottom are each semicircles,
    # so each section's height is equal to the section's radius. We've got
    # two curved areas, so subtracting 2r from the overall height gets us
    # just the height of the straight section. Since the tank's width is
    # 2r, we just use that.
    # Now calculate the surface area of the side of the tank. It will be 
    # equal to the area of a circle with the tank's radius (e.g., pi*r^2)
    # plus the area of the square describing the middle part of the tank.
    # Now multiply that surface area times the length to get the volume
    # in cubic centimeters.
    return tank_volume
def get_oil_quantity():
    Returns the filled volume of one vertical oval oil tank in cubic
    Math in this section courtesy of:
    # The math varies depending on how much oil there is...
    if oil_level < tank_radius:         
       # Use circular segment method
       oil_volume=0.5 * tank_radius**2 * (theta - math.sin(theta)) * tank_length
    elif (oil_level > tank_radius) and (oil_level < (tank_radius + tank_square_height)):
        # Half of circular portion plus volume in rectangular portion
        vol_circle=math.pi * (tank_radius**2) * tank_length
        height_in_square = oil_level - tank_radius
        vol_cube=height_in_square * tank_width * tank_height
        oil_volume=(vol_circle/2) + vol_cube
        # Use circular segment method for empty portion, then apply
        # V(tank) - V(segment)
        oil_volume = vol_tank - air_volume
    return oil_volume
def cc_to_gallons(cubic_cm):
    Given a volume in cubic centimeters, return the equivalent in
    U.S. gallons
    return cubic_cm * 0.000264172052358
# Register handlers for abrupt termination, to make sure we clean up
# the GPIO pins
signal.signal(signal.SIGTERM, termhandler)
signal.signal(signal.SIGINT, termhandler)
# Get the amount of oil (in cubic centimeters)
oil_remaining_cc=oil_remaining_cc_1tank * num_tanks
# Get the volume of all tanks in the system
oil_capacity=oil_capacity_1tank * num_tanks
# Calculate percentage
orp=(oil_remaining_cc / oil_capacity) * 100
print "%.1f of %.1f gallons remaining ( %3d%% )" % (oil_remaining_gal, oil_capacity_gal, orp)
# Calculate remaining runtime
hours_left=oil_remaining_gal / oil_burn_rate
print "%d hours of runtime remaining at %.2f gal/hr" % (hours_left, oil_burn_rate)
days_left=hours_left / daily_runtime
print "%d days of operation at %.2f hours per day average" % (days_left, daily_runtime)

When executed, this program returns output like this:

Adjusted air space in tank is  69.0  cm
Oil level calculated as  42.5  cm
178.9 of 525.7 gallons remaining (  34% )
178 hours of runtime remaining at 1.00 gal/hr
35 days of operation at 5.00 hours per day average


In the future, I’ll write code that integrates this with my Nagios monitoring system, which will send me notifications when the oil gets low. I may also write code that keeps track of consumption to send me predictive warnings based on how quickly I’m burning oil.

]]> 0
Raspberry Pi-powered Oil Tank Monitor, Part 2: Interface Board Sun, 01 Feb 2015 03:45:49 +0000 Now that we’ve built the sensor for our Raspberry Pi-based oil tank monitor, it’s time to build the interface and integrate the Pi hardware.

Proof-of-concept interface circuit on solderless breadboard.



Circuit schematic.

Circuit schematic—click to enlarge.


  • J2–J4: Two-position screw terminal.
  • C1: 100nF ceramic capacitor (noise filter).
  • R1: 330-ohm 1/4-watt resistor
  • R2: 1.8k-ohm 1/4-watt resistor
  • R3: 3.3k-ohm 1/4-watt resistor
  • D1: 1N5226B 3.3-volt Zener diode
  • D2: 1N6263 Schottky diode











  • RED: Pin 4 “+5V”
  • BLACK: Pin 6 “Ground”
  • BLUE: Pin 1 “+3.3V”
  • YELLOW: Pin 3 “SDA”
  • GREEN: Pin 5 “SCL”
  • BLUE: Pin 7 “GPIO 4″


  • WHITE: Pin 8 “UART TXD”
  • GREEN: Pin 10 “UART RXD”
  • BLACK: Pin 14 “Ground”









Next: Basic software for reading the tank level.

]]> 0
Raspberry Pi-powered Oil Tank Monitor, Part 1: Sensor Unit Sun, 01 Feb 2015 02:26:57 +0000 My house is heated by an oil-fired hot-air furnace. The oil tanks are in the far corner of the basement. Occasionally, I’ll walk over and glance at the float gauge to see if it’s time to order more oil. Often, I forget to check for a while, and then it’s a panic…





My monitor features:

  • Controlled by a Raspberry Pi running Raspbian Linux

I intend to add software for automatic monitoring and alerting when the oil level is low. I may also integrate it with my Nest thermostat, so that the heating temperature is automatically lowered when the oil level is critical.

IMPORTANT: These plans are provided without warranty or certification. They have not been inspected or approved by any authority. By using these plans, you accept all risks associated with the device. No representation is made that this device is free from hazards or suitable for the purpose for which it is presented.

This sensor is designed for indoor use only. It is not weathertight, and technical limitations require the Raspberry Pi device to be mounted within four feet of the device.


The distance sensor

I chose to use the name-brand Ping))) sensor because it’s reasonably priced and accurate. There are nearly identical generic sensors available at about a tenth the price (the HC-SR04) that could be used instead, although they will require wiring and code changes. The HC-SR04 uses separate leads for initiating the distance measurement and getting the result; the Ping))) uses a single lead for both.

The Ping))) is theoretically accurate to 1 centimeter. However, that requires precise timing as well as temperature calibration. It is difficult to obtain that precision with a preemptive-multitasking OS like Linux, especially using a scripting language.

The temperature sensor

The TMP102 temperature sensor is pre-calibrated and uses the I2C bus to communicate with the Pi. It’s more expensive than standalone temperature sensors like the LM32, but it won’t require an analog-to-digital conversion circuit for use with the Pi.

It does introduce a major limit, however. The I2C bus has strict capacitance limits, and those limits can be exceeded by modest lengths of Category 5e cable. Therefore, the sensor unit must be mounted very close to the Raspberry Pi in order for the TMP102 (and any other I2C devices) to work. That makes my design unsuitable for outdoor tanks, unless you want to build a weathertight Pi enclosure.

Theoretically, you can build a buffered I2C-bus extension. I tried doing this using TI P82B96 chips; I couldn’t get it to work. But then, I’m a UNIX admin, not an electrical engineer.

Constructing the sensor head unit

This sensor is designed to fit a standard American 225-gallon heating-oil tank. It should work with any other tank having an available 2″ threaded port on the top.

From time to time, it may be necessary to remove the ultrasonic sensor for cleaning. For example, oil may splash on it when the tank is filled. To make it easier to do this, I designed the housing with a three-inch cleanout on the top. A two-inch cleanout wouldn’t leave enough room to get your hands inside and get the sensor out. As a result, the sensor unit is pretty large compared to the actual working bits inside.

WARNING: The sensors are not sealed from the oil tank. You must not install the sensor head in a location where oil may enter the sensor head. If you have multiple interconnected oil tanks, you should usually install the sensor head on the tank farthest from the filler pipe. Do not allow your oil company to overfill your tanks or damage to the sensor may result.

Bill of Materials

Plumbing (from your local home center)

PVC and acrylic plastic have very good resistance to diesel oil. Home heating oil is essentially identical to diesel oil, so these are good choices for constructing our sensor.


You will also need soldering equipment and supplies.


  • Drill (cordless recommended)
  • 11/16″ drill bit, Forstner preferred, but spade will do
  • 1/4″ twist drill bit
  • 1/8″ twist drill bit
  • Scrap wood block for drilling
  • Hacksaw with fine teeth
  • Coarse to medium sandpaper
  • Squeeze clamps
  • Small needlenose pliers
  • Linesman’s/Electrician’s pliers
  • Sharp utility knife
  • Countersink bit

1. Fabricating the sensor mount

In some ways, the hardest part of this build is making the plate that the Ping))) sensor will mount to. I chose to use a leftover piece of 1/8″ thick clear acrylic (sometimes called Plexiglas, but any brand will do). Acrylic likes to crack when you work with it, so work slowly, carefully, and with plenty of support.

The completed sensor bracket with Ping))) sensor installed.

The completed sensor bracket with Ping))) sensor installed.

Do not remove the protective label covering the acrylic until you have completed cutting and drilling the bracket.

  1. Download the Ping))) Datasheet. Print out page 1, making sure you print at 100% scale. (Most PDF viewers default to “scale to fit,” and thus may print out the datasheet at the wrong scale.) Use a ruler to verify that the diagram at the bottom of the page printed at the dimensions shown. If not, adjust the print enlargement scale and print it again until you have an actual-scale printout.
  2. Place the 2″ PVC pipe against the acrylic sheet. Using a Sharpie, trace tightly around the pipe, creating a circle on the sheet’s backing.
  3. Working carefully, cut along the inside of the traced line. You want your circle to be ever so slightly smaller in diameter than the pipe’s outside dimensions, so that it will fit snugly in the threaded adapter.
  4. Test-fit the circle in the threaded adapter. Use the hacksaw or sandpaper to adjust any high points until it fits snugly. You should be able to press it into place with finger pressure, but it should not fall out.
  5. When you have cut out the circle, place it on top of the datasheet printout. Use the left-hand picture of the Ping))) as a guide, centering the module’s sensors on the acrylic circle. Make sure that there will be enough clearance between the corners of the Ping))) and the edge of the circle to accommodate the thickness of the 2″ Schedule 40 DWV pipe that will be inserted over it! Mark the centers of the sensors and the mounting holes on the acrylic with the Sharpie.
  6. Clamp the circle securely to a block of scrap wood. With an 11/16″ drill bit, carefully drill out the holes for the sensors. If using a cordless drill with multiple gears, select the slowest gear. Use a speed that is fast enough to avoid catching the drill, but not so fast that you risk melting the plastic.
  7. Use a 1/8″ drill bit to drill the mounting holes. Work with extreme care; the mounting holes are close to the sensor holes, and the acrylic will want to split.
  8. Attach the two nylon spacers to the acrylic circle using the two M6 screws. The threaded portion of the nylon spacers should point away from the acrylic. The Ping))) will rest over the nylon threads when the unit is assembled.
    Note: Some of the pictures show an earlier prototype assembly where the spacers are attached with nuts; this is impractical as it prevents easy disassembly of the sensor head for cleaning.

2. Wiring the Ping))) sensor

The Ping))) has three header pins. It’s not practical to fit a standard female header connector onto these pins inside a 2″ pipe. I chose to solder wires directly to the header pins. Alternatively, you could desolder the right-angle header pins and replace them with straight-up header pins, and then use an appropriate header connector.

My prototype, pictured, used four-conductor hookup wire (with one conductor stripped off) for this connection. That proved to be an error when I abandoned the I2C extender. That’s why these instructions don’t quite match the photos.

  1. Cut a 4.5-foot length of Category 3 or better twisted-pair cable.
  2. Remove about six inches of the outer jacket from one end of the cable. Separate the wire pairs, but do not untwist them!
  3. Using a spare piece of twisted-pair cable—not the five-foot length you just cut—obtain about six inches of white-with-blue-stripe wire.
  4. Solder wires as follows, stripping about one inch of insulation and wrapping the wire tightly around the header with fine needlenose pliers before applying solder:
    SIG: Orange with white stripes
    5V: White with orange stripes
    Spare length of white with blue stripes

3. Wiring and attaching the TMP102 sensor

The TMP102 sensor installed in the PVC pipe. In this prototype, hookup wire was used instead of twisted-pair cable.


  1. Cut a 1.5″ length of the 2″ Schedule 40 DWV pipe. (This should be just long enough to mate the male threaded adapter to the 3″x2″ reducer.)
  2. Place the TMP102 breakout board against the inner edge of the cut pipe. Using a Sharpie, mark the location of the mounting holes.
  3. Using an appropriate small drill bit , drill holes for mounting screws in the PVC pipe. You’ll need small wood screws that will attach the TMP102 securely without protruding from the pipe, and without shorting any circuit traces on the TMP102.
  4. Untwisting the wires the least amount necessary to do so, solder wires from the twisted-pair cable to the TMP102 as follows:
    SCL: Blue with white stripes
    SDA: Green with white stripes
    GND: Spare length of white with blue stripes
    3V3: White with green stripes
  5. Wrap the unused brown pair of wires along the outer sheath of the cable.
  6. Using the IDC, connect the three white-with-blue-stripes wires.
    Hint: Use a hemostat to keep the three wires from slipping relative to each other while you use your linesman’s pliers to crimp the IDC.
  7. Slide the PVC pipe over the twisted-pair cable, with the screw holes toward the Ping))) sensor.
  8. Attach the TMP102 to the PVC pipe with the wood screws.

4. Gluing the PVC

WARNING! PVC primer and cement fumes are toxic! Work in a well-ventilated area and/or use an appropriate respirator. Wear nitrile gloves.

WARNING! PVC primer and cement may permanently damage sensors and wires! Use extreme care when applying and handling these chemicals to avoid damage. The primer is especially prone to dripping where you don’t want it.

NOTE: The pictures show a prototype version of the sensor that used hookup wire instead of twisted-pair wire. Your wiring will look different.

The plastic components are assembled in this order. This prototype used hookup wire instead of twisted-pair cable.


  1. Insert the acrylic circle into the threaded male adapter. Ensure that it is firmly seated.
  2. Push the Ping))) sensor onto the nylon spacers. Ensure it is firmly seated. The M3 connectors are somewhat large for the Ping)))’s mounting holes, so this should work fine.
  3. Carefully test-fit the PVC pipe into the male adapter, being careful not to shove the TMP102 against the Ping))). You’ll want to wind up with the TMP102 along the long side of the Ping))) that doesn’t have the header pins. Mark both PVC pieces with the Sharpie to indicate the correct orientation before taking them apart again.
  4. While being very careful to avoid dripping on the wire or electronics, very carefully apply a small amount of PVC primer to the inside of the male adapter and the matching outside end of the PVC pipe (the end with the TMP102) following the manufacturer’s directions. When the primer is ready, apply a thin layer of PVC cement to the primed surfaces, being careful not to apply so much that it will squeeze out onto the electronics. Then immediately push the pieces together, very slightly out of alignment, and give them a slight turn into their final orientation. (This will help create a gas-tight seal.)
  5. Thread the 3″x2″ reducer over the twisted-pair cable. Use primer and cement to glue it to the 2″ pipe using the same care and technique.
  6. Thread the cleanout adapter (female thread) over the twisted-pair cable. Use primer and cement to glue it to the reducer, using the same care and technique.
  7. Wait at least ten minutes for the PVC cement to set.
  8. Being careful not to drill into the wire, clamp the assembled sensor unit to your workbench and drill a hole into the side of the 3″ x 2″ reducer to accommodate the twisted-pair cable. For most cable, a 1/4″ twist bit should fit nicely. You want a hole that’s snug, to minimize any oil fume leakage.
  9. Using a sharp utility knife and/or a countersink bit, round off the outside edge of the wire hole to prevent sharp edges from cutting the cable.
  10. Hold the countersink bit in your fingers. Place it on the inside of the wire hole and twist it to deburr the hole and file off any sharp edges that could damage the cable.

    Deburring the inside of the wire hole using a countersink bit.

    Deburring the inside of the wire hole using a countersink bit.

  11. Wrap electrical tape around the cable on the inside of the sensor to prevent it from pulling through the hole. This will act as a strain relief.

    Electrical tape wrapped around the end of the cable's outer jacket will prevent it from being pulled through the hole, acting as a strain relief.

    Electrical tape wrapped around the end of the cable’s outer jacket will prevent it from being pulled through the hole, acting as a strain relief.

  12. Thread the twisted-pair cable through the wire hole. Leave enough slack inside the sensor casing to avoid strain and allow for maintenance.
  13. Install the 3″ threaded plug snugly.

This completes construction of the sensor head unit. Set it aside until you’ve built the interface board and tested it. The interface board will be covered in the next post.

The completed sensor head  assembly. As mentioned, the purple PVC primer is very runny and gets everywhere, even when you're being careful.

The completed sensor head assembly. As mentioned, the purple PVC primer is very runny and gets everywhere, even when you’re being careful.


The business end of the completed sensor head unit. Note that the author failed to carefully note the position of the TMP102 module compared to the Ping))) while gluing the unit together. Thankfully, there’s just enough clearance between the Ping))) headers and the TMP102 board. This may not have been true if using the cheaper HC-SR04 sensors, which have four header pins instead of three.

Continue to Part 2: the interface board.

]]> 0
Setting up S/MIME mail encryption on Mac OS and iOS Tue, 18 Nov 2014 23:21:32 +0000 Encryption software can do two things for your email: It can sign your messages, to prove that it was you who sent it and that the message wasn’t altered in transit; and it can encrypt your messages, so no one but the recipient can read the contents.





Getting an S/MIME certificate


There are several CAs that will give you a “Class 1″ SSL certificate for your email address. That’s the minimum you need.  You can get “better” certificates that provide a stronger proof of your identity. If you don’t already know you need a better SSL certificate (and how to get one), you’re almost certainly fine with a Class 1 certificate.


To get a StartCom SSL certificate:

  3. Click “Sign-up”.

Getting more SSL certificates


Installing your S/MIME certificate in Apple Mail


Using S/MIME in OS X Mail





Installing your S/MIME certificates on iOS


Part One: Export the certificate from your Mac


Part Two: Import the certificate on your iOS device

  10. Tap the “Account” line.

Using S/MIME in iOS Mail



  4. To install the certificate, tap “Install”.
  5. Tap “Done.”


]]> 0
Critique of Granby, CT’s proposed excavation regulations Wed, 29 Oct 2014 21:02:18 +0000 At last night’s Public Hearing on the Granby Planning and Zoning Commission’s proposed revisions to the town Zoning Regulations, I submitted a written critique of the proposal.

You can find the existing regulations and the proposed amendment on the Town’s web site—although the amendment text isn’t exactly the same as that before the Commission last night. The copy they had includes paragraph numbers.

Granby Community Television posted video of the hearing on YouTube, including the comments I made.

The written comments I submitted are now part of the public record, and should be available for inspection at the Office of Community Development. In my experience, it’s not always easy to get to those public records, especially electronically. Therefore, I’m posting a copy of my comments here.

In PDF format, you can read the  cover letter enumerating my objections,  some revisions I proposed to address the objections, with annotations, and a page of annotations that were too long for the margins that Word decided to spit out as a separate document entirely.

Unfortunately, the Commission closed the public hearing last night after receiving comments from me and my mother, so they aren’t likely to accept additional comment at this time. However, if they make substantial revisions to the proposal—as I hope they do—they would likely need to open a new public hearing.

]]> 0
Site slow today Thu, 15 May 2014 14:39:44 +0000 Today’s a really bad day for WordPress spammers. My site is under a flood of bogus comments being sent in hopes that one will slip through and carry an advertising link someone will be dumb enough to click. As a result, it may take a while for pages to load.

]]> 0
Peck Orchard Knoll runoff pollutes Fox Brook Tue, 13 May 2014 22:06:58 +0000 On Saturday, May 10, 2014, a few heavy downpours made their way through North Granby. The result was a stream of sediment pouring down Peck Orchard Road from the Peck Orchard Knoll sand mining stockpile building site.IMG_0317Not only did this wash across the road higher up, but water poured down to the foot of the road. When the drainage culvert further uphill got clogged with sand, it reached the lower culvert…


…which empties directly into Fox Brook.


The brook, which was running clear above the culvert, turned brown from the runoff coming through the culvert.


This picture is only a few hundred feet upstream from where Fox Brook discharges into Salmon Brook.

How did this happen? The evidence was there on Sunday. It all starts with the gigantic funnel created by the huge mounds of sand that have been bulldozed up and left exposed. These mountains were created weeks ago, and have stood untouched since then. Notice the pile on the right, which extends far above the original topography of the site. There’s another on the left, hidden behind a hill.

DSCN2665That part in the middle? That’s a “road” dug into the sand. Rain from these hills sheds down into this new artificial valley. Despite R. R. Hiltbrand’s presentation at the special permit hearing, wherein their engineer claimed that this sandy soil was incredibly quick-draining and it could absorb the runoff from a hundred-year storm, this summer thundershower obviously created damaging runoff.


Looking closer at that hillside, you can see the deep gullies created from erosion. It’s obvious that a lot of water ran down that hill, and that it wasn’t being absorbed by the sand.


When it hit the bottom of the sand ramp, it left a huge pile of silt on top of the traprock apron that Simscroft-Echo Farms installed.


That runoff was then funneled off to the side of the driveway… mostly. POK had a small pit in the sand here to catch sediment; it filled up in the previous storm. This time, it didn’t help.


The runoff went out and around the silt fence and hay bales that were supposed to contain it. It washed onto the “bituminous” driveway apron: chunks of loose asphalt material packed into a firm, but not solid surface. Why didn’t the silt fence work?


It was full. The design of this “erosion control measure” was laughably inadequate to cope with a spring thundershower; one can imagine how it would perform in a serious summer thunderstorm. It will take a lot more hay to stop a pile of naked sand this size from washing away.


Besides,a few wooden stakes pounded not very far into the ground are no match for hydraulic pressure. Once the stakes flop over, the fence does nothing to control runoff. However, it does present a serious hazard to traffic.


Past that silt fence, there’s evidence of a large, erosive water flow. Possibly it was enhanced by runoff from the hillside that has been stripped of trees but not yet stripped of topsoil.


The result was a veritable river delta stretching across Peck Orchard Road. On Saturday, this part of the road was a brown mass of silty runoff. On Sunday, it was a potentially deadly hazard to bicycle and motorcycle traffic.


Remember that bituminous driveway material? Here’s a whole bunch of it, several hundred feet down Peck Orchard Road. It may be more permeable than pavement, but it’s not permeable enough to stop this much water… and it doesn’t stay put.

Then we come to the first storm drain on the side of Peck Orchard Road.


If you’re looking for it, it’s right near the construction sign. (The one that isn’t reflective, and therefore can’t be seen well at night—which is why Connecticut DOT requires reflective signs for state contracts.)


You still can’t see it? That’s because it’s buried.


A few leaves and a whole lot of mud make for a clogged storm drain…


…but not before the whole pipe fills with sediment, and the outlet swale loses a few inches of depth.


Cleaning out that drainage pipe and runout is going to be a time-consuming, expensive job for Granby Public Works. I wonder if Granby taxpayers will be footing the bill?

Having filled up the first storm drain, the water kept flowing downhill, carrying silt with it.



Very little of this is from winter salt-and-sand spreading. Most of this is fresh silt.



Both sides of the road had torrents of water running down it. Here’s the erosion on the other side of the road. Fox Brook is about 25 feet to the right from this next shot.



By the time the water reached the second storm drain, it was still carrying substantial silt. It made a good start on clogging this drain, too.



You can still see the new layer of sediment in Fox Brook at the other end of that culvert.



But at least it’s not like there’s any environmental threat from this sand, is there?


I think that filling Salmon Brook’s tributaries with sand might have an effect on any juvenile salmon that might be present.

Since these photos were taken, Peck Orchard Knoll has dug out some, but not all, of the silt from behind their silt fence, and they’ve pounded those wooden stakes back into the ground. The road has been swept, but it still raises clouds of fine sand dust when people drive past. (The past few days haven’t been kind to the paint on cars traveling Peck Orchard Road!) Even so, if we get another fast-moving downpour like last Sunday, this will happen again. The same erosion controls are in place, and they are demonstrably inadequate.

And Granby still hasn’t gotten around to making it illegal to do this again.






]]> 0
Peck Orchard Knoll Sediment Heading for Fox Brook Mon, 10 Mar 2014 17:57:43 +0000 When Michael Girard presented his Peck Orchard Knoll excavation proposal to the Planning and Zoning Commission of Granby, CT, he and his engineer claimed that there was no realistic chance of environmental damage. The proposal called for removing about 100,000 cubic yards of sand and gravel from the site, a hilly residential lot.

The proposal was withdrawn after the Commission showed reluctance to give Peck Orchard Knoll carte blanche to excavate… and because it turns out that they didn’t need a special permit to create what is, in essence, a strip-mining operation on a residential lot in Granby. A simple building permit, issued after pro forma inspection, suffices under Granby’s regulations. However, the plans submitted with the building permit application were substantially the same as the special-excavation plans.

A warm weekend, causing almost two feet of snowpack to start melting, shows evidence that Peck Orchard Knoll’s claims that runoff wouldn’t be a problem were… inaccurate.

While the plans call for Phase One to be a driveway with various sediment controls, the actual first phase of the project is using an old wood road that was cut illegally close to the adjoining property line, according to the town’s previous building inspector. The wood road has been “improved” with crushed stone, but without any inherent runoff controls.

Gravel access road into Peck Orchard Knoll showing muddy runoff leaving the property and heading down Peck Orchard Road

The “wood road” access road into Peck Orchard Knoll, Sunday, March 9, 2014.

The result, as seen here, is a river of muddy water, laden with sediment, running down Peck Orchard Road.

Peck Orchard Knoll access road, showing muddy, sediment-laden water entering the road and running downhill

View of Peck Orchard Knoll access road facing uphill.

Runoff does run down Peck Orchard Road for quite a ways, and a fair amount of water comes down the hill from above Peck Orchard Knoll. However, much of it leaves the road in the swale just uphill from the access road. On this day, the runoff that did come from uphill was practically clear. All of the brown, muddy sediment in these photos is coming from Peck Orchard Knoll. There is a fair amount of sand on the side of the road; Granville plows Peck Orchard Road, and they use a sand/salt mix. However, the sand mix is clean, and doesn’t create mud, especially not this long after the last snowstorm. In the next picture, you can clearly see how clean the “upstream” water (on the right) is, and how muddy the runoff from Peck Orchard Knoll (left) is.

Close-up showing contrast between practically clear water from uphill and deep brown muddy water from Peck Orchard Knoll's access road

Clear runoff in the center/right is from uphill on Peck Orchard Road. Mud at the left is entirely from Peck Orchard Knoll’s access road. Water is flowing downhill, toward the top of the photo.

What about the sediment control? Well, to be fair, Peck Orchard Knoll did install some sediment controls for this wood road. There are hay bales:

Crushed-stone driveway with muddy runoff; along the left edge of the driveway, there is a stack of hay bales neatly piled on top of the snow, completely out of the potential path of any runoff.

POK’s access road. Note sediment-control hay bales (stacked, on left).

And there’s also landscaping cloth:

A used, haphazardly-bundled section of black landscaping cloth, with wooden stakes entwined within, sitting on the snow beyond another landscape-cloth silt fence bordering the POK access road

This bundle of landscaping cloth was, at one time, placed across POK’s access road when they weren’t working. On Sunday, it was carelessly discarded, near (or possibly over) the property line.

Obviously, the Simscroft-Echo Farms employees who are excavating the site didn’t think that it was critical to reinstall the erosion-control system before leaving the site the last time they were working. They aren’t working every day; they’re removing sand when they have a buyer for it. They certainly weren’t working this past weekend, when temperatures were as high as the mid-fifties.

The effect of this negligence is a new river delta in front of Linda Varcoe’s home on Peck Orchard Road:

Sediment lining Peck Orchard, with a broad swath of muddy runoff  crossing the width of the road

The sediment on the left is mostly dirt, mud, and stone dust from the wood road. Some of it is road sand, but notice the muddy texture: road sand doesn’t look like that.

The entire width of Peck Orchard is coated with runoff here. At night, when the temperatures drop below freezing, this will be black ice.

You can also see here that the road is starting to break down from the runoff, perhaps enhanced by the additional heavy truck traffic. Unlike Hartland, Granby does not routinely seal cracks on Peck Orchard Road. However, historically the road has been lightly used and has held up pretty well. This year, it’s a different story.

Muddy runoff pouring into a  two-inch-wide, long crack in the middle of Peck Orchard Road's uphill travel lane; asphalt debris is visible nearby. Muddy runoff fills half the travel lane.

It’s small now, but let’s see how it looks in a week after some freeze/thaw cycles.

This isn’t just a little extra runoff; it’s substantial sediment running the length of Peck Orchard Road.

Quick-flowing runoff traveling through thick muddy sediment covering one-third of Peck Orchard Road's uphill travel lane.

Some of the runoff continues all the way down the road. However, much of it enters a culvert near this road sign.

Fast-moving muddy runoff courses down Peck Orchard Road. Much of it flows into a culvert at the side of the road, hidden under snow. However, a stream of it continues down the road into the distance.

No small amount of sediment is entering this culvert, hundreds of feet downhill from Peck Orchard Knoll’s driveway.

A drainage grate is partially seen underneath a crust of ice and snow at the edge of the road. A thick layer of sediment—some of it road sand, some of it mud—creates eddies in a stream of very muddy water flowing into the grate. A discarded Nantucket Nectars bottle lies in the gutter.

Peck Orchard Road also has a litter problem. Unusually, this drink container isn’t for an alcoholic beverage.

This grate enters a culvert under Peck Orchard Road. It drains on the other side.

Covered with deep snow, a gulley in the downhill side of Peck Orchard Road leads toward Fox Brook, about 100 feet downhill of the culvert opening and currently covered with ice and snow. As such, the brook itself isn't immediately visible.

The culvert’s drainage channel comes out just uphill of Fox Brook, currently frozen over and covered with snow.

Click the photo to see a larger version. Because of the cold winter, Fox Brook is a bit hard to see; it’s in the floor of the valley seen in the background, currently covered with ice and snow. While you can’t see the runoff from this culvert in this picture, it is there, underneath the snow.

That river of mud is heading straight for Fox Brook.

And Fox Brook, a few hundred feet later, empties into Salmon Brook.

These are the wetlands that Peck Orchard Knoll said would be unaffected by their work. During the public meetings, there were those who scoffed at the suggestion that silt and sediment would enter the Fox Brook watershed.

Yet here we are, barely into snowmelt season, and it’s already happening.

We’ve still got a foot of snow to melt.

We haven’t gotten any spring rains yet.

And there’s the potential for so much more runoff, because—let’s not forget—this is a strip mine:

The Peck Orchard Knoll mining site, showing two- to three-foot deep raw cuts into topsoil, as well as exposed hillsides of fine light-grey sand, all unprotected from the elements and with no visible erosion-control measures. A large backhoe is parked on the hillside, where it was excavating sand. A large expanse of freshly-clearcut land extends uphill from these cuts, covered in snowfall.

This unprotected, raw topsoil is already washing down Peck Orchard Road just from snowmelt. What happens if we get a thunderstorm?

There’s nothing left to protect the land here. The topsoil has been scraped aside and piled uphill. There are raw cuts exposing feet of topsoil. A pit of sand is exposed to the elements. Notably absent from the work zone is any form of erosion control whatsoever. That pile of topsoil is wholly unprotected. The banks are unprotected, even as a thick pack of snow is exposed to direct sunlight thanks to the clear-cutting of the property. There’s nothing in place to keep it from washing down the road and into the creek.

Well, except those hay bales and that length of sediment fence.

You know, piled up where it won’t get dirty.

But even if it were in place, is it reasonable to think that such a rudimentary structure would suffice?

Would it hold up to an April thunderstorm?

Just a few months into this excavation—which Girard said could take years to complete—and already, these promises of environmental responsibility appear to have fallen by the wayside. I’m scared to imagine what damage will be wrought to the neighborhood by the fall.

In the meantime, the Town of Granby can’t even scrape up enough people to make a quorum to meet and discuss possible drafts of potential changes that might get enacted to change Granby’s zoning regulations to stop this sort of thing. From my point of view, it simply doesn’t seem to be a priority for Granby’s land-use-governance officials.


NOTE: All comments on this site are moderated, and will not appear until approved. This may take hours or days. This is because there are many, many spammers who think that posting blatant advertisements as blog comments is a good idea. Most legitimate comments will be approved and posted. However, I reserve the right to decline posting any comment, especially those that are defamatory or incendiary in nature.

]]> 0 An open letter to Verizon about VoiceLink Fri, 05 Jul 2013 17:04:26 +0000 Lowell C. McAdam
Chairman and Chief Executive Officer
Verizon Communications
140 West Street
New York, NY 10007

Dear Mr. McAdam,

I can’t understand your strategy behind pushing Voice Link as a replacement for landline wireless. It seems to be a major misstep, of the kind that should lead prudent investors to short Verizon.

I understand that your revenue from traditional landline services has declined. As you sell it today, copper landline service is mostly noncompetitive with the alternatives, and that has hurt its market share in your service area. But that’s not the whole story.

Yes, copper landlines come with many regulatory restrictions, require considerable maintenance, and do not support competitive broadband data speeds. From a consumer point of view, they only work in the home and they’re expensive.

But, from Verizon’s point of view, I think you’re missing something important: Copper landline technology has a substantial benefit that differentiates it from all of your competitors, a benefit Verizon has failed to market properly.

It’s reliable.

Or, at least, it used to be reliable; in your service areas, your failure to maintain copper plant and infrastructure has weakened that reputation considerably… but it can still be regained.

With a copper landline, properly implemented and maintained, service remains up until the line is severed, and that generally takes considerable damage. If commercial power is out, landlines generally remain up. If you need to call 911, it’s going to work best from a landline, which will have the capacity and power to complete the call, and will reliably connect you to the correct PSAP on the first try, with accurate location data even if you can’t speak. If you need a medical alert device, a landline is the most likely to work when you need it. It won’t turn out not to have a generator, or be overloaded by many calls, or fail due to radio interference. It doesn’t depend on having commercial power to the home to charge batteries or power base stations.

In short, the key differentiator of the venerable copper landline is that it’s suitable for life-critical communications.

Consider: Once you transition a customer to Voice Link, they are now on your wireless service. That’s a commodity product, and it lacks that key differentiator. For a consumer, Voice Link is not substantially different from AT&T’s fixed-wireless service available at Target, or similar offerings from Sprint, T-Mobile, or their MVNOs. It’s also not substantially different in terms of reliability or price from numerous VoIP providers.

By moving people to Voice Link, you’re inviting them to drop Verizon entirely and move to competitors that offer the same service with better features or a better price… because you can’t use your key advantage, the unmatched reliability of a regulated copper landline.

Investors should shy away from companies that willingly surrender a key market differentiator in the name of short-term profit.

Already, Verizon has surrendered the Internet market to its cable competitors by abandoning FiOS. Verizon’s DSL offerings are pathetic compared to cable’s low-cost, high-speed Internet; fixed wireless LTE is so expensive that it’s solely a last-choice alternative.

I am currently a Verizon landline customer. I pay for the service because I value the reliability, even though Verizon’s landline service costs more than a VoIP line even without services now seen as basic, free features on every competing technology: caller ID, call waiting, voicemail, unlimited long distance… If Verizon were to stop providing this landline service, I would not purchase Voice Link. I would move to one of your competitors, where I would get a better value for less money.

My advice to you: Abandon Voice Link as a replacement for copper landlines. Market it as a low-cost alternative for those who need seasonal service, or service where installation of the last mile would be prohibitively expensive to the customer… or as an additional-line alternative to VoIP. Reinvest in your copper landlines to restore their reliability. Market that reliability heavily. Bring the feature set of a basic $35 landline in line with that of a $20/month prepaid cellphone: caller ID, call waiting, and basic voicemail at no additional charge. You can then use affinity programs to sell landline consumers on your wireless offerings by providing a discount.

The alternative—eliminating your inherent competitive advantage, the last advantage of the old Bell monopoly you’ve been allowed to retain—makes no business or social sense.



Robert A. Levandowski

]]> 0