A Raspberry Pi Telegraph Emulator

In early 2022, I visited a telegraph museum in regional Australia. Whilst there, I chatted with the duty volunteer who lamented at the challenges Australian telegraph museums are experiencing to reliably send and receive messages between the museum stations scattered around the country. The underlying issue turned out to be related to transmission errors and the explanation of the problem started me along the path of writing this project: a Raspberry Pi application that emulates a historic telegraph network using the Internet.

Telegraph has had a long and interesting history. A superb Neal Stephenson article in the December 1996 edition of Wired Magazine provides an awesome insight into the people, places and times of the telegraph’s heyday and if you have a few spare hours (as the article is extensive), its meandering explanation of the history is equally interesting, delightful and informative. You can easily and freely find the article by searching the Internet. Its title is "Mother Earth, Motherboard" and I highly recommend it.

The overland telegraph became redundant and was replaced when the nation undertook a transition to a national (voice) telephone network. Over time, a network of telegraph museums was established and because the overland telegraph no longer existed, in order to demonstrate how telegraph used to work, the museums turned to the telephone network to convey telegraph signalling between themselves. Their emulation method was both simple and clever: by connecting a morse key directly to the serial data input of a 300 baud analogue modem, the modem could convey the keypresses to the far end telegraph station via the telephone network, and a sounding device connected to the serial data output of the far end modem could replay the morse code.

So-called ‘dial up modems’ are not normally used this way. Instead, they normally convey serial data formatted as 8 bits + 1 stop bit + parity. However for the telegraph application, the museums were using the dial up modems to directly sample the morse key at a rate of 300 times per second. With this arrangement of modems, providing that the PSTN provides a reliable connection, so too will morse keypresses be reliably communicated (with keypress timing quantised at 300 samples per second).

The issue the museums are now facing is that the traditional telephone network has now itself been superseded by a national broadband network. Just as happened with the telegraph, our former telephone network now no longer exists. Telephone-like services are still available of course, but they are emulated using VOIP (Voice over IP) techniques which sample and compress audio telephony waveforms into data packets suitable for conveying over a data network. This is so for both contemporary land line and contemporary mobile telephony.

This means that the museums are now connecting their 300 baud modems using VOIP adapters. Stop for a moment and think about the end to end arrangement: the morse key feeds a 300 baud modem which then feeds into VOIP adapter. The VOIP signalling and packets traverse the broadband access network, then the internet service provider’s internal network, and then heads out onto the internet. At the far end when the packets reach the peer telegraph museum, the signalling and packets go through the same steps in reverse.

This chain of connections is complicated and there are many ways that errors could be introduced. Although VOIP works very well when conveying the human voice, it can be very poor at conveying an audio-band data service such as a 300 baud modem link. Voice compression and the asynchronous internet does not work well when conveying highly phase and frequency sensitive modem tones. The degree to which this telegraph emulation arrangement works at all is highly ATA-configuration and voice service provider dependent.

The experience and reliability of using 300 baud telegraph over VOIP was fine when we had a ‘real’ (uncompressed synchronous/isochronous) PSTN, but using VOIP over a best efforts data network does not lead to a great experience. For the telegraph museums, a broadband-specific solution may provide greater reliably.

Making some design decisions

One of my first concerns upon embarking on this project was to ensure that the timing of the morse keying could be detected, transmitted across the internet and then reproduced as accurately as possible.

Back in the day when morse ruled the communications world, the idiosyncratic ‘sounds’ of the ‘fists’ of individual operators could be recognised by the other telegraph operators in distant telegraph outposts: different operators had their own unique sound. Trained ears could hear the timing differences from one operator to the next and so they were able to uniquely identify each other by the style of the dots and dashes. I therefore wanted this telegraph emulator to reliably reproduce pulse timing so that the idiosyncrasies of the morse operators were not lost or distorted. Accuracy of measuring and reproducing pulse and space widths and transmitting the information across a jittered lossy Internet would therefore be central to the implementation.

The 300 baud modem approach sampled the morse key at 300 times per second. Back in the day, many operators could transmit 40 or 50 words per minute – and some could even exceed those rates. In rough numbers, 40 to 50 words per minute equates to roughly 20 cadenced state transitions per second. Ideally, to faithfully reproduce the individual characteristics of a fast telegraph operator, it would be nice to sample at a higher rate than 300 times per second.

