A few days ago I was doing some refactoring of my galileo-osnma project. This is a Rust library that implements the Galileo OSNMA (open service navigation message authentication) system. The library includes a demo that runs in a Longan nano GD32VF103 RISC-V microcontroller board. The purpose of this demo is to show that this library can run on small microcontrollers. My refactoring was in principle a simple thing: I was mainly organizing the repository as a Cargo workspace, and unifying the library and some supporting tools into the same crate. However, after the refactor, users reported that the Longan nano software was broken. It would hang after processing some messages. This post is a collection of notes about how I investigated the issue, which turned out to be related to stack usage.
Author: destevez
First analysis of the Lunar GNSS Receiver Experiment data
The Lunar GNSS Receiver Experiment (LuGRE) is a NASA and Italian Space Agency payload that flew in the Firefly Blue Ghost Mission 1 lunar lander. An overview of this experiment can be found in this presentation. The payload contains a Qascom GPS/Galileo L1 + L5 receiver capable of both real time positioning and raw IQ recording, and a 16 dBi high-gain antenna that was pointed towards Earth. For decades the GNSS community has been talking about using GNSS in the lunar environment, and LuGRE has been the first payload to actually demonstrate this concept.
The LuGRE payload ran a total of 25 times over the Blue Ghost mission duration, starting with a commissioning run on 2025-01-15 a few hours after launch and ending with a series of 9 runs on the lunar surface between 2025-01-03 (the day after the lunar landing) and 2025-01-16 (end of mission after lunar sunset). Back in October 15, the experiment data was published in Zenodo in the dataset Lunar GNSS Receiver Experiment (LuGRE) Mission Data. This dataset includes some short raw IQ recordings, as well as output from the real time GNSS receiver (raw observables, PVT, ephemeris and acquisition data). Since I have some professional background implementing high-sensitivity GNSS acquisition algorithms and I find this experiment quite interesting, I decided to do some data analysis, mainly of the raw IQ data.
The initial results of the experiment were presented on September 11 in the ION GNSS+ 2025 conference in a talk titled Initial Results of the Lunar GNSS Receiver Experiment (LuGRE). This talk is only available to registered ION attendees. As I don’t want to resort to my network to scrounge some ION paper credits (which is how proceedings are usually downloaded from the ION website), I haven’t seen anything about this talk besides the abstract. It is quite possible that something of what I will mention here was already presented in this talk. This is what we get as a society for not doing science in a completely public and open way. However, it’s interesting that this also makes my analysis less likely to be biased. I’ve just downloaded some raw IQ data and started looking at it with only basic context about the instrument that produced it and how it was run.
For a first analysis, I have implemented a high-sensitivity acquisition algorithm for the GPS L1 C/A signal in CUDA. I have run this on all the 20 L1 IQ recordings that are available. In this post I present the algorithm and the results.
Decoding ESCAPADE
ESCAPADE is a twin spacecraft mission that will study the Mars magnetosphere. The science mission is led by UC Berkeley Space Sciences Laboratory and the spacecraft buses were built by Rocket Lab. It was launched on November 13 on the second Blue Origin New Glenn mission NG-2. The spacecraft will spend a year around the Earth-Sun L2 Lagrange point before falling back to Earth for a powered gravity assist that will place them on Hohmann transfer orbit to Mars as the “launch window” to Mars opens. These are the first spacecraft to fly this kind of trajectory.
The day after launch, I used two antennas from the Allen Telescope Array to record the X-band telemetry signals of the two spacecraft, which were approximately 200 thousand km away from Earth. In this post I will show the results of this observation, and how to decode the telemetry. I have published the recording in the dataset “Recording of ESCAPADE X-band telemetry with the Allen Telescope Array shortly after launch” in Zenodo.
sigmf-toolkit
I have published a new Python package called sigmf-toolkit. It is intended to be a collection of Python tools to work with SigMF files. At the moment it only contains two tools, but I plan on adding more tools to this package as the needs arise. These tools are:
gr_meta_to_sigmf. It converts a GNU Radio metadata file with detached headers to a SigMF file. At the moment it is really simple, and it doesn’t handle capture discontinuities.- sigmf_pcap_annotate. This tool parses a PCAP file using Scapy and it adds annotations to a SigMF file for each packet in the PCAP file.
I find this sigmf_pcap_annotate tool quite useful when comparing side by side a SigMF file in Inspectrum and a PCAP file in Wireshark to debug issues with digital communications systems. In this post I showcase how this tool can be used.
Non-coherent m-FSK BER
Yesterday I posted about how to compute the well known formula for the bit error rate of FSK with non-coherent demodulation. Later I realized that the same kind of argument can be extended to cover the case of \(m\)-FSK in which the \(m\) tones are orthogonal. The formula for this is not so well known, and I don’t recall having seen it before, although surely it is somewhere in the literature. Here I show the calculations and the closed-form expression that is obtained.
Non-coherent FSK BER
It is well known that the formula for the bit error rate of 2-FSK using non-coherent demodulation is \(\exp(-\frac{E_b}{2N_0})/2\). However, I can never quickly find a source where this formula is derived, so I decided to figure this out and write down the derivation. I will use my post about m-FSK symbol error rate as a starting point.
10 years of blogging
Today marks 10 years since I wrote the first post in this blog. It was a very basic and brief post about me decoding the European FreeDV net over a WebSDR. I mainly wrote it as a way of getting the ball rolling when I decided to start a blog back in October 2015. Over the 10 years that I have been blogging, the style, topics, length and depth of the posts have kept shifting gradually. This is no surprise, because the contents of this blog are a reflection of my interests and the work I am doing that I can share freely (usually open source work).
Since I started the blog, I have tried to publish at least one post every month, and I have managed. Sometimes I have forced myself to write something just to be up to the mark, but more often than not the posts have been something I really wanted to write down and release to the world regardless of a monthly tally. I plan to continue blogging in the same way, and no doubt that the contents will keep evolving over time, as we all evolve as persons during our lifetime. Who knows what the future will bring.
I wanted to celebrate this occasion by making a summary of the highlights throughout these 10 years. I have written 534 posts, and although Google search is often useful at finding things, for new readers that arrive to this blog it might be difficult to get a good idea of what kind of content can be found here. This summary will be useful to expose old content that can be of interest, as well as serve me to reflect on what I have been writing about.
Flip-flop timing experiments
Since watching Matt Venn‘s video about flip-flop timing, I have had at the back of my mind the idea of designing my own ASIC flip-flop and doing some simulations to measure its timing parameters. This is partly an excuse to learn how to use Magic and other VLSI design tools, and partly a good way to understand better how the numbers that appear on a flip-flop datasheet relate to what physically happens in the flip-flop.
I have now designed a flip-flop in Magic and done ngspice simulations to measure its setup, hold and output delay times. This work can be found in a flip-flop-timing repository in Github. In this post I explain how the flip-flop is designed and how the timing analysis is done.
10 GHz FMCW radar LO board
In February this year I was in the Spanish amateur microwave radio conference Micromeet 2025. In this conference, Luis Cupido CT1DMK presented a simple and inexpensive 10 GHz transverter that he called Nes-Transverter, with the motto “Instant microwaves. Just add solder”. The main idea of this design is that it is very simple and can be built by anyone with just a handful of inexpensive components. Luis was hoping that this project would help more people get on the 10 GHz band in a hands-on way, and he also wanted to demystify some ideas such as amateur microwave radio being difficult or expensive.
The schematic for this design is available here. It uses a 144 MHz IF, allowing it to be connected to a VHF amateur radio. An ADF4351 synthesizer, to be sourced from an inexpensive AliExpress dev board, generates a 2.556 GHz LO with complementary outputs. These two outputs are used in a frequency doubler built with two BAT15 diodes to produce a 5.112 GHz LO, which is filtered with a transmission line stub and amplified with an MMIC such as the ERA 3+. A harmonic x2 mixer built with two BAT15 diodes directly connected to the waveguide probe uses the 5.112 GHZ LO and the 144 MHz IF to produce 10.368 GHz, which is the usual frequency for terrestrial narrowband communications in the 10 GHz amateur band.
I was very interested by this talk, and thought that it would be fun to play with this project, since I haven’t done any hands-on electronics projects in quite a while. However, rather that building a transverter for narrowband communications, I decided to adapt the ideas to build a 10 GHz FMCW radar. I wanted to build a cheaper version of the ADALM-PHASER, minus the phased array part. The Phaser is an educational development kit from ADI that demonstrates concepts in phased array beamforming and FMCW radar. It uses an ADF4159 waveform generator synthesizer and a HMC735 VCO as a 12.2-12.7 GHz LO source that can be programmed to generate FMCW waveforms such as a linear sawtooth and triangle chirps. An ADALM-PLUTO or another SDR is used as a 2.2 GHz IF to obtain 10-10.5 GHz via high-side LO injection. On the transmit section, the 10-10.5 GHz signal is sent to an SMA connector to drive an external antenna. On the receive section, a 4×8 phased array of patches is included in the PCB. Each column of 4 patches is phased as a single element by connecting them together on the PCB. The 8 columns are beamformed in groups of 4 with two ADAR1000, which allows choosing independent complex coefficients for each column. Each of the 4-column beamformer outputs is connected to an RX channel of a 2-channel SDR, so that the final beamforming step can happen in software (see here for a block diagram of the Phaser).
The first thing I needed to replace in Luis design to convert it to an FMCW radar was the LO source. Since I will be using an SDR rather than a VHF radio as the IF, I could use an LO of around 4-4.5 GHz, which would give me around 10-10.5 GHz with an IF around 1-2 GHz. This meant that I could use the ADF4158 synthesizer as the LO source. This is the cheaper variant of the ADF4159, and it only goes up to 6.1 GHz instead of 13 GHz, which is fine for my use case. I needed a VCO to go together with the synthesizer, and after some looking around I decided to use another ADI part, the HMC319, which is a 3.9-4.45 GHz VCO. An IF of 1.6 GHz covers 10-10.5 GHz with an LO of 4.2-4.45 GHz, which is quite appropriate for this VCO choice.
I designed a small PCB with an ADF4158 and HMC391, which I now have built and tested. In this post I explain some of the aspects of the board design and the results of the initial tests.

