An Engineer's Perspective

Tag Archives: SSTV

I read a series of posts (first post is here) on a very interesting blog the other day about transmitting pictures over the radio with Slow Scan Television (SSTV). The blog gives a nice description of the SSTV format which uses a frequency modulated signal to encode line brightness data. This modulation is very easy to implement with the FM modulator described previously, so I decided to implement this transmission scheme across the underwater communications link and see what sort of performance I could achieve.

SSTV Signal Generation

SSTV signal generation is not terribly difficult. The first step is to resize the image to 120 rows. Next the brightness values in each row must be mapped into the correct instantaneous frequency. I did this by normalizing the black and white image to values between 0 and 1, where 1 represented white and 0 represented black. I then interpolated each row to cover the entire transmit line interval. SSTV uses 15 lines per second, this gives each line a duration of 66.67 ms. 5 ms of this time is consumed by the line sync pulse, so each row must be interpolated to cover 61.67 ms at the chosen sampling frequency. Once this interpolation is finished, the values can simply be scaled by 800 and offset by 1500 to produce the desired frequency.

I created one long vector defining the frequency at each moment in time at the desired sampling frequency. This is sufficient for download onto the FPGA, but if you’re interested in forming a wav file you need to perform a few final steps. One, you need to recognize that the instantaneous phase of a sinusoid is equal to the derivative of the phase divided by 2 pi. So to turn the frequency vector into a phase vector, you need to integrate the vector (e.g. perform a cumulative summation), and then multiply this value by 2*pi/sF where sF is the sampling frequency. You can then feed this phase into a sinusoid to get the desired modulation.

I’ve included the Matlab code I used to generate the SSTV wav file in the zip file at the end of the post. If you’d like to try decoding the SSTV signal I used for these experiments you can download the wav file here.

I did not actually download the wav file above to the FPGA, instead I downloaded the frequencies scaled to fit into a 16 bit signed number. I used a modulation scaling of 10 allowing me enough range to implement the needed frequencies.

Signal Decoding

The setup used to transmit the signal was essentially the same as the previous post. I used the SDR to receive and store the IQ signal, and then performed the analysis offline in Matlab.

The signal I received through this setup was very nice. Below you can see a spectrogram from one of the received signals.

You can clearly make out the line sync signal at 1200 Hz and the variable frequency content between those pulses corresponding to the picture amplitude.

I decoded the signal in three steps, first find the vertical sync signal, second, find the horizontal sync signal to isolate each line, three, use a short-time fourier transform to create each line.

I used a matched filter to find the vertical and horizontal sync signals. Since these signals are just pure tones, the matched filter is a sinusoid. The variation between the vertical sync and the horizontal sync is simply the duration. The longer vertical sync pulse means that its maximum output should be larger than the horizontal sync’s output, this can be used to identify it. Below you see the output of the matched filter for a signal containing multiple SSTV transmissions back-to-back.

The vertical pulse sync 30 ms while the horizontal sync lasts only 5 ms, so the matched filter output for the vertical sync should be 6 times larger when it encounters a vertical sync as compared to the horizontal syncs. You can see this difference in the low level signal between the large spikes above. Below shows a close up of the above signal.

The peak of this signal allows the start of the image to be identified. The next step is to find the individual line syncs. We again use the same idea, below you can see the output of the line sync matched filter on the same segment of data as above.

With a close up of the first line sync pulse shown below.

You can see that this matched filter forms a nice peak when matched with the line sync. I used the peak of each of these sync pulses to keep the decoder aligned along each line. I then sliced off the part of the signal between these pulses for the STFT decoding.

I tried out a number of different window and FFT sizes for the decoding. The smaller the window the less frequency resolution you have, but the larger the window the more smearing, so there needs to be a balance. I typically used window sizes around 32 to 64 samples and zero padded the FFT to 512 or 1024. I should note, the blog I mentioned above uses a different method to estimate the instantaneous frequency. For comparison, here is his SSTV wav file decoded using the stft method. My picture transmitted and decoded is shown below.

I was very happy with the overall quality. I actually tried to make things a little more challenging by inserting some air filled cavities and bubbles into the propagation path to disrupt the signal. The figure below shows the received signal during this experiment. Clearly the signal becomes highly attenuated part way through transmission.

Even with this poor signal quality, the overall image turned out fairly nice.

Where the signal amplitude is low, the quality of the image is rather poor, but you can still clearly make out the image.

Overall, I was really impressed by the quality of image that could be transmitted with such a simple scheme and so little bandwidth. I’m really tempted to build a little device I could drop into a lake that would beam back images through a transducer. I have a UART camera, I’d just need to get an inexpensive FPGA (I think there would be a fair chance this would be a one way voyage…) and a lower frequency ultrasound transducer. Now that I think of it, I actually have an old fish finder that I believe operates around 100 KHz. I think I’ll explore a few more data transmission schemes before designing something like this. If I were to make something like this, I’d like to be able to transmit data down to the device so I could perhaps scan the camera, or tell the device to surface, etc… It’s definitely something to think about.

If you’re interested in the Matlab code I used to do the encoding and decoding you can download those files here. They are commented fairly well, so even if you aren’t familiar with Matlab you can probably follow what’s going on. I’ve also upload the received signals, basic SSTV through water at 3.5 MHz, and the disrupted SSTV transmission.