I required an approach for reading the morse key and precisely timing the key-press intervals, and then driving a morse sounder with equal precision. Precision like this can be achieved with carefully controlled software timing loops, but because I wanted to use a Raspberry Pi, the telegraph emulator would need to run under Linux in a multi-tasking operating system environment. Linux is a great platform because the operating system is written to allow many different things to be going on at what appears to be the same time. However doing lots of different things at the same time is really an illusion. For any (single threaded) multi-tasking operating system, the processor’s available time is ‘sliced’ between all of the different tasks and the operating system is really doing one thing at a time, switching rapidly between different tasks so as to give an impression that everything is happening at once. When the CPU supports two or more threads, a few independent tasks can run pseudo-simultaneously (accessing physical memory and physical I/O can still be a bottleneck!), but as there are typically hundreds of jobs that the operating system is performing at any one instant, each task is still essentially time-sliced. Knowing this is important because at the millisecond level, the scheduling from task to task can introduce substantial jitter. This means that polling the morse key input and intermittently updating the sounder output would not work with the expected precision if the software simply ‘polled’ the devices. Try it this way and you will see for yourselves!

As an aside, as a younger hobbyist, I made a simple voice recorder. I sampled a microphone using an 8 bit A to D converter. I separately built a playback circuit using an 8 bit D to A converter, an audio amplifier and a speaker. You can build something similar these days much more easily than I did, such as by using an Arduino. You will find that if you implement a software loop to time the recording and playback of samples, you will hear all kinds of strange whines and noise in the recorded stream, especially when interrupts are enabled for doing other things. The strange noise in the recording and playback is the result of sampling and playback jitter when software is responsible for the timing – some samples are inevitably collected or output just a little late or early compared with the previous sample creating a kind of frequency modulation of the sampling rate. The whines you hear are the frequency spectrum of this jitter.

Software polled I/O in a multi-tasking environment will never achieve very high precision. Interrupt driven I/O can get you must higher precision, but it too will fall short of precise timing when the interrupt environment is complex (i.e. the processing of the interrupts themselves becomes jittered as the different interrupts queue). There is only one approach that always works perfectly: Direct Memory Access (DMA) where the hardware itself does the polling and writing, and the job of the software is relegated to configuring the hardware and then standing back to let the hardware autonomously do its recording or playback job.

