← NOTES

LOG-005 ·

Building a TETRA Scanner with an RTL-SDR

With a recently acquired interest in RF, I bought an RTL-SDR and built RF Drive with Codex: a working scanner that detected TETRA radio activity.

TETRA and software-defined radio

TETRA stands for Terrestrial Trunked Radio. It's a digital radio standard used by emergency services and other organisations. ETSI's overview explains the system and who uses it.

The idea came from the commercial product Blu Eye. It detects active TETRA/Airwave communication, which can give a warning before a vehicle is visible. Detecting the radio activity itself caught my attention and gave me something to experiment with using the receiver I already had.

An SDR, or software-defined radio, lets a computer do much of the signal processing that would traditionally happen in dedicated radio hardware. The receiver supplies samples of the radio signal, and software decides what to do with them. The RTL-SDR introduction was a useful starting point.

The setup

I used an RTL-SDR Blog V4 connected to my laptop, with a V dipole antenna suction-mounted at the top of the car's windscreen. Each arm was about 17 cm long, with the V facing sideways towards the doors. A separate USB GPS receiver could add the car's location to the recordings when it had a fix. This helped put detections in context while testing reception.

The laptop ran RF Drive. The signal went from the antenna into the SDR, then over USB to the software for analysis. When it found a matching burst, it updated the display, logged the result and could sound an alert.

The receiver scanned sections of the 380–385 MHz band in turn because of a hardware limitation: the RTL-SDR can't receive that entire 5 MHz span at once. At the sample rate I used, it captured roughly 2.4 MHz at a time, so I had to retune it between overlapping sections. While it listened to one section, it could miss a short transmission elsewhere. Making good use of its receiving time became an important part of the project.

Building RF Drive

I built the program with Codex so I had something practical to test with: a live spectrum, a large signal-strength display, audio controls and recordings I could review afterwards.

RF Drive replaying recorded TETRA activity, with a signal-strength display, spectrum, receiver information and audio controls.
RF Drive reconstructed from a saved road-test recording. This is a recorded-data replay, with audio off. The large percentage is a relative signal-strength display that fades between matches.
View full size

The spectrum shows the radio activity reaching the receiver. The main display responds to bursts that pass the TETRA pattern checks, so a large peak in the spectrum doesn't automatically trigger an alert. The receiver information also helped me check whether a quiet period meant no accepted activity or a problem collecting data.

Getting to that point took a few changes. The early version mostly looked for signals standing out above the background. That showed activity, but a strong signal alone wasn't enough to establish what it was.

TETRA radios can send short bursts of network signalling even when nobody is speaking. Blu Eye describes recurring network check-ins as periodic registration in its user manual. Transmissions from a radio towards a base station are called the uplink; the other direction is the downlink. RF Drive only listened for uplink activity.

That made short bursts a useful thing to look for. I checked their shape and length, how the signal's phase changed, and whether they contained the expected training patterns. These are known sequences that help a receiver recognise and synchronise with a transmission. Combining those checks gave me much better evidence of TETRA activity than simply watching for a spike. I recognised the burst format without decoding what each message was for.

Measured radio-power profiles showing a sequence of short bursts at regular intervals.
Measured power profiles from one recording. The bursts last roughly 13 milliseconds and repeat at about 56.7-millisecond intervals. Blue bursts passed the normal detector; the orange burst was logged by a weaker-signal comparison that stayed silent.
View full size

Another problem was repeated beeping from the same evidence. I changed the alert logic so a fresh qualifying result could request an alert without repeatedly sounding for an old one.

There was also time being lost while the computer analysed each capture. I changed the program so it could collect the next set of samples while processing the previous one. In the recorded runs I compared, usable observation time went from roughly 40 seconds to 50 seconds per minute. That meant spending more time receiving rather than waiting for the software to catch up.

Taking it out on the road

The interesting part was comparing the recordings with what I actually saw. I tested it on several drives and noted encounters so I could go back through the signal measurements afterwards.

On 21 September, I heard strong alerts before seeing an emergency vehicle with its lights and siren on, around 18:52. The recording showed 21 matching bursts on one frequency between 18:51:32 and 18:52:33. I hadn't noted the exact second I first saw the vehicle, but it was an encouraging example of hearing the alert before seeing what was coming.

Recorded TETRA bursts around the reported emergency-vehicle encounter on 21 September.
The emergency-vehicle encounter, with the approximate sighting time marked. Each point is a matching radio burst; the dashed line isn't an exact first-sighting timestamp.
View full size

On 22 September, I compared the times I saw vehicles or they passed me with the recorded signal activity:

Vehicle sighting / time Recorded signal activity
Vehicle seen at 13:52:18 32 matching bursts in the preceding two minutes, with activity before and after the sighting.
Vehicle seen at 13:53:16; passed at 13:53:30 Matching activity at 13:53:08–12, then further matches around the pass.
Vehicle approaching at 13:55:00; alongside at 13:55:22 Matches before and after the close pass, with a gap between 13:55:12 and 13:55:43.
Vehicle passed at 13:59:31 Three matching bursts at about 13:59:26, roughly five seconds before the pass.
Recorded activity around several emergency vehicle sightings, including a close pass and a petrol-station stop.
More emergency vehicle sightings from 22 September. The markers show my observations and the dots show recorded bursts. The lower panel also shows the test beside a parked emergency vehicle: strong activity, a quiet interval, then activity returning around the approximate departure time.
View full size

That gave me several real encounters to compare with the recordings. It also showed how reception could come and go even with a vehicle nearby, which was useful when working out what the detector was doing.

Later on 22 September, one of the clearest examples was an emergency vehicle I first saw at 14:22:03. The software had a matching result available at about 14:21:48, roughly 15 seconds earlier. There was stronger reception on the same frequency shortly before the vehicle came alongside.

Later in that drive, I heard a beep and an emergency vehicle appeared around a corner. The sighting was noted at 14:30:52, with matching results available at about 14:30:48.5, roughly 3.5 seconds before it came into view.

Road-test timeline comparing recorded burst strength with reported emergency vehicle sightings.
Recorded activity from the afternoon drive. The top two panels show the emergency vehicle encounters; blue dots are normal detector matches and orange crosses are silent comparison results. The times compare software results with my sighting notes, rather than measuring when the speaker sounded.
View full size

Those were useful examples of the warning I was hoping to get. The recordings let me check the timing afterwards, rather than relying only on remembering a beep. They show activity lining up with vehicles I actually saw, although the software didn't identify those vehicles as the transmitters.

It wasn't consistent on every pass. There were also quiet gaps with an emergency vehicle nearby, and activity when I couldn't see an obvious source. That was part of testing it: a radio needs to transmit while the receiver is listening, and the signal still has to reach the antenna clearly enough to pass the checks.

Where I left it

I see this as a completed, working POC. It picked up TETRA burst patterns and gave me useful warning during the vast majority of the encounters I tested. It wasn't perfect, but I was using inexpensive hardware and a simple antenna setup to explore what was possible.

The project did what I wanted it to do: I got to experiment with RF, build my own detector and see real signals turn into something useful on screen. That was a pretty interesting result from buying a USB receiver and wondering what I could do with it.