Close
0%
0%

An old rotary phone as Bluetooth set

When did the charm of holding a bulky receiver to your ear end? What if we could bring the feel of the old times to our smartphones?

Public Chat
Similar projects worth following
The aim of this project is to bring an old FeTAp-611 german rotary phone back to life. The device will be used as a bluetooth peripheral for your smartphone to make calls and receive them. Basically the same purpose it was thought for 30 years ago but complicating the things a lot.

In old times placing a phone call required a much more deeper link with the machine. In the case of rotary phones it even required to put your finger inside the holes of the dial wheel. With the touchscreens of nowadays smartphones -and even voice-dialing in some cases- the art of telephoning has come to a colder, feeling-less age. But what if we could combine the look and feel of vintage phones with the current telecommunication advances? 

This project started when I -to much displeasure of my girlfriend- acquired yet another piece of old technology, frozen witness of ages gone by: An old German post-telephone from the 80s.

The source code for a functional Python client is hosted in this GitHub repository. Feel free to use it, comment, and contribute!

  • 1 × USB Sound-card A cheap USB-Sound card with microphone and speaker connectors
  • 1 × Raspberry Pi Zero W With built in Bluetooth and Wi-Fi!
  • 1 × OTG Cable To be able to connect the USB Sound-card to the Raspberry Pi Zero W
  • 1 × An old rotary phone In my case a FeTAp-611 phone acquired on E-Bay
  • 1 × USB Power supply Either a cable to a socket-charger or a power-bank will do the job

  • Making it ring

    Xabi Zubi04/26/2019 at 11:48 0 comments

    The second most significant feature of these vintage phones, after the rotary-dial, is the characteristic ringing bell. Here the thing gets a little more complicated: Old phones have a electromagnet driven bell inside which sounds wonderfully well, but also requires very specific signals to be driven.

    In order to drive the bell we will require an at least 30V AC signal with 20-25 Hz frequency, which of course needs to be turned on and off appropriately (1 second ringing, 4 seconds pause, and repeating). In really old telephone exchanges this signal was produced by a electric little motor switching on and off contacts at the specified rate. These are the steps to obtain such a signal:

    1. A DC voltage of 30V needs to be obtained: This can be done either boosting up the 5V provided by our Raspberry Pi or down-converting and rectifying a higher voltage (such as the one from the AC sockets for instance).
    2. Once this is achieved the signal needs to be switched with a frequency of 20-25 Hz and the polarity needs to be inverted so that the electromagnet ringing the bell functions properly. This can be achieved by a PWM switched DC converter and an H-Bridge

    On the other hand they are also commercially available ringing signal generators.

  • Making everything work together

    Xabi Zubi04/26/2019 at 09:41 0 comments

    Currently we have a functioning Bluetooth set but we can only place calls, and interact with it through the cold touchscreen of our smartphone.

    It is time to use the peripherals of the rotary phone to answer calls, dial-numbers, and end-calls.

    Ofono exposes the most important methods to the D-Bus. D-Bus is an inter-application messaging system for Linux. D-Bus can be easily accessed and controlled using the Python module 'dbus'. The following snipped shows how to place a call:

    import sys
    import dbus
    
    number = 123456789
    
    bus = dbus.SystemBus()
    
    manager = dbus.Interface(bus.get_object('org.ofono', '/'), 'org.ofono.Manager')
    
    modems = manager.GetModems()
    
    # Take the first modem (there should be actually only one in our case)
    modem = modems[0][0]
    
    hide_id = "default"
    
    print("Using modem %s" % modem)
    
    voice_call_manager = dbus.Interface(bus.get_object('org.ofono', modem), 'org.ofono.VoiceCallManager')
    
    voice_call_manager.Dial(number, hide_id)

    More information about the complete Ofono API can be found on its GitHub repository documentation. Specifically the most interesting part is the VoiceCallManager API.

    Our phone should be able to place calls, answer them, and hang them up. On top of that, it would be nice if it could replicate all bells and whistles (pun intended) of the rotary-phone. The plain old telephone system (POTS) produces a 440 Hz tone when the receiver is lifted in order to signal that the line is available for use.

    Moreover, we want to also exploit additional functionalities thanks to the internet connection of our new phone. We could, for example, use the numbers dialed when the receiver is hooked to trigger features such as spoken weather forecast, spoken mail reading, shutting down the system, or fast dialing; while the numbers dialed when the receiver is lifted will work as they were intended to: by dialing that number on our smartphone and starting the call.

    The telephone.py script contained on this project implements the most important of these described functionalities. We will copy this file on our /home/pi/ directory.

    Once our script is finished, we can add it as a service that runs on boot for headless operation. We will create the file /etc/systemd/system/telephone.service and copy the following text in it:

    [Unit]
    Description=Bluetooth Telephone interface
    After=ofono.service
    Requires=sound.target
    
    [Service]
    Type=simple
    ExecStart=/usr/bin/python3 /home/pi/telephone.py
    
    [Install]
    WantedBy=multi-user.target
    

    This will force to run our system as soon only if our soundcard has been loaded properly and after ofono service is initiated. Afterwards the service needs to be enabled with:

    systemctl enable telephone.service 

    Our telephone interface script will be now loaded on each reboot.

  • Setting up the Bluetooth

    Xabi Zubi04/25/2019 at 21:09 1 comment

    Bluetooth allows to communicate between different types of devices and with different purposes. Therefore, several profiles exist for each communication type. The classical and best known ones are:

    • A2DP  (Advanced Audio Distribution Profile): It is mostly used on unidirectional Bluetooth audio system such as wireless Bluetooth speakers or multi-room audio streaming.
    • HIP (Human Interface Profile): As the name suggests used for all Bluetooth mice, keyboards, and other input devices.
    • FTP (File Transfer Protocol): User for file transfer as the name shows. Good old way file exchange between not-so-smartphones when the cloud was still just a mass of condensed water.
    • HSP (Headset Profile) and HFP (Handsfree Profile): Used for communication between a Bluetooth enabled device and a headset.

    HSP fits perfectly our needs. It allows us to handle the signaling (dialing, call start/end) between the smartphone and the telephone as well as the audio stream exchange. On top of that, one must make the distinction between the HSP "Server" and the HSP "Client". In our case the Pi will function as client while our smartphone will be the server.

    Unfortunately for us, the A2DP profile is the only straightforward out-of-the box implemented profile for the Raspberry Pi so enabling our Pi Zero to work as a HSP will not be such a trivial task.

    Three applications take part on the whole Bluetooth routing:

    • The BluEz Bluetooth agent: It is in charge of managing the pairing, trusting, and connection with any device.
    • Ofono: Originally developed by Intel and Nokia for their phones, this software package will allow us to handle all telephony related signaling.
    • Pulseaudio: While Ofono handles the signaling, once a call is established it is necessary to route all incoming and outgoing audio traffic from our old phones receiver all the way to the smartphone through our Bluetooth connection. Pulseaudio's capabilities to handle HSP Bluetooth profile are relatively newly added and we can say that they are still in continuous improvement. The current stable version of Pulseaudio is version 12, however only version 10 is included on the default Raspbian Stretch repository. Some other tweaks need to be performed to make the latest Pulseaudio compatible with our little Raspberry.

    The first two packages can be installed from the standard Raspbian Stretch repository with the following command:

    sudo apt-get install pi-bluetooth ofono
    

    A small change needs to be made to the dbus policy of ofono in order to be able to open the audio link properly and communicate with other processes. The file /etc/dbus-1/system.d/ofono.conf needs to be modifies so that the line reading

      <policy context="default">
        <deny send_destination="org.ofono"/>
      </policy>
    

     reads

      <policy context="default">
        <allow send_destination="org.ofono"/>
      </policy>
    

    Compiling Pulseaudio

    On the other hand, the Pulseaudio source requires a small modification and needs to be manually built. It can be fetched from the project's GitHub repository:

    git clone git://anongit.freedesktop.org/pulseaudio/pulseaudio

    The problem here lies on how Pulseaudio implements the HSP Audio routing. When two Bluetooth enabled devices establish a HSP Audio link, the data is exchanged by means of Synchronous Connection Oriented (SCO) packages. This is a real-time narrow-band protocol without package retransmission suitable for Bluetooth voice exchange. The synchronization between the transmitting and receiving parts is made by sending one SCO package per received SCO package. 

    This all works perfectly if both packages have same or very similar size, however Pulseaudio hard codes the SCO package size to 48 bytes, while the controller from the Raspberry Pi negotiates a package size of 60 bytes. This behavior was observed...

    Read more »

  • Programming the interface

    Xabi Zubi04/25/2019 at 20:46 0 comments

    The software tasks can be divided into the following parts:

    • Setting up the audio: The USB Card needs to be set as the main card
    • Reading the dialed numbers: The rotary-dial needs to be read and its pulses translated to the dialed number
    • Reading if the hook is lifted: It was necessary to lift up the hook to start dialing a call. We want to replicate this behaviour. We also want to use the action of hooking down the receiver to end a call.
    • Setting up a Bluetooth link to our smartphone: Ideally the tabletop-telephone needs to be detected as a Bluetooth hands-free set and the appropriate signals (start call, hang call, audio-link) have to be exchanged between the smartphone and the "dumb-phone".

    Setting up the audio

    The Raspberry Pi Zero with the latest Raspbian operating system should already automatically detect most of the USB sound-cards. To avoid any sort of confusion between devices we will disable the builtin audio by commenting the following line out from the /boot/config.txt file.

    dtparam=audio=on

     Afterwards we can already test the speaker by typing the following command:

    speaker-test --test=wav -w /usr/share/sounds/alsa/Front_Center.wav
    

    We should be able to hear "Front Center" repeatedly spoken from our receiver's speaker.

    We will come back to the audio setup when configuring the Bluetooth. The services we are willing to use for the Bluetooth hands-free profile require Pulseaudio to be modified, compiled, and installed from source.


    Detection of signals

    The dialing pulses and the hook can be read using the RPi.GPIO Python module. The following class snippet can be used to place the decoded number into a queue and be accessed from other threads (more about multi-threading and queuing can be read here).

    
    class RotaryDial(Thread):
        def __init__(self, ns_pin, number_queue):
            Thread.__init__(self)
            self.pin = ns_pin
            self.number_q = number_queue
            GPIO.setup(self.pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
            self.value = 0
            self.pulse_threshold = 0.2
            self.finish = False
            GPIO.add_event_detect(ns_pin, GPIO.FALLING, callback=self.__increment, bouncetime=90)
    
        def __increment(self, pin_num):
            self.value += 1
    
        def run(self):
            while not self.finish:
                last_value = self.value
                time.sleep(self.pulse_threshold)
                if last_value != self.value:
                    pass
                elif self.value != 0:
                    if self.value == 10:
                        self.number_q.put(0)
                    else:
                        self.number_q.put(self.value)
                    self.value = 0

     Similarly we can detect if the receiver is hooked or lifted:

    # Receiver relevant functions
    GPIO.setup(self.receiver_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
        if GPIO.input(self.receiver_pin) is GPIO.HIGH:
            self.receiver_down = True
        else:
            self.receiver_down = False
    GPIO.add_event_detect(self.receiver_pin, GPIO.BOTH, callback=self.receiver_changed, bouncetime=90)
    
    def receiver_changed(self, pin_num):
        if self.receiver_down:
            self.receiver_down = False
        else:
            self.receiver_down = True

    Notice that in my case because of wiring optimization I chose to join both switches to active low value (meaning they will be grounded when closed). Therefore the pull-up settings have to be set accordingly. 

  • Wiring everything up

    Xabi Zubi04/25/2019 at 19:06 0 comments

    We want to replace the ancient simplicity of the Siemens manufactured board by the modern complexity of the Raspberry Pi Zero W. The project, however, also aims to keep the component count low and avoid using unnecessary components if they are not compulsory: The phone already has its own speaker and microphone? So why replace them with their modern counterparts? Yes, I know an old carbon microphone may not sound precisely crystal clear, but it will add another bit of vintage touch to our project (and a 1980 flavored frustration to the one talking to us on the other side of the line); our smartphone already has all required communication functionalities and chatting applications? So why re-implement them on the Pi? Let's just figure out how to connect our new old rotary-phone to our old new smartphone. The solution will be squeezing the Bluetooth capabilities of the Raspberry Pi Zero to the maximum.


    Wiring the rotary dial

    Another important point to preserve the touch of this old phone is conserving and using the rotary dial as it was intended to. Old rotary dials require the finger to be inserted in the hole corresponding to the number to be dialed and turning the wheel clockwise until the stop. When the wheel is released, a spring rewinds it back to its original position. On its way back the dial opens and closes a contact several times producing a train of equally spaced pulses. The amount of times this contact is closed and opened corresponds to the dialed number. The diagram below shows such a pulse train:

    A four pin socket named NS (Nummerschalter) links the circuit board to the rotary dial part.

    First of all, all unnecessary components have been soldered out of the circuit board to free up space for the placement of the Pi and the sound-card as well as the OTG cable linking both and additional cabling to redirect the microphone and speaker. However, the old circuit boards is a perfect support for all the pins and our devices, thus it has not been completely removed.

    After checking the circuit diagram and careful cross-checking with a multimeter, the circuit between the NS pins 1 and 2 seems to close when a dial-pulse is produced. These pulses can easily be read using any input-enabled GPIO from the Pi. 


    Wiring the hook

    The hook switch operates in the opposite way to the intuitive one. The circuit is closed as long as the receiver is hooked up and it's opened when the receiver is picked up. The circuit is opened and closed between the pins 2 and 4 of the NS header. 

    Because the rotary dial impulses and the hook switch share the pin 2, a voltage (or ground connection) can be fed to this pin and the value of pins 1 and 4 read using the GPIOs of the Raspberry. 


    Wiring the receiver

    The receiver encapsulates the carbon microphone and the speaker. The covers of them can be removed exposing both parts attached through a rubber ring which was already merged with the plastic with the pass of the years, Although the audio quality produced by both parts will not sound so great there is no real need to replace them and re-attach modern microphones and speakers as replacement.

    In order not to damage the rubber rings, the wires correspond to the microphone and the ones from the speaker were found by trial and error using the sound-card. In this very model the pins 1 and 2 from the header labeled 'HS' correspond to the microphone and the pins 3 and 4 to the speaker. 

    Another important fact to notice is that due to the fact that the speaker and the microphone signals are mixed for transmission, there is a short circuit between their pins. Because of that, the track from the other side of the circuit board starting from speaker and microphone pins was cut to isolate them. 

    [insert pic of cut track]

    Since we cut this tracks, from this very moment the phone is nonoperational for the traditional...

    Read more »

  • Opening the box and wiring

    Xabi Zubi04/25/2019 at 18:56 0 comments

    The phone was intended to be technically manipulated only by authorized personnel of the German Postal Service therefore in first sight it does not have any exposed screws or possible means to remove the upper cover. However, there are 5 small white seals labelled with a 'D' that can be punctured and removed by using any sharp object.

    Behind them 5 screws allow to remove the main cover as well as the network and receiver's wire cover. Exposing the inner part of the device:

    The circuit seems to be very simple and it contains only a handful of electronic components. A quick internet search delivers us a rather low resolution circuit-diagram of the telephone:

    The most meaningful components can be therefore straightforward identified and mapped to their physical locations. From the black yellow-topped diodes of the 80s to the tiny isolation transformer on the corner. Although the old electronics have an unique charm, we are only interested in the human-interface peripherals. Namely:

    • The rotary dial (more on its operation later)
    • The connections to the receiver (microphone and speaker)
    • The hook-switch
    • The ringer (more on this also later)

  • The Fernsprechtischapparat 611

    Xabi Zubi04/25/2019 at 18:48 0 comments

    German is such a language that allows the creation of long yet overly specific words such as the one designating the main protagonist of this project. The Fernsprechtischapparat  (tabletop-telephone-machine) Model 611, appropriately abridged as FeTAp 611, was the common-issue telephone from the Bundespost (German Postal Service) starting in 1968. It allowed the real broad expansion of the German telephony network. In 1963 only 19% of German households had access to the phone network, while in 1988 already 88% of private-houses had a telephone-line.

    The device that I acquired is the Model 611-2a. The digits 61 let us know that it was the rotary-dial model (as opposed to the 71 and 79 which for instance already had a numeric dial-pad). The last digit 1 informs that it is a standard model (meaning it does not include any fancy features such as return-call functionality or a fare counter). The final 2a presumably shows that it is a later model.

    On the same plate, the number 04/80 is engraved inside a black box pointing out to the date of issue of the terminal (April of 1980).

View all 7 project logs

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates