Bluetooth-Connected Rotary Payphone
by dsluder13 in Circuits > Raspberry Pi
9475 Views, 137 Favorites, 0 Comments
Bluetooth-Connected Rotary Payphone
About 10 years ago, feeling inspired by Sparkfun, I wanted to turn a 1950's Western Electric Rotary Payphone into a working Bluetooth headset. I called it "The World's Most Impractical Bluetooth Headset." After some hacking around, I got most of the internals working, but I couldn't figure out a way to make it call out. Today, though, we've got the Raspberry Pi, which makes this thing a cinch.
This, my first Instructable, will be a walkthrough of the hacking that went into figuring out how to make this work along with what exactly I did to create the final product. The project uses a Raspberry Pi 3B and some supporting electronics, so we're going to cover the decisions I made and why this was so [relatively] easy. Here's what you'll need if you want to do something similar:
Supplies
Most Importantly
- An old rotary payphone
The Guts
- Cheap headphones with built-in microphone
- Male-to-male audio cable
- 4.7K resistors
- Multi-colored Hookup Wire
- 4-Wire Male/Female Connector
- Heat Shrink Tubing
- 9 inches of thick stranded insulated wire
The Brains
- Raspberry Pi 3B
- Raspberry Pi Peripherals (Power supply, MicroSD card, USB Keyboard/mouse, Monitor with HDMI cord)
- USB Soundcard
- USB Bluetooth Dongle
Everything Else
- Soldering Iron + Solder
- Heat Gun
- Multimeter
- Alligator Hookup Wire
- Wire Stripper
- Various Screwdrivers
Organize Ourselves
If you've used a Bluetooth headset or connected your phone to a car's Bluetooth stereo, you know that there are plenty of things that the headset or stereo can make your phone do: answer a call, hangup from a call, call a specific number, increase/decrease your phone's volume, send a spoken text message, etc. To figure out exactly what we're going to need to do, let's set the goal for what we want to be able to do with this project:
I want to be able to:
- Pair my phone with the payphone
- Use the phone to listen to the audio of the call and have it transmit my voice
- Answer an incoming phone call
- Dial a number and make a call
- Hang up on an active call
All of these goals have some underlying requirements on our project. I like writing these down on a checklist so that I know what I've accomplished and what is left. Here they are:
- Hardware that supports the ability to connect my phone to it via Bluetooth and act like a wireless headset. Hardware can output audio and also receive audio as an input.
- In the phone handset, I'll need something to convert the output signal (speaker) so I can hear it and something to pick up my voice and convert it into a signal to send (microphone).
- Ability to sense that I've picked up the handset so that it knows to answer the call and start transmitting audio.
- Ability to sense when a number is dialed and what that number is.
- Ability to sense that I've hung up the handset.
Looking at that list, we can see that we've got one output and three inputs. They are split between analog signals (i.e., those that have continuous values) and digital signals (i.e., those that have only two values like on/off). To learn more about the difference, Sparkfun has a great Analog vs. Digital write-up.
Outputs:
- Speaker signal (analog)
Inputs:
- Microphone signal (analog)
- Handset Pickup/Hang up signal (digital)
- Dialed number signal (digital)
So at a minimum, we need a piece of hardware that supports Bluetooth connectivity with the Headset profile, has multiple inputs and outputs, and can handle both digital and analog inputs and output. As you saw earlier, I'm going to use a Raspberry Pi 3B to make this happen. It'd be possible to do this with an Arduino and the right Bluetooth shield, but the ease of use of the Raspberry Pi made it the winner for me.
Hack the Dialing Mechanism
I love that old phones are totally analog - you won't see a PCB in sight. They're packed with switches, resistors, transformers, and that is IT. That makes hacking it relatively simple. The thought process for this step is that we need to see what connections are available to use for us to feed into the Raspberry Pi so that it can know what number is being dialed.
After we open up the phone and take off the half that has the dialing mechanism, we see five contacts stacked on top of each other. Let's assume the connections between these switches have different characteristics. To figure out those differences, we're going to use the multimeter to measure the resistance across each combination of these contacts. The way I like to do this is to write out a "resistance map" where I assign an index to each contact, write out each possible contact combination, and then measure the resistance for each combination.
Some contacts have zero resistance, meaning they're directly connected; some contacts have infinite resistance, meaning they're completely disconnected; and some contacts with some small amount of resistance, meaning that they're basically connected. Next is figuring out what changes when we dial a number. Using the same set of contact combinations, connect the multimeter to each set of contacts and then slowly turn the dial to see what changes (some alligator clips and an auto-ranging multimeter can save some frustration here). I wrote out what happens for each contact that has some sort of change when dialing.
To finish up this step, let's draw out a logic diagram showing what happens when a number is dialed, but only for those combinations that change. Looking at the diagram, we discovered that some contacts flip once or twice while dialing, indicating a start or stop of the dialing process. Others will alternate as many times as the digit that was dialed. Next, we'll build a circuit that we can use to tell the Pi when a number is being dialed and what that number is.
Dialing Mechanism Circuit
We can use the logic diagram we drew up at the end of the previous step to figure out the circuit to build to input our dialing signal to the Raspberry Pi. To make the programming simpler, I'm going to use two inputs: one to indicate when dialing starts and finishes and another input that will alternate as many times as the dialed digit.
To create these inputs, we need to make sure they are the right voltage level for the Pi. In general, binary digital inputs are either HIGH or LOW, which means the voltage is either some MAX or MIN value, respectively. For the Pi, the MAX value is 3.3V and the MIN value is 0V (i.e.,ground). What is also important is the threshold between those values. For the Pi, a value of 1.8V is this threshold: anything higher than that is interpreted as HIGH and anything lower is LOW. To reduce any confusion, we want to make sure to stay away from that threshold value so there's no confusion.
One more thing to remember is that a Raspberry Pi is powered by a 5V USB plug; there's a voltage regulator that reduces the 5V to 3.3V. We can use either that 5V or the 3.3V in our circuit - to make things easier, we'll stick to the 3.3V.
Now, we need two sets of contacts: one that indicates the beginning and end of a dial and another that alternates to indicate the dial digit. Looking at the logic diagram, I see that R13 fits the first need and R25 fits the second.
The usual pattern for an input signal like this is to use a resistor in series with the switch (i.e., pull-up or pull-down resistor) and have the input wired to the connection between them. That way, when the switch is open, the signal will get pulled up or down by the resistor, but once the switch closes, it will be pulled down or up by the input voltage. We saw that the resistor connections are never purely connected, but the resistances we see (1.2Ω in R13 and 120Ω in R25) are small enough that they can be negated with the right-sized pull-down resistor. See the schematic for the calculations. (I used 5kΩ for the calcs but only had 4.7kΩ laying around, which was close enough).
Wiring this up is pretty easy since the contacts all have screws that I can put wires underneath. I wired together R1 and R2 since they both have the 3.3V input voltage needed so I only have to deal with one wire going to the Rapsberry Pi. For the same reasons, I connected the ground wires.
After all the connections were made, I hooked up the Pi purely to access the pins that supplied the 3.3V and ground connections to make sure the circuit worked correctly. Check out the video to see how it does.
Finally, to tidy things up, I soldered my 4 wires (3.3V, Ground, Dialer Start/Stop, Dialer Digit) to an I2C connector so that I could connect it to the other half of the phone without having hard-wired connections.
Handset Switch Hacking
This is going to feel a lot like Step 1. First, we'll find all of the available contacts, then we'll create a resistance map, and finally we'll see what changes when the handset gets picked up.
For this phone, I'll be using all of the switches that would make contact with the front half of the phone once they're put together. I'll be using the connected screw terminals to take the resistance since the tabs are relatively flimsy and don't respond well to poking.
Handset Switch Circuit
The final resistance map here tells us that R56 is infinite by default and zero when we pick up the handset. This means we can treat these contacts like a normally open/closed switch. We'll just add a pull-up resistor to it and then let the voltage across the resistor be our input. When the handset is down, it is pulled to 3.3V. When the handset gets picked up, it is pulled to ground.
All in all, this circuit requires has three connections: 3.3V, Ground, and the Headset On/Off Input. I'll combine the 3.3V and Ground connections with wires needing the same connections from the dialing mechanism circuit so that we've only got one connection for each to the Pi.
You'll see in the photos I went ahead and soldered up the other I2C connector and then extended the wires into the phone's change cage, where the Pi will sit.
Handset Speaker
Next step is to get the speaker and microphone in the handset working. Opening up the handset, the speaker and microphone drop right out - they're only held in by the handset grates. Looking at the wires coming into the phone, we've got a total of three connections here: two for the speaker and two for the microphone with one connection in common. That works out - we should only need 3 wires to get our speaker/microphone signals to the Raspberry Pi.
First is the speaker. Looks like the contacts in the handset press against two tracks on the speaker. To test out the speaker and see if it can be driven by a typical audio signal, I cut my male-to-male audio cable in half and stripped the wires down. I used my multimeter to figure out which band on the plug corresponded to which wire, connected a set of alligator clips to each wire, plugged the audio cable into my phone, and queued up some royalty-free music. I used the alligator clips to connect each combination of wires to the speaker contacts and found that a black with either a red or a white played music through the phone. That means the black is our ground wire and the other two are the left/right signal wires, but we'll only need one of them since the phone speaker is a mono signal.
Handset Microphone
The microphone for this handset doesn't have anything connecting it to the wires, which is surprising. The other issue, though, is that this microphone is a carbon microphone. The electronics of that type of microphone won't work with the Raspberry Pi, so we'll need to replace it with something more contemporary. Here is where we'll deconstruct the headphones with built-in mic.
First, open up the mic enclosure as best you can without hurting the mic. Take the mic out and cut off any wires not connected to it. Then we'll desolder the current connections - one to G for Ground and the other to M+ for the mic signal. After that we'll solder a couple wires to it so we can use it in the handset.
To finish it off, we'll connect it to the handset, keeping an eye on what we consider the ground line - which it'll have in common with the speaker - and the microphone signal line. As you'll see in the phone, the white line in the handset is our ground line, the black line is our microphone signal line, and that makes the red line the speaker signal line. Now we'll put the speaker back in along with its cover and the cover for the microphone.
Wire It All Up
Now that we've got all the hardware sorted out, it's time to get everything connected. From the handset, we've got three wires that we'll need to hook to our two audio plugs: one for the speaker, the other for the microphone. The challenge here is that the original wires from the handset aren't made out of traditional copper; instead, it seems like they are copper "threads." I tried to solder on them, but instead they just burnt, so I used some thick, stranded wire to try to "weave" the wires into the stranded bundle to make sure there were plenty of connections. Once that finished, I had three beefy wires that I soldered to the hookup wire I've been using so everything looks clean-ish. After that, I connected the hookup wire to the audio plugs so I could plug it into the Raspberry Pi sound card.
The last step here is to create a way to plug everything into the Raspberry Pi consistently. To do this, I used some female-to-female jumpers that let me insert my wires into them to connect everything up. I selected my 3.3V, Ground, and 3 Input signals to all be next to each other:
- Pin 15: Input
- Pin 16: Input
- Pin 17: 3.3V
- Pin 18: Input
- Pin 20: Ground
I put the jumpers on and then hot glued all 5 of them together so that it'd take a lot of force to remove them. And then after that, I snaked everything into the change cage and plugged it in: speaker output, microphone input, and my 5 hookup wires. BOOM WE ARE CONNECTED. Now let's get to programming...
Programming Overview
Here's how we'll approach the programming:
- Set up our Pi with Raspberry Pi OS
- Install the required audio/Bluetooth packages
- Test out the Bluetooth to make sure our speaker and microphone work
- Create a service that uses a Python script we'll also write to allow us to connect Bluetooth devices without having to interact with the Pi
- TEST IT OUT
Bur first, a shout out to scribles.net. I'm using this post as the basis to get things working, and it told me everything I needed to know.
Set Up Raspberry Pi OS
Alright, you've got a microSD card and its adapter so you can write data to it. Here's how to install our operating system:
- Download and install balenaEtcher, which will let you write the Linux image to your microSD card.
- Download the August 20 2020 release of the Raspberry Pi OS. (I had issues with getting more recent releases to work easily)
- Plug your microSD card into its adapter and into your SD card reader.
- Open up balenaEtcher, select "Flash from file," then find the .zip file you downloaded of the OS image.
- It should automatically select your microSDcard - if not, make sure to select it.
- FLASH!
When it's done, plug the microSD card into your Raspberry Pi, plug it into an HDMI cable and power it on to make sure everything works. I'd also suggest a wireless keyboard/mouse combo that'll make interacting with the Raspberry Pi easier. Alternatively, set up the wireless and enable SSH on your Pi and access it through your computer via SSH.
Pi Setup and Bluetooth Configuration
After you boot up your Pi, you'll want to make a few changes to it so that it uses the Bluetooth USB dongle instead of the on-board chip. Then you'll install ofono, to let you interact with your phone, and PulseAudio (if it's not already there), to let your Pi interact with and manage the audio from your phone.
Once those are good to go, you'll set up a Bluetooth connection to your phone and make a call to validate that Bluetooth works along with the speaker and microphone.
Looking at the three text files attached to this step, follow them in this order:
- PiSetup.txt
- BluetoothSetup.txt
- ofonoTest.txt
At the end of this step, we've confirmed that Bluetooth works, our handset works, and we can dial out programmatically. Now we just need a Python script that watches our inputs and calls out if we dial a number.
Dialer Python Script and Service Setup
To finish setting things up, we will create a Python script that has all of our logic in it and then create a service so that it continually runs in the background. This step will all happen on the Raspberry Pi. Go ahead and download all of the files and then follow the steps in the "ScriptAndServiceSetup.txt" file to get things set up.
Test Our New Headset
The moment of truth here is: will it work?!?
We've checked the circuit, confirmed Bluetooth works, and added all of our code. Now let's plug the Pi in, pick the phone up and dial a number.
LOOK AT THAT! IT'S RINGING! IT'S WORKING!
Hang it up. THAT WORKED TOO!
Now let's call myself from a different phone.
YASSSSSSSSSSS. Pick it up.
I can hear me talking to me on a 1950's rotary payphone. That's badass.
The demo video isn't too exciting since to experience you need to be the one dialing out or receiving a phone call from it. You can see me dialing a test phone number, waiting for it to say my phone number out loud (come on, it's the internet), then doing an echo test so that I can hear myself.
Lessons Learned and Next Steps
This was a long journey, and there were plenty of bumps along the way. Here's some of what I learned:
- Raspberry Pi OS distributions differ more than you think I initially started this project last year, and the August 2020 desktop distribution was what I used. I ended up upgrading to the December 2020 OS Lite distro and found some Bluetooth issues. Once I went back to the August 2020 distro, everything worked like I expected.
- Analog electronics aren't perfect I initially had 2 signal lines coming from the dialer - one to determine when a digit dial starts/stops and another that oscillates the same number of times as the digit dialed. It turned out the signal that indicated the dial start/stop wasn't perfect - it gave me random oscillations, so I had to get rid of it and use timing in the code instead.
- Coding takes a lot longer than expected I thought I'd finish the coding in a weekend, but I was wrong. Stupid mistakes, syntax errors, and debugging over wifi made everything take longer.
But now that I've got it all working, here are some improvements I want to make:
- Make it ring These old phones were only meant to be dialed from, not answered from. There's a bell-shaped piece of metal inside the thing that I'd like to hook up a ringer to so that I can hear when someone's calling me.
- Make it tone When you pick up the handset, I want to generate a dial tone and play that so it sounds like phones used to sound
- Make it pretty The change cage is an eyesore, there's a big black panel where something used to go, and there's some cleaning up I can do to it.
- Make it portable What good is a Bluetooth headset if you need to plug it into a wall? I'd like to get a hefty USB battery pack to plug the Raspberry Pi into. Then I want to strap this thing to piece of wood, add some padding, and wear it like a backpack.
- Make it shareable In order to connect a phone, you have to SSH into the Pi and manually allow it. I'd like to add some automation so that others can connect to it and play around with it.
- Make it light up and more interactive I'd like to add a couple LEDs for status since there isn't any output connected to the Pi. I'd also like to add a dial or two so you can increase and decrease the volume and microphone levels. It also sounds fun to add some "special numbers" that play something interesting if you happen to dial them
Thanks to everyone who reads through this journey. It wasn't short, but I had a lot of fun finally finishing it and documenting it along the way.