Micropython code for your embedded project to read dialled numbers from a rotary phone. Use an old phone as an input device for your retro-futuristic project.
I designed this for an ESP32 board, but I think any board that is supported by the micropython machine
module will work.
This code is interrupt-driven so your main program is free to do whatever you want. You can poll for a dialed number, or register a callback to run once a number is dialed.
2024-11-10 - This is a work in progress. It's almost done, but give it another month for it to be production-ready.
Copy this to your /lib/
folder and you're ready to go.
This has no dependencies beyond machine
and time
that are already part of micropython.
Sample programs:
polling
import time
from pulse_decoder import retrieve_dialed_number, gpio_pin_number
gpio_pin_number = 14
def main():
while True:
# Check periodically for a completed phone number
dialed_number = retrieve_dialed_number()
if dialed_number:
print("Detected dialed phone number:", dialed_number)
if dialed_number[0] == 1:
# 1 - ABC - Play ABBA
pass
elif dialed_number[0] == 2:
# 2- DEF - Play Debussy
pass
elif dialed_number == (8,6,7,5,3,0,9):
# Play Tommy Tutone "867-5309/Jenny"
pass
# Sleep for a bit to avoid excessive polling
time.sleep(0.1)
interrupt-driven
import time
from pulse_decoder import register_callback, gpio_pin_number
gpio_pin_number = 14
def dialed_number_callback(dialed_number):
if dialed_number:
print("Detected dialed phone number:", dialed_number)
if dialed_number[0] == 1:
# 1 - ABC - Play ABBA
pass
elif dialed_number[0] == 2:
# 2 - DEF - Play Debussy
pass
elif dialed_number == (8,6,7,5,3,0,9):
# Play Tommy Tutone "867-5309/Jenny"
pass
def main():
# do some stuff
register_callback(dialed_number_callback)
# do more stuff
gpio_pin_number
- integer - Which ESP32 GPIO pin you want to use. Must support an internal pull-up resistor.virtual_timers
- boolean - Whether your device supports virtual timers. (defaultFalse
. The ESP32 does not.) The program will choose timers 0, and 1. You can change those too, if you want.- Various pulse characteristics if you really want
*DURATION*
,*DELAY*
,*TIMEOUT*
,*TOLERANCE*
. But you should not have to touch them.
This should "just work", but if your specific phone's characteristics are different from those expected, you may need to tweak the code a little. There are commented-out print statements you can uncomment to (To make the code as fast as possible in interrupt-context, these are left as commented rather than if-statements.)
- https://en.wikipedia.org/wiki/Pulse_dialing
- https://www.dialogic.com/webhelp/csp1010/8.4.1_ipn3/dev_overview_dsp_one_-_e1_dial_pulse_address_signaling.htm
- https://www.3amsystems.com/World_Tone_Database/Signalling_guide?q=Pulse_dialing
- https://fahrplan.events.ccc.de/congress/2023/fahrplan/system/event_attachments/attachments/000/004/462/original/analog_phones.pdf
From the REPL:
import os
os.mkdir "lib" # Just once
import mip
mip.install("xmltok") # For example
There is no unit testing. It's so hardware-dependent that I never Mock-ed it all up. Just load it on your ESP32 and test.