Time-dependent delay in GNU Radio

Since some years ago, a Doppler correction block has been available in gr-satellites. This block uses a text file that defines a time series of frequency versus time, and applies the appropriate frequency shift to each sample by linearly interpolating the frequency corresponding to the time of that particular sample. It can be used both to correct Doppler in a satellite propagation channel and other similar channels, as well as to simulate Doppler.

For some time I have been wanting to implement a similar block that applies a time-dependent delay to a complex baseband signal. The delay versus time would be defined by a text file in the same way as for the Doppler correction block. With this block, the delay of a satellite propagation channel can be simulated. It can also be used to correct the delay-rate of a satellite channel, which causes waveforms to be expanded or compressed in time due to a changing time-of-flight. This effect is known as code Doppler in GNSS, and as symbol frequency offset in general digital communications.

For accurate simulation of a satellite propagation channel, both the Doppler block and the delay block are needed, since the Doppler block accounts for the effects of variable time-of-flight on the RF carrier, and the delay block accounts for the effects on the band-limited modulation of the signal, by delaying its complex baseband representation.

I have now added a Time-dependent Delay block to gr-satellites. In this post I give a few details about its implementation and usage.

Analysis of the CAMRAS Venus radar experiment

On March 22, CAMRAS performed a Venus radar experiment (or Earth-Venus-Earth bounce, as it is more commonly known in Amateur radio) in collaboration with Astropeiler Stockert, the Deep Space Exploration Society, and the Open Research Institute. The experiment was done in L-band, at 1299.5 MHz, using the 25 m Dwingeloo radiotelescope as transmitter and receiver and the Stockert 25 m telescope as a receiver. The experiment was done during the Venus conjunction, as this minimizes the distance between the Earth and Venus. The round-trip time to Venus was approximately 280 seconds. The radar waveform was a CW carrier with a duration of 278 seconds. It was transmitted a total of 4 times every 600 seconds. Thus each period was composed by:

  • 278 second transmission
  • ~2 second TX/RX guard time
  • 278 second echo reception
  • ~42 second wait

More transmissions were planned, including some spread-spectrum signals designed by the Open Research Institute. However, the transmitter started failing and they had to stop.

Update 2025-04-21: I have been informed that the spread-spectrum signal for this experiment was designed by CAMRAS. The waveform that the Open Research Institute is designing will potentially be used in future experiments.

CAMRAS has published an analysis of the recorded IQ data, showing successful echo detections with Dwingeloo and Stockert. There is an example Jupyter notebook that shows how to Doppler correct the echo and detect it with an FFT. All the recorded IQ data has been published.

In this post I will do my own analysis of the experiment. The goal is not to confirm the successful detection with an independent analysis, since I believe that the analysis published by CAMRAS is correct and leaves no doubt about this. It is to expand this analysis and to touch on other topics that this analysis has not covered:

  • Calculation of the Doppler. CAMRAS has published CSV files containing the expected Doppler at each receiver, but they have not published the code to calculate this. Here I will do all the relevant calculations with SPICE.
  • Doppler correction with the gr-satellites Doppler correction block, which performs linear interpolation of the Doppler frequency to calculate the frequency shift applied to each sample.
  • High-quality spectral analysis with a polyphase filterbank.
  • Try to estimate the Doppler spread and compare with some results in the literature.

BGM-1 Doppler during the lunar landing

On Sunday March 2, Firefly Aerospace’s Blue Ghost Mission 1 successfully landed on Mare Crisium, becoming the first NASA CLPS mission to perform a fully successful lunar landing. Congratulations to all the team at Firefly for this huge achievement.

Both AMSAT-DL and CAMRAS covered this event live, by receiving the S-band beacon from the lander with the 20 m antenna in Bochum Observatory and the 25 m Dwingeloo radiotelescope respectively, and streaming the waterfall of the signal in YouTube.

In this post I do a quick analysis of the Doppler of the signal received at Bochum and Dwingeloo. Part of the goal of this is to try to answer a question of Jonathan McDowell, who asked if it was possible to determine the exact second of the touchdown from this data. The answer is that this is probably not possible, since for a soft touchdown there is no significant acceleration at touchdown that can be identified in the Doppler curve.

The raw IQ data recorded by AMSAT-DL is not publicly available. The data recorded by CAMRAS can be found here.

Coding NEON kernels for the Cortex-A53

Some weeks ago, I presented at FOSDEM my work-in-progress high performance SDR runtime qsdr. I showed a hand-written NEON assembly implementation of a kernel that computes \(y[n] = ax[n] + b\), which I used as the basic math block for benchmarks on a Kria KV260 board (which has a quad-core ARM Cortex-A53 at 1.33 GHz). In that talk I glossed over the details of how I implemented this NEON kernel. There are enough tricks and considerations that I could make a full talk just out of explaining how to write this kernel. This will be the topic for this post.

Decoding IEEE 802.11ah

Since some time, I’ve been thinking about doing something similar to my posts about LTE and 5G NR, but for WiFi (IEEE 802.11). In these posts, I take a signal recording and write a Jupyter notebook from scratch to analyze the signal and decode the data. I use these posts as a way of learning all the details of how these standards work, and I have seen that some people find them very useful.

