December 02, 2015

Reading Lecroy Binary Waveform in Python

I needed to read Lecroy binary waveforms files recently, and the one python script I had found didn't read them properly due to improper handling of 16 bit samples.

I wrote an alternative lecroy.py that should be a drop-in replacement. It  handles 16 bit waveforms and exports a LecroyBinaryWaveform class that also provides additional metadata. It supports saving to CSV for binary to text conversion.

October 05, 2015

On the Use of I/Q Signals


  • All signals are complex, that is they have the form of $$x(t)=A\exp(i\omega t)$$. I/Q presentation of a signal fully captures this by storing the real component in the I, the in-phase signal, and the complex component in Q, the quadrature signal.
  • When we force signals to be purely real, e.g. $\cos(\omega t)$, we taking the real part of $exp(i\omega t)$. Because we ignore the imaginary component, we lose information. Specifically, $\cos(\omega t)$ can be the real part of $\exp(i\omega t)$ or $\exp(-i\omega t)$. We don't know any more.
  • This ambiguity is present in the exponential form of $\cos$: $$\cos(\omega t) = \frac{\exp(i \omega t) + \exp(-i\omega t)}{2}$$. Note the presence of the two complex signals whose sum is always purely real as their imaginary parts cancel out. The real part of either complex signal will produce $\cos(\omega t)$.
  • This ambiguity is why when you multiply $\cos(\omega_0 t)$ and $\cos(\omega_1 t)$ you end up with $\cos[(\omega_0 + \omega_1)t]$ and $\cos[(\omega_0 - \omega_1)t]$. In other words, the frequency add as $\pm \omega_0 \pm \omega_1$, which produces 4 unique combinations that reduces to 2 because $\cos$ is even.
    • The result of multiplying real cosines produces two peaks in the frequency spectrum.
  • On the other hand, preserving the complex nature of a signal by presenting it as $A\exp(i\omega t)$ means that multiplying two signals together produces a unique result: $$A_0\exp(i\omega_0 t) \times A_1\exp(i\omega_1 t) = A_0A_1\exp[i(\omega_0 + \omega_1)t]$$. This is because there is no ambiguity as we have not thrown away any information.
    • The result of multiplying complex signals produces one peak in the frequency spectrum.
  • This is one of the advantages of working with I/Q data, which preserves the complex nature of signals, and allows us to frequency shift a signal through multiplication without also generating an additional unwanted image of the signal.
Cheers,
Steve

October 04, 2015

Simple FM Receiver with GNU Radio and RTL-SDR

Introduction


I recently started playing around with software defined radio using a USB TV tuner dongle utilising the popular RTL2832U chipset. After playing around with software like CubicSDR and gqrx I was somewhat frustrated at the opaqueness of what is going on under the hood. As such I resolved to learn GNU Radio so I can do the signal processing myself. Starting with a basic FM receiver seems like a good idea, since one of my goals is to receive NOAA APT transmissions, which are FM modulated at 137 MHz.

The Radio


The image below is the FM radio (source code) I built in GNU Radio Companion. GNU Radio Companion is part of GNU Radio that makes it pretty easy to graphically put together a custom signal processing chain and "make" a radio in software. I am not usually a big fan of graphical programming, but in this particular instance I have to admit the going was a lot easier than if I had to do this textually. There is built in support for documenting each block, which is nice, though I wish I had more control over the font used and the size of the text boxes.

FM radio created in GNU Radio Companion.

It looks more complicated than it is. Basically, the output from the receiver, which is centred around the central frequency, is down-sampled from 2.4 MHz to 500 KHz, then low-pass filtered and then passed to a FM demodulator module. The output of the FM demodulator is then resampled to 48 KHz and piped to an audio sink, i.e. a sound card.

All the extra stuff is are GUI controls and visualisations to aid in understanding and debugging.

This is what it looks like running, tuned a local station at 99.1 MHz, which is BBC Radio 1.

Radio in operation. Top-left: FFT of the signal from the receiver; Top-right: resampled signal; Bottom: Low-pass filtered signal.
There is some rudimentary control over GUI position and size, but it is otherwise brutally utilitarian. However the resulting python file can be modified to fine tune appearances and such I believe. Nonetheless, it is very useful for figuring out where you went wrong.

Next Step

The current goal is to make a NOAA APT specific radio and keep trying for a clean image.

Cheers,
Steve

May 04, 2015

Porting Seeeduino Xadow to Arduino 1.6.3

I bought a Seeedstudio Xadow recently, and to get it to work with Arduino 1.6.3 was bit of a pain. Long story short, you can find the necessary files along with pithy instructions at my github repo.

The most crucial difference between the files Seeedstudio supplied and what is needed is that when referencing the core and variant, you must specify the vendor ID, or Arduino 1.6.3 will assume that you have custom source files in the vendor directory. In other words, instead of

Xadow.core=arduino

You must write

Xadow.core=arduino:arduino

This bit of information, along with others, is documented on arduino's github wiki, in particular Referencing another core, variant or tool.

Cheers,
Steve