Bespoke Dial: Old-Timey Automation

Software development affords a great deal of freedom that you won’t find in the physical sciences and engineering. Tolerances, non-ideal particles, and even the laws of physics fall away as you construct ever larger digital systems. As Hal Abelson noted in his seminal 6.001 lecture, “in building a large program there’s not that much difference between what [you] can build and what [you] can imagine.”

It is always refreshing, therefore, to escape the cerebral world of code and return to the reassuringly palpable realm of the physical. Hardware and electronics, although bound by the laws of Newton and Maxwell, are instantly accessible solely because they can be touched and held by the user.

It was with this in mind that I entered Hard Hack, a weekend of learning, hacking, and collaboration in honor of all things hardware. My goal was to use one of the most solid and nostalgic objects in my possession, the rotary telephone, to breathe new life into a forgotten relic.

image

What emerged was Bespoke Dial, an Old-Timey Speed Dial with a nod to the future. At its most basic Bespoke Dial allows you to enter a number on the much-more-satisfying rotary phone and immediately connects your party via Google Voice. On a deeper level you can use Bespoke Dial to automate most any process at the touch of a rotating button – unlocking a secret room, controlling the lights in your home, or surreptitiously ordering a pizza.

Bespoke Dial reads keystrokes from the rotary phone using a circuit that transitions from closed to open a number of times equal to the digit dialed. For example, dialing a “7” causes the circuit (usually closed) to become open 7 times in rapid succession. The following Arduino code interprets the rapidly opening and closing circuit and converts the result to a number that is written out to the serial port. (props to @guidomax on Instructables for the original code).

image

int dialHasFinishedRotatingAfterMs = 100;

int debounceDelay = 10;

void loop() {

    int reading = digitalRead(in);

    if ((millis() - lastStateChangeTime) > dialHasFinishedRotatingAfterMs) {

        if (needToPrint) {

            Serial.println(count % 10);

            needToPrint = 0;

            count = 0;

            cleared = 0;

        }

    }



    if (reading != lastState) {

        lastStateChangeTime = millis();

    }

    if ((millis() - lastStateChangeTime) > debounceDelay) {

        if (reading != trueState) {

            trueState = reading;

            if (trueState == HIGH) {

                count++;

                needToPrint = 1;

            }

        }

    }

    lastState = reading;

}

Now that we have the number being printed to the serial port we can listen for all 10 digits in Python and trigger a call via Google Voice.

def listen():

    ser = serial.Serial(SERIAL_INTERFACE, 9600)

    previous_numbers = []

    while True:

        number = ser.readline().strip()

        previous_numbers.append(number)

        if len(previous_numbers) == 10:

            call(''.join(previous_numbers))

            previous_numbers = []

For the full source code check the Bespoke Dial github page.

For fun I attached an MP3 Player Shield to the Arduino so you can hear the rockin’ sounds of Bill Haley calling out the numbers as you dial.