Analog Phone Dialer
Few months ago I got one of those old analog dial-based phones (the ones with the “rotary thing” that uses a pulse dialing technique to transmit the numbers across the phone line).
After some cleaning and minors fixes (like replacing a broken microphone) it became fully functional again, except for the fact that I could recieve< calls but I couldn’t make them…
The reason wasn’t a broken device but it’s own old pulse dialing tech (remember that nowadays everything goes under Dual-Tone Multi-Frequency signaling).
Even if most of the main modern phone lines still support pulse dialing (not actually sure how consistent this compatibility is), the average domestic optical fiber router doesn’t. Therefore, even if I could dial up to some destination, chances are the receiver wouldn’t even support my ancient dialing method, so if we were dealing with one of those answering machines “press 1 for whatever option”<) it would became useless again.
There are some workarounds over this problem out there, but I decided to go with my own AVR-based solution: an atmega48p capturing the rotary dial pulses and generating the proper DTMF tones using a DAC converter made with a R-2R resistors ladder.
How it works
After that, it was “only” a matter of counting the numbers on the rotary thing when dialing (there’re plenty examples out there, usually the most important thing when dealing with those switches is the debouncing time for proper reading - I based my implementation on this small snippet already available there) and writing the proper software to control everything (“reading numbers” + “injecting numbers onto the line”).
I also glued a small microswitch near to the main “hanging switch” to detect whenever the phone is “grabbed” or “released” in order to manually open/close the line (this could probably be done by other means, such as hooking up to some internal phone circuitry, but I wasn’t sure how to detect it and a simple extra switch was more than enough).
With all those elements in mind, I soldered the first prototype (click to enlarge):
Notice there’s also an external 5v relay module to control the line open/close contact (maybe a little bit too much for that…). This contact was previously attached to the dial piece, but since now it’s wired to the micro I’m “manually” controlling it by opening/closing the relay according to the firmware logic (also the line remains closed if the main “hanging switch” is pressed, so even if the micro wants to “open the line” it won’t be able to do it unless someone “grabs the phone” - which will also lead to the internal microswitch to be released too!).
The final schematics looks like this (click to enlarge):
- The whole port B is dedicated to the resistor ladder for the DAC converter.
- The headset button is wired to a microswitch next to the main “hanging switch” on the phone (the part that gets pressed when the headset sits on the phone itself). It’ll be activated/released the same way the main switch behaves.
- The dialer connector is directly wired to the “dialer wheel”. It’s a closed circuit that gets opened at certain intervals when “releasing the rotated number”. Counting does intervals is the key to detect which number was dialed.
- The relay output goes directly to the line connectors the “dialer wheel” was supposed to be initially attached. This way, instead of being that dialer reponsible for opening and closing the line when rotating (because of the pulse dialing) is the microcontroller itself the one that can open or close this part using the 5v relay.
- There’s also a LED + an unused push button for visual output and extra control (the button was never used but, hey, it can be implemented if required).
With that in mind I designed a small board with everything inside (small enough to be fitted inside the phone):
My initial idea was to screw the whole board on the base with some M3 screws, but I mess up the measurements and end up with holes too big. Also the bottom plate was harder to drill than I expected, so I ended up using that old friend of everyone: the hot glue gun.
State machine
When it comes to the “regular usage” of the device I made the following list of important things to solve and/or take into consideration when designing the logic of the whole system:
- Some delay between numbers during the “input phase” may occur (since the physical dialer takes some time to process each number). Need to make sure the line won’t reset / stop listening during those intervals.
- During a call (specially with automatic machines such as classic “customer service operators”) numbers must be added as fast as possible (no delay, no “numbers buffer” in that case, etc.).
- No external modifications to the phone (maybe one extra external cable, but do not drill/cut/break anything on it’s original case).
While the “no external mods” part is more or less solved with an additional USB connector on the back for power (wasn’t sure about hooking the whole thing to the phone line, so I thought an extra 5v USB connector would be the best approach), the other issues took me a little longer until I came up with the following state machine that implements everything I need:
graph TB
A(1. WAITING) -- phone-released
microswitch
released --> B(2. OPEN LINE)
A ---> A
B -- first input
before X ms --> C(3. BUFFERING)
B -- more than X ms
without first input --> B
B -. hanging the phone .-> A
C -- no new inputs since Y ms --> D(4. DIALING)
C -- input new number
before Y ms --> C
C -. hanging the phone .-> A
D -- output DTMF for each buffered number --> B
D -. hanging the phone .-> A
- It starts on the WAITING state with the headset on the “initial position” and the line closed. Each time the headset is “returned” everything would be reset and this state would be reached again.
- When grabbing the phone, the microswitch detects the change and moves to OPEN LINE. On this state we could start dialing the first number within the first X ms or wait. If we wait the state would be locked (until a reset action is performed) and, if we dial a number, it would be injected instantly. This way we can send signals to an open line if we need to (the “dial X to do Y” scenario on automatic answering machines). Line remains opened during this state (and after waiting the initial X ms) UNLESS we start dialing before the initial threshold. If so, we’ll change to the BUFFERING state.
- After dialing the first digit when grabbing the phone, the line is closed, that first number is stored in a buffer and the BUFFERING state is reached. Here the system listens and saves whatever amount of numbers are added to the buffer and, after Y ms of inactivity, it switches to the DIALING state. This was designed to be able to dial a full number without worrying too much about the response time on an opened line.
- The DIALING state would open the line, output the buffer content as DTMF signals and switch to the OPEN LINE state. Notice in that case the X ms count is not reset, so after that the user won’t be able to dial a full number again unless performing a reset by hanging the phone.
With this simple state machine we can:
- Answer the phone when ringing (the line would be opened right after releasing the headset)
- Dialing discrete numbers with an already opened line
- Have enough time to dial a full number when grabbing the phone by disconnecting the line on the first seconds of dialing
- Reset the whole thing by hanging the phone
The idea was to provide the most simplified experience rather than add more buttons and options (which can be done easily: speed dial, extra keys -asterisk, hashtag-, etc.) all while keeping the “visual aspect” as it was.
Sadly I needed an external power source, but I’m sure this would be solved in future iterations:
In the meantime I’ve got a fully functional old phone (I was searching for a red-colored one, but still this one is cool too!), I’ve learnt lots of things about wavetable synthesis generation and old/modern phone lines, and I made a small simple and cheap board to connect those old devices into the present days.
Source code
Available on my github page under the Unlicense.
Ordering boards
I made this thing mostly for personal use, but I was also trying to be as “standard” and “open” as possible (maybe in case I want to wire it to another different phone in the future, who knows…); so I ended up with a bunch of extra functional boards and now I’m thinking about distributing them (maybe even add the whole additional hardware stuff in case someone wants a kit or something similar).
I have no idea how to do that in the most efficient way (maybe a Tindie shop? my own small marketplace?) but if someone is actually interested in owning one of those boards, please reach me out and we’ll see! :D
Improvements, future changes, ideas…
- Self-powered device, wired to the phone internal power itself
- Phone-release detection based on phone circuitry rather than an external microswitch
- Use the PWM internal capabilites instead of the DAC converter?
- New functions such as speed-dialing, re-dial, “special keys” (hashtag…)
More images
(click to enlarge)
Links, references…
- Wikipedia: Dual-Tone Multi-Frequency signaling
- DTMF Measurement Description
- WolfSound: Wavetable Synthesis Algorithm (article)
- WolfSound: Wavetable Synthesis Algorithm (video)
- DTMF generator
- Sine Look Up Table Generator Calculator (the one I used on my code)
- Arduino DTMF Generator
- Interface a rotary phone dial to an Arduino