Writing interrupt or DMA code can be complicated too, but thankfully there is an awesome and sophisticated library available on the Raspberry Pi called ‘pigpio’ (https://abyz.me.uk/rpi/pigpio/). This library contains an extensive set of features to communicate with the Raspberry Pi’s General Purpose I/O (GPIO) pins, including various DMA driven I/O features. It was perfect for this telegraph project as I will explain.

For reading a GPIO input, the pigpio library incudes a DMA method for tracking when an input level change occurs, and counting out (in hardware) the precise time duration between level transitions. The library defaults to a timing accuracy of 10 microseconds (and can be configured more precisely if you need it) and this is way more than sufficient for precisely logging the transition intervals of the string of morse key-presses. Because the pigpio library takes care of precise transition timing, it doesn’t matter when the operating system might get around to scheduling the telegraph emulator software: every edge transition is logged to the nearest 10 microseconds, and when the telegraph emulator is eventually scheduled by the operating system to next execute, it confidently receives a precise record of when those morse-key transitions occurred.

For writing to a GPIO output, the pigpio library supports precisely timed reproduction of the morse key edge transitions. The DMA approach achieves this precision using hardware timers which then trigger the edge transitions out of the morse-sounder output.

The task of the telegraph emulation software is to read the precise duration of each morse key press and key release, transmit the information to the other telegraph stations, and then replay those same key press and key release durations to the remote stations’ morse sounders.

I realised that there’s something else that’s nice about using a Raspberry Pi (and the internet) in lieu of the original overland telegraph network. The Internet is a ‘cloud’ that can inherently support simultaneous communication with many endpoints. Just as a so-called peer to peer network can facilitate data exchange between many peers at the same time, a telegraph session over the internet need not be constrained to just two endpoints. I’ve written this telegraph emulator to support many endpoints in a group session, but of course the programme will also work just fine when used to communicate from just one point to another too.

The interface circuit

A quick look at the interface circuit for the morse key and sounder will show that it is relatively straightforward. Understanding the circuit is easier than it may at first appear. Around half the components I’ve shown are included solely for electrical protection of the Raspberry Pi GPIO pins.

There are five connections to the Raspberry Pi’s GPIO connector: ground and 3.3 volts, one GPIO input and two GPIO outputs.

I have numbered the Raspberry Pi interface pins Jxx where the xx refers to the number of the pin within the 40 (or 26 for the version 1 pi) GPIO header. Beware that the software name of the GPIO pins bears no relationship to the actual hardware pin number.

Each of the GPIO pins is protected by a series 1k resistor (R1-R3) and the GPIO input is additionally protected by diodes (D3 and D4). Although shown as a speaker, the sounding output is capable of driving any DC load up to around 100V, and diode D5 provides some protection in case that the load is inductive. Note that for best protection, it is preferable to position one diode on the Raspberry Pi interface board and a second similar diode directly across the terminals of the sounding device, as physically close to that actual sounding device as feasible.

There are two potential kinds of morse key that can be used: (i) a traditional key-switch (S1), and (ii) a paddle/keyer that generates a sequence of morse dot and dash logic pulses. The keyer input in the interface circuit supports CMOS logic levels at a connector I labelled as J100. If your application doesn’t require a morse keyer input, you may omit R6, R7 and Q2. Conversely, if your application doesn’t require a traditional morse key input, you may omit the RC debounce circuit consisting of R5/C1.

Click on image below for higher resolution.

The sounder output is driven by an N-channel FET Q1. The chosen FET part supports a DC load with a driving voltage anywhere up to a maximum of 100V DC. The FET is driven by either of two GPIO outputs which are diode ORed together using D1 and D2. Resistor R4 keeps the sounder turned off when neither output is active. The purpose of two outputs is so the telegraph software can separate locally keyed morse pulses from remotely received morse. The local keypress sounding can be de-selected as a run time option when launching the software.

If your sounding device draws more than a trivial current, it is advisable to tightly twist the two wires leading to the sounding device in a way similar to the twisted pairs in a cat5 cable. The wire should be twisted from as close to Q1 all the way to the terminals on the sounding device.

Preparing the Raspberry Pi

I have built and tested the telegraph emulator using both 32 and 64 bit Raspbian Bullseye images, on Pi 1, Pi 3, Pi4 and Pi Zero 2W hardware. I expect it will work equally well with an earlier or later version of Raspbian, provided the pigpio library is available.

I won’t go into a lot of detail about how to prepare the SD-MMC card image for the Raspberry Pi because this has been covered ad-infinitum elsewhere on the Internet. I will only say that I am assuming you have:

The first thing to do is to upgrade your operating system and install the required libraries:

sudo bash

apt-get update

apt-get -y upgrade

apt-get -y install raspberrypi-kernel-headers pigpio pigpiod make apache2

Enter the following to enable general access to the GPIO pins:

sudo bash

echo ACTION==\"add\", KERNEL==\"gpio\", MODE=\"0666\" > /etc/udev/rules.d/local.rules

Copy the telegraph tarball onto your Raspberry Pi using your favourite technique: either use a USB stick, or mount a network share and copy the file over the network. When the tarball is accessible on the pi, unpack into the local directory as follows:

tar zxf telegraph.tgz

The tar command will create a subdirectory that contains the source code. You can change into that subdirectory and compile the code and then install it:

cd telegraph

make

make install

make clean

You will see some additional text displayed and the make step will take a minute or so on an older Pi. There should be no errors when running any of the commands above. If you encounter errors, you will need to determine what has gone wrong and resolve the issue. It may be that you didn’t succeed when you attempted to install the necessary pigpio library, or that the C compiler is not installed correctly on your distribution of Raspbian.

At this point (perhaps after rebooting your Raspberry Pi), its all done and ready to go!

Launching the telegraph emulator from a web browser

There are three ways of launching the telegraph station emulator. The easiest is via a web interface which you can either run on your Raspberry Pi itself (if you are using a keyboard/mouse/monitor) or you can run it on a computer/phone/iPad connected to your home LAN.

Assuming all went well with the compile and make install, there will be a web server running on your Raspberry Pi which now has a GUI for controlling the telegraph software. Make sure your computer or phone is connected to the same LAN as the Raspberry Pi, and you can open a web browser to its IP address as shown below.

Click on any of the images below for higher resolution.

Graphical user interface, text, application, email

Description automatically generated

If you don’t know its IP address, you can also got to the text version of the hostname (in my case in this example, it is ‘stefan-pi4.local’ because I called the hostname ‘stefan-pi4’)

Graphical user interface, text, application, email

Description automatically generated

Now that you have the GUI displayed, there are some optional parameters to fill out, and a big green button to click to launch the server.

There is a ‘Peer List’ field into which you can type the names of one or more stations to which you wish to connect. You may enter either their IP addresses, or if a domain name has been set up, the domain name. If you wish to enter more than one station, separate the IP addresses or domain names by spaces, as shown in the example below.

If you don’t enter anything into the Peer List field, the telegraph server will be launched but it will not attempt to connect anywhere. Instead, it will sit there and wait for somebody else to try and connect to it.

Graphical user interface, text, application, email

Description automatically generated

The next field is for this station’s name. By default, it will display the Raspberry Pi HOSTNAME that you entered when running the raspberry-pi imager programme. You can also change the hostname using ‘sudo raspi-config’ from the command line. The purpose of this text entry field is so that you can enter a name that is different than the hostname. This name will be sent to other telegraph emulation stations to identify you.

Graphical user interface, text, application, email

Description automatically generated

The next field is a selection of either of two options: to display morse symbols or to display decoded text. When the telegraph station emulator starts up, it will show you a live screen into which it will display the morse characters you are transmitting or that other stations are sending to you. The selection shown below allows you to choose between showing the morse symbols (dots and dashes) or the text characters that they represent.

Graphical user interface, text, application, email

Description automatically generated

The last field is a choice about whether you would like the telegraph emulator to silence the sounding of the local morse key. If your morse key already has its own sounder, you can check this box and the telegraph emulator will silence output for the local morse key (but will still sound input from other telegraph stations).

After you’ve entered the choices as described above, click on the green button to launch the telegraph server.

Graphical user interface, text, application, email

Description automatically generated

The monitor window will now open, and you will see the outgoing and incoming text from other stations as it arrives.

Graphical user interface, text, application, email

Description automatically generated

At this point, you have two options for sending morse code:

When typing text and getting the programme to send it as morse code, sending rates from between 2 words per minute and 150 words per minute are supported. The programme can probably go faster, but that speed is already faster than human has achieved, and it did not seem right to allow the emulator to exceed this.

Launching the telegraph emulator other ways

A second method for launching the telegraph emulator is via the GUI start menu. You will find a new icon in the start menu under ‘Internet’, however there’s no way to enter any remote station addresses this way, nor to select any of the other options. You are welcome to do your own custom configuration of the launch icon by editing the start-menu icon.

The final method for launching the telegraph station emulator is via the command line. There are more options and help available when you run the command at the terminal prompt:

telegraph -h



Finally, here is a tar ball of the source code, and installation + configuration scripts. You don't need to look at or understand any of the source code in order to use the telegraph station emulator. Just follow the instructions above to install the code onto each Raspberry Pi, and then run!

telegraph.tgz

To those that are interested: the code is structured as a number of independent linux threads. Several threads handle the web interface (which supports multiple simultaneous web connections), several threads handle the transmission and reception of UDP packets. There's a thread that broadcasts the identity of all peer-stations it knows about to all the other peer-stations, so that new stations that join anybody in an existing peer-group are quickly 'learned' by the other participants. There's also a thread that receives morse keypress information, and another that manages the sounding of the local morse buzzer. I added a thread to manage the decoding of the incoming morse stream back to text and to incrementally show the decoded morse stream either on standard output, and to each of the connected web sessions.

I've had the system running with five Raspberry Pis in the peer-group, but it will happily support more if you're keen. I have tried it successfully on a broad range of models of Raspberry Pi except the Pico (which is not supported as it doesn't run Linux - use a Pi-Zero-W varient instead).

I’ve tried to comment the source code to make it easier to follow. If you find any bugs, please let me know how you fixed them. Enjoy!



Contact me

Return to my home page.