Rotary phone running Linux
How to connect a vintage rotary phone to raspberry pi (and use it as a wedding guestbook)
I’m a software engineer, and am not very familiar with the inner workings of most electronics. I had an idea for using an old rotary phone as a Linux peripheral device. In this blog post, I’ll show you what I learned, and how to connect an old rotary phone to a Raspberry Pi.
Requirements
To do this project, you won’t need any electronics knowledge. It is basically as simple as unscrewing a few connections, plugging together wires, and taping them down. I assume you have some knowledge of running Linux programs on the Raspberry Pi, and in particular a bit of Python experience.
The materials needed for this project are also simple.
- First, you will need a Raspberry Pi. You could use a Raspberry Pi zero for this, but my understanding is that connecting to GPIO on the zero is trickier. On a normal-sized pi, you can instead use jumper cables. You will also need an SD card and power supply.
- You will need some wires to connect the componants to your pi. I got some jumper cables (these and these). You could use any wires really. I used the ones mentioned above, and taped them as needed to form a connection. If you are comfortable soldering, that is fine too.
- To use audio, you will need a USB audio adapter. I have an older pi, which has a 3.5 mm output jack on the board. If you didn’t need audio in, you could get away with just using that. Any USB audio adapter that works on the pi should be fine.
- Now, you will need something to plug into the 3.5 mm jacks on the adapter. I used these, which makes it very easy to connect the phone wires to a 3.5 mm jack. Alternatively, you could just use an old 3.5 mm cable, and splice it onto the phone’s wires.
- You will need a rotary phone. I got mine from an antique store, and I think it is from the 70s or 80s. Make sure the phone you choose is a rotary phone if you want to use the dial. There are some phones that appear to have dials, but the dial does not spin, and the numbers are actually buttons instead. You probably could get these to work if you tinkered around yourself, but I have no experience with them. JWZ wrote this post about using a more modern payphone. If you search ebay for “rotary phone” you will find lots that fit the bill.
- You will need some screwdrivers to take apart the phone. My phone just uses regular screws.
In total, the pi and phone are by far the most expensive part of this project. Most phones I’ve seen have been around $40, or more for fancy colors. So overall, you could probably complete this project on a budget of $45-$100 depending on your selection of phone, and if you have an old Raspberry Pi lying around.
An old-fashioned rotary phone is a very simple device. The hook (the button to know if the phone is picked up) is just a basic button. The rotary dial may seem complicated, but ultimately, it is just a pair of basic buttons. The speaker and microphone are just analog audio componants. I’ll first describe how each of these individual parts can be connected to the Raspberry Pi.
Since I’ve already done this process on my phone, I don’t have photos in progress, but hopefully it should be self explanitory to take things apart. Your phone may look different on the inside anyway, but the concepts will likely be similar.
The first thing to do is to take your phone apart. No actions here need to be desctructive, or at least weren’t for me. Everything was just unscrewing connections. I removed as many wires as possible. The ones that are required for use will be connected to the componants we are interested in a way that can’t be removed. I also took out the bell, since this was very large. It functions via electromagnet, and I haven’t figured out the best way to run it via the Pi.
Connecting audio
The phone handset is connected to the base by 4 wires. These form two pairs, one for the microphone, and one for the speaker. They operate like a normal analog audio cable.
I was able to differentiate the pairs by unscrewing the plastic on the headset, after doing so I could see the color wires that connected to the speaker, which here are white and green. The remaining wires went to the microphone.
I used the 3.5 mm clips, and taped them to these wires. Then I plugged in the 3.5 mm cables into the USB audio adapter. I plugged this into my laptop, and tested both the microphone and speaker worked by recording with audacity, and playing a YouTube video.
My microphone is very clippy, which is to be expected of something so old. Perhaps your phone will be better. I accidently bought the wrong adapter here, and needed to add an auxillery cable, so my cables look very messy.
Connecting the “hook”
Next, I wanted to connect the “hook” switch. Basically, this is a button that is pressed when the phone is set down on the phone, and released when it is picked up. Under the switch on the phone, there were a series of plates and wires. To simplify things, I removed all of these wires but two. This actually complicated things, since it was tricky getting the plates to compress correctly with the wires missing. I added cardboard to pad the space.
I took the two wires, and taped them to jumper cables. Next, I connected them to the GPIO pins, one to ground, and one to a general purpose pin. I booted my pi, and ran the following python program to test it worked.
import RPi.GPIO as GPIO
import time
BUTTON_GPIO = 24 # Change to the pin you are using
GPIO.setmode(GPIO.BCM)
GPIO.setup(BUTTON_GPIO, GPIO.IN, pull_up_down=GPIO.PUD_UP)
while True:
if not GPIO.input(BUTTON_GPIO):
print("phone is on hook")
else:
print("phone is picked up")
time.sleep(1)
While running it, you can pick up and set down the phone handset to see if the wires are connected correctly.
Connecting the dial
The dial is the most complex part of the phone, but it basically is just two buttons.
The first here on the left is formed by the green and blue wires. For each number the dial rotates past, the circuit is closed. For example, if you dial a 4, the plates connected to these wires touch 4 times, and so the Pi sees this as 4 button presses.
The second button formed by the two white wires is closed while the dial is in motion. To simplify my wiring, I ignored this button, and instead just timed the first button, by counting how many times the button is pressed before 0.3 seconds without any change (to signify the dial reached the end).
I used tape and jumper cables to connect the green and blue wires to the GPIO on
my Pi. Then I used this program to test the dial is working. It should print
out the number dialed. The REST_TIME
parameter may need tweaking if your dial
moves very slowly.
from datetime import datetime, timedelta
import RPi.GPIO as GPIO
import time
BUTTON_GPIO = 25 # Change to the pin you are using
GPIO.setmode(GPIO.BCM)
GPIO.setup(BUTTON_GPIO, GPIO.IN, pull_up_down=GPIO.PUD_UP)
REST_TIME = 0.3 # seconds
rest_start = datetime.now()
count = 0
printed = True
pressed = True
while True:
# If there is a new press of the button
if not GPIO.input(BUTTON_GPIO):
if not pressed:
# Count how many times the button is pressed
count+=1
pressed = True
printed = False
else:
# End the current button press
if pressed:
rest_start = datetime.now()
pressed = False
# If it has been REST_TIME seconds since the button was pressed, and we
# haven't printed the result, print it
if datetime.now() - rest_start > timedelta(seconds=REST_TIME) and not printed:
# Only add this dial to queue if we should accept numbers at this time
print(count % 10) # wrap 10 presses to 0
# Reset values
count = 0
printed = True
time.sleep(0.01)
More programs to try
From the first two programs, you can get some idea of how to read the dial and
the hook button. To play and record audio, I found the programs aplay
and
arecord
work best, and can be easily invoked via Python’s subprocess module.
I also like to use espeak
to have the Pi read text.
Wedding Guestbook program
Here is a simple program to create a wedding guestbook. This is an idea I, and many others had, as a cool retro thing to have at a wedding reception to have guests leave recordings at.
It is very basic, feel free to adjust it to your needs. The way it works is when someone picks up the phone, the recorder will start, and save the recording to a timestamped file. When the phone is hung up, the recording ends. If you want the user to interact with the dial, I recommend the general purpose phone program listed later.
Note, this requires you to have the program arecord
installed.
import subprocess
import time
import threading
# Events allow us to wait until a variable is set
phone_hung_up = threading.Event()
phone_hung_up.set()
phone_picked_up = threading.Event()
phone_picked_up.clear()
# This thread sets the variables based on the status of the "hook" button
class HangUpThread(threading.Thread):
def __init__(self, phone_hung_up, phone_picked_up):
threading.Thread.__init__(self, args=(), kwargs=None)
self.daemon = True
self.phone_picked_up = phone_picked_up
self.phone_hung_up = phone_hung_up
GPIO.setmode(GPIO.BCM)
GPIO.setup(BUTTON_GPIO, GPIO.IN, pull_up_down=GPIO.PUD_UP)
def run(self):
while True:
if not GPIO.input(BUTTON_GPIO):
self.phone.phone_picked_up.clear()
self.phone.phone_hung_up.set()
else:
self.phone.phone_picked_up.set()
self.phone.phone_hung_up.clear()
time.sleep(0.1)
HangUpThread(phone_hung_up, phone_picked_up).start()
while True:
# Wait until the phone is picked up
phone_picked_up.wait()
# Start the recording process
process = subprocess.Popen(["arecord", f"{datetime.now().strftime('%Y%m%d-%H%M%S')}.wav"])
# Record until the phone is hung up
phone_hung_up.wait():
# Kill the process
process.terminate()
General purpose phone
I wrote this program that is a general purpose way to run commands when a number is dialed. For example, you can dial a specific number, and it will play a song, or read the weather, or let your record a message. My configuration is similar to the default. I added some fun Wav file events, such as one to the George’s voicemail song from Seinfeld:
52=events.WavEvent /etc/phone/sound/seinfeld.wav
If you have any questions about this, please email me (check my website’s footer for my address). I’ve just moved apartments, and so wasn’t able to fully verify all of the sample programs here work perfectly.