--- title: "Rotary phone running Linux" date: 2022-04-14T21:52:01-05:00 aliases: - /post/blog/78 --- # 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](https://www.adafruit.com/product/4944) and [these](https://www.adafruit.com/product/1956)). 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](https://www.adafruit.com/product/1475). 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](https://www.adafruit.com/product/4181), 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](https://www.jwz.org/blog/2016/01/my-payphone-runs-linux-now/) 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. ```python 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. ```python 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. ```python 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](https://git.marks.kitchen/?p=rotary_pi;a=summary) 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.