summaryrefslogtreecommitdiff
path: root/content/blog/rotary_phone_running_linux.md
diff options
context:
space:
mode:
authorMark Powers <mark@marks.kitchen>2022-07-19 21:12:41 -0500
committerMark Powers <mark@marks.kitchen>2022-07-19 21:12:41 -0500
commit4e965c7d9a66d6a72b24c7b319c10d8006f2026e (patch)
tree4021ef67be5ed3a76e0632c3cfec5d6428806850 /content/blog/rotary_phone_running_linux.md
Initial Commit
Diffstat (limited to 'content/blog/rotary_phone_running_linux.md')
-rw-r--r--content/blog/rotary_phone_running_linux.md276
1 files changed, 276 insertions, 0 deletions
diff --git a/content/blog/rotary_phone_running_linux.md b/content/blog/rotary_phone_running_linux.md
new file mode 100644
index 0000000..bf74f86
--- /dev/null
+++ b/content/blog/rotary_phone_running_linux.md
@@ -0,0 +1,276 @@
+---
+title: "Rotary phone running Linux"
+date: 2022-04-14T21:52:01-05:00
+---
+# 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.
+
+<iframe src="https://drive.google.com/file/d/1omulMRk71ZLnNeU9ytPbbEzRNth8wofV/preview" width="640" height="480" allow="autoplay"></iframe>
+
+## 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.
+
+<iframe src="https://drive.google.com/file/d/147yXcljBHC5YustzxSKdR3e3zPz3KHJj/preview" width="640" height="480" allow="autoplay"></iframe>
+
+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.
+
+<iframe src="https://drive.google.com/file/d/1HXRcyiyssQoM8UFvF867ygjDNpQvtQ4J/preview" width="640" height="480" allow="autoplay"></iframe>
+
+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.
+
+<iframe src="https://drive.google.com/file/d/1ngBg4z-gllk_08xzF5WV_9jWlH2iOrN0/preview" width="640" height="480" allow="autoplay"></iframe>
+
+## 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.
+
+<iframe src="https://drive.google.com/file/d/1A5NbGSgC4ooElVGK-jb0b8Ix5UW6YQuz/preview" width="640" height="480" allow="autoplay"></iframe>
+
+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.
+
+<iframe src="https://drive.google.com/file/d/1V9wChq0vLBPAYIcBnffrIViQU8G_i2MN/preview" width="640" height="480" allow="autoplay"></iframe>
+
+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.
+