|Figure 1: |
The "Grey" waterfall mode of the mcHF self-contained SDR transceiver
in "Magnify" mode which shows only 24 kHz total bandwidth.
Three - possibly four SSB QSOs are visible in this picture.
It seems that all "good" SDR rigs have them these days - so why not this one? When I first started working with the mcHF and contemplated this question, "there's plenty of processor horsepower for this... I think..."
Actually, it was more complicated than that.
Two types of LCDs and interfaces:
There are two "flavors" of the mcHF: The early units used LCDs with "SPI" (high speed Serial) interfaces while the current crop (and by far the majority) use a parallel interface that physically maps the display's RAM to the processor's I/O controller so that it sees it as RAM - plus, it can access the display's normal commands with 16 bit-wide parallel data - either method being orders of magnitude faster than the SPI.
Now, as new features are developed for the mcHF, it is strongly desired that they all be compatible with both the SPI and Parallel version. To that end Chris, M0NKA kindly send me an older "Rev 0.2" UI board with an SPI interface-type LCD so that I could spend some time improving the SPI-based routines that work with the display - plus it gave an opportunity to test both types prior to releasing software to make sure that I'd not "broken" anything on one or the other version of hardware.
Fortunately, after a bit of studying of the data sheets for the LCD unit I was able to discern that there was a hitherto un-utilized hardware feature that allowed bulk-writing to a defined area of display RAM and with this - and a few other tweaks - was able to speed the "user experience" of those with SPI interface mcHF transceivers by a factor of 4-10 or so, depending on what they were doing. To be sure, the display updates on SPI-interface radios are still significantly slower than the Parallel-interface radios, but the former are very usable.
Rewriting the "Spectrum Scope":
So, I completely scrapped the Spectrum Scope function save for the original RFFT written by Chris, the somewhat hairy and efficient display functions originally written by Chris and hacked on by me (this is open-source!) and I kept my IIR low-pass filter which seemed to be just fine.
When I was done I had a "proper" spectrum scope with the vertical scale adjustable from 5dB/division to 20dB/division and even 1, 2 and 3 S-Units/Division (because I could...). There was even an AGC function so that the strongest signal was adjusted to be at the top of the scope, but at the same time it would detect the peak/average of the signals on the scope and prevent an "empty" span from rising up and simply filling the display full of noise!
Not wanting to stop there, I put some thought into the waterfall display.
Adding a "Waterfall" display:
The waterfall display is the same as the spectrum scope, except that it adds the dimension of time: While the frequency is represented horizontally along the "X" axis as with the spectrum scope, with a waterfall display the strength of the signal is represented by the color or intensity of what is on the display rather than the height. The newest signal is "painted" along the bottom of the display and when the next scan is complete, the "old" information is scrolled upwards and the new information takes its place. In this way, one has a brief history of signals - both on and nearby the center frequency.
There was a problem: How do I do this without taking up massive amounts of processor power and/or memory?
As it turns out, all I really needed to store at any given time was the magnitudes and signals in the passband. In "normal size" mode, the waterfall display is 70 pixels high and since it used a 512 point FFT (sort of...) I had 256 frequency bins, so I represented 48 kHz of bandwidth with 256 pixels horizontally with each pixel representing 187.5 Hz, nominally. (Note: It really doesn't work that way - read about FFT and windowing if you are interested...) If all I wanted to do was store that information, I needed only 17920 bytes of storage since all I was actually storing was the same sort of data that the Spectrum Scope produced: A signal that went from 0 for the weakest signal to 63 for the strongest - which would fit in a byte! Making this a circular buffer with a pointer for each line, I could easily keep track of where I was in "time".
For the color palette I did the obvious: A 65 entry RGB palette that matched that 0-63 amplitude range: That extra color? I'll get to that in a moment...
The LCD actually uses a 16 bit RGB (5,6,5) color scheme, so it was easy to make another array into which I could simply load my color palette of choice.
Updating the display:
Updating the display was the slightly tricky bit.
Remembering that I'd implemented some "block write" functions when optimizing the SPI interface functions, I wrote some additional, minimalist functions to perform the needed tasks: One to set up the area on the screen for the block write, another to accept data and another to "close" the block write and return the LCD to "normal" operation.
To display the waterfall, one simply defines the area of the screen defining the extent of the waterfall, enables the "write" command and then blindly throws the exact number of bytes of 16 bit RGB data at it constituting the size of the waterfall display. It was a simple matter to use the stored amplitude data from the 17920 byte circular buffer to index the color palette and send that data to the LCD - I just had to make absolutely sure that I sent exactly the amount of data that conformed to the expected column and row sizes.
Since this was a "blind" write to the LCD it took an absolute minimum of I/O and even on an SPI interface LCD - while significantly slower than on a Parallel-interface LCD - it is still very usable! Better yet, it doesn't take oodles, gobs and tons of processor power
It does take more processor power to update the display than does the spectrum scope, particularly if one has it set to its highest speed, but in actual use one would have it set so that it would take 10-20 seconds for a signal to disappear from the display, and that really doesn't load the processor too much. (Audio processing always takes precedence, so if one turns on all of the DSP modes with the waterfall set to its fastest mode, you will see it slow down significantly!)
About that "65th" color? If you look carefully at Figure 3, above, you'll note a blue (cyan, actually) vertical line aligned with the "7035" graticule on the bottom of the screen: It's used for that!
In Figures 1 and 3 the waterfall is shown in the "Magnify" mode in which only 24 kHz is actually being displayed instead of the possible 48 kHz (I need to add a picture to show this...) and there is also a mode of the waterfall display that takes up more of the screen, covering the word "Waterfall Display". There is also a "HotCold" palette in which weak signals are blue and strong are red - and it would be an easy matter to add even more palettes - if someone wants to go through and derive all 64 colors.
There are even more tweaks/additions that will no doubt be made
Note: As of version 0.0.219.18, eight types of FFT windowing are available! - For more information about this read the article on Wikipedia about Window Functions. If one chooses the appropriate window function the waterfall display and spectrum scope's response to signals is much "tighter" as spillover energy from one "bin" on the screen can be minimized.