Recently I was taking a look at a baby monitor camera system, composed by a camera and a monitor screen, since I was curious about how the camera transmits the video. Using Maia SDR, I located the signal at 866 MHz and realized that both the camera and the monitor screen were transmitting OFDM packets of approximately 2 MHz of bandwidth on this frequency. With some cyclostationary analysis, I found that the subcarrier spacing was 31.25 kHz (which works out to be 2 MHz / 64 FFT points), and that the cyclic prefix was 1/4 of the useful symbol duration. This pointed me straight to IEEE 802.11ah (WiFi HaLow), a variant of WiFi designed for the 800 MHz and 900 MHz license-exempt bands. After comparing the packet formats on the 802.11ah standard with the waterfall of my recording, I was sure that this was indeed 802.11ah. What started as a fun and short signal recording experiment has ended up going through the rabbit hole of implementing 802.11ah decoding from scratch in a Jupyter notebook. In this post I explain my implementation and the analysis of this recording.

Tianwen-1 second apoapsis raise

Some weeks ago I reported about an apoapsis raise manoeuvre done by Tianwen-1, the Chinese Mars orbiter. This has now happened again. Using state vectors from the telemetry decoded with the 20 m antenna in Bochum observatory by AMSAT-DL, we have detected an apoapsis raise manoeuvre done on 2025-01-08. This new apoapsis raise is much larger than the previous one. I have done the same kind of calculations as in the previous post, and also corrected a bug in my Keplerian elements plots (the periapsis and apoapsis passings were being paired incorrectly, which caused the SMA and eccentricity not to change in the plots I did in the previous post).

Tianwen-1 apoapsis raise

For a long time, AMSAT-DL has been using the 20 meter antenna in Bochum observatory to receive some telemetry from Tianwen-1, the Chinese Mars orbiter, almost daily. Since the telemetry includes the spacecraft’s state vectors, we can use this to monitor the spacecraft’s orbit. In 8 November 2021, Tianwen-1 entered its remote sensing orbit. This is an elliptical orbit with a period approximately 2/7 Mars sidereal days plus 170 seconds. This causes a ground track that is almost repeating, but drifts slowly to cover all the surface area of the planet.

I have been posting yearly updates about Tianwen-1’s orbit, the last of them this summer. In these updates, we can see that no manoeuvres have happened, and the changes in the Keplerian elements correspond to orbital perturbations caused by external forces. The orbit is in fact designed to cause the latitude of the periapsis to precess. In this way, all the surface of Mars can be scanned from low altitude.

Now we have some news. In the telemetry of the last few days we have detected that Tianwen-1 has raised its apoapsis radius from about 14134 km to 14489 km. All the data we have indicates that a propulsive burn has happened recently. In this post I give the details about this apoapsis raise manoeuvre.

5G NR PBCH

This post is a continuation of my series about the 5G NR RAN. In these posts, I’m analyzing a recording of the downlink of an srsRAN gNB in a Jupyter notebook written from scratch. In this post I will show how to decode the PBCH (physical broadcast channel). The PBCH contains the MIB (master information block). It is transmitted in the SSB (synchronization signals / PBCH block). After detecting and measuring the synchronization signals, a UE must decode the PBCH to obtain the MIB, which contains some parameters which are essential to decode other physical downlink channels, including the PDSCH (physical downlink shared channel), which transmits the SIBs (system information blocks).

In my first post in the series, I already demodulated the PBCH. Therefore, in this post I will continue from there and show how to decode the MIB from the PBCH symbols. First I will give a summary of the encoding process. Decoding involves undoing each of these steps. Then I will show in detail how the decoding procedure works.

Published
Categorised as Software Tagged ,

Analysis of DME signals

You might remember that back in July I made a recording of the DME ground-to-air and air-to-ground frequencies for a nearby VOR-DME station. In that post, I performed a preliminary analysis of the recording. I mentioned that I was interested in measuring the delay between the signals received directly from the aircraft and the ground transponder replies, and match these to the aircraft trajectories. This post is focused on that kind of study. I will present a GNU Radio out-of-tree module gr-dme that I have written to detect and measure DME pulses, and show a Jupyter notebook where I match aircraft pulses with their corresponding ground transponder replies and compare the delays to those calculated from the aircraft positions given in ADS-B data.

Not-LoRa GRCon24 CTF challenge

This year I submitted a track of challenges called “Not-LoRa” to the GRCon 2024 Capture The Flag. The idea driving this challenge was to take some analog voice signals and apply chirp spread spectrum modulation to them. Solving the challenge would require the participants to identify the chirp parameters and dechirp the signal. This idea also provided the possibility of hiding weak signals that are below the noise floor until they are dechirped, which is a good way to add harder flags. This blog post is an in-depth explanation of the challenge. I have put the materials for this challenge in this Github repository.

To give participants a context they might already be familiar with, I took the chirp spread spectrum parameters from several common LoRa modulations. These ended up being 125 kHz SF9, SF11 and SF7. LoRa is somewhat popular within the open source SDR community, and often there are LoRa challenges or talks in GRCon. This year was no exception, with a Meshtastic packet in the Signal Identification 7 challenge, and talks about gr-lora_sdr and Meshtastic_SDR.