Multispectral analysis of the Tres Cantos wildfire with Sentinel-2 data
A few days ago, I posted about a recent wildfire in Tres Cantos, Madrid, Spain, sharing images of Pléiades Neo and Sentinel-2 that showed the extent of the fire. Since the Sentinel-2 data products can be downloaded for free and they include multispectral data covering 13 bands including visible, near infrared and short wave infrared spectrum, I have decided to do an analysis of this data. There are two main goals to this. The first is to learn. I have never done this before. It is an interesting topic, and I mostly learn by doing. So bare with me that although all my results seem to make sense, I could have made some mistakes or done something in a suboptimal way.
The second is to understand how badly the holm oak woodland in “Monte de Viñuelas” has been burnt. In the previous post I explained that this is a 30 km² estate and that a large part of it has been hit by the fire. From the wall that borders the estate I can see that the oaks that are near the wall have not burnt, but the grass in the ground has burnt completely. The leaves on these oaks are mostly fine. Some of them might wither with time if the fire has killed the tree (in some previous smaller fires I have seen that if the fire has killed only part of the tree, just that part will wither). Here are some images published by a hunting journal showing how some of these areas look like a few days after the fire.
However, deeper into the woodlands there seems to be more damage and trees burnt completely. This is not so easy to see from the wall, and I cannot just walk in, as it is private land. Aerial photography would be best, but without it, satellite imagery is the next best thing. It is hard to tell how large the damage is from the visible spectrum imagery, but as we will see in this post, the infrared bands have much more information.