Lord777
Professional
- Messages
- 2,577
- Reaction score
- 1,556
- Points
- 113
The content of the article
- Simple SDR
- Synthesizer
- Assembling the receiver
- We include
- Software
- Bonus
SDR (Software Defined Radio) is a software-defined radio system where software converts the radio signal into digital form. This opens up the broadest possibilities for signal analysis. The advent of more and more affordable SDR systems has become a wonderful gift for radio amateurs. In this article, we'll go over how SDR works, the most reliable method is to create your own receiver. And at the same time we will try not to drown in the abyss of matanalysis.
One of the most popular SDRs today is the Chinese "whistle" RTL-SDR, we have written about it many times (you can see, for example, the article "Taking the first steps with RTL-SDR"). It has fantastic features for its price.
The RTL2832 + RT820 circuit looks like this.
The signal enters the input of the radio path, implemented on the RT820, where the first frequency conversion to the intermediate frequency is performed, here 3.57 MHz. The specular channel is suppressed by the filters as much as possible.
This solution allows you to cover a huge frequency range from several tens of megahertz to a couple of gigahertz. Not all at once, of course, but only in pieces of several megahertz (judging by the documentation, the RTL2832 is also capable of digitizing a signal with a frequency of several tens of megahertz, but it rests on the USB bandwidth). In fact, this is often enough.
The received IF signal is digitized in RTL2832, after which it is subjected to a second software frequency conversion. Here, a quadrature local oscillator is already used, implemented in software as the dot product of the input signal to the reference signal. And in the case of a quadrature local oscillator, two signals with the same frequency, but phase-shifted by π / 2, are used as references. At the output of the mixers, there are low-pass filters that filter the signal with twice the reference frequency. As a result, we also have two signals at the output: in-phase (I) and quadrature (Q). However, the names are to some extent arbitrary.
Signals are streamed over USB. Actually, resampling takes place before sending, when the transfer rate drops to about 2 MS / s, in this scheme this is a "bottleneck". Why Quadrature LO? From the theory of digital signal processing, it is known that with only I and Q signals, you can decode a signal with any of the existing modulation methods. For example, AM modulation, which we will focus on below, is the easiest to implement.
If we imagine that I is the real part, and Q is the imaginary part of the complex signal Z, then |Z| = (I^2 + Q^2)^1/2there is the desired demodulated signal. With the World Cup and FM it will already be more difficult, but not fundamentally. However, the theory of digital signal processing is too difficult to retell it in a nutshell - if you wish, you can read in more detail yourself.
Further, the signal is processed by the computer, where a complex sample is formed from separate I and Q samples Z = I + jQ. However, as you understand, this is also a certain convention that allows using the mathematical apparatus of complex calculus to a signal.
Essentially all of this is done by software packages such as SDR # (Windows), Gqrx (Linux), or GNU radio (Linux). The latter is the most interesting to us, since it allows us not only to go over the range, but also to understand how the software part is implemented inside. And at the same time, you do not need to get into the programming jungle, but you can use the mouse to compose a structural diagram (graph) from separate blocks. Blocks usually implement one operation (in the best Unix tradition). This is how the simplest FM receiver on RTL-SDR looks like in GNU Radio, created in a couple of minutes.
The simplest example
RTL-SDR acts as a source producing a stream of complex Z-values, which is equivalent to both I and Q streams. Then the signal goes to a digital low-pass filter, LPF, which cuts out the band of interest. Since in this case frequency modulation is expected, we need a bandwidth of ~ 200 kHz, centered at zero, which corresponds to the frequency set on the RTL-SDR. Then the signal goes to a frequency detector, at the output of which a real sound signal is obtained, suitable for a sound card. A resampler is needed to match the bitrate of the signal. Total - half of the receiver in just a few clicks!
Simple SDR
In the past, SDR receivers, which used a computer sound card as an ADC, were relatively popular. Most had a similar design and consisted of a reference oscillator, phase shifter, mixer and low frequency amplifier. The amplifier output was connected to the line input of the sound card. Do you feel the analogy with the RTL2832 discussed above? The essence is the same, only the intermediate frequency is lower here and the quadrature signal is already digitized.
Consider the diagram of the popular ZetaSDR receiver.
ZetaSDR scheme
The signal from the clock generator with frequency F goes to the phase shifter, performed on two D-flip-flops connected to a Jenson counter. That is a shift register , the last inverted output of which is fed to the input. When a clock signal is applied, a wave of zeros and ones will propagate through the outputs of the shift register. In our case, the states 00, 01, 11, 10 will be sequentially set at the outputs Q0 and Q1, which in the decimal system corresponds to 0, 1, 3, 2.From the point of view of signals, these are two square waves of frequency F / 4, phase-shifted by 90 degrees.
Jenson counter signal diagram
The resulting reference signals are then fed to Dan Tayloe's key mixer, which is based on a 74HC4052 multiplexer. The mixer multiplies one signal by another, so if one of the signals is a square wave, then the multiplication is reduced to a simple switch.
How the Teilo mixer works
The picture below shows a diagram of the multiplexer operation, where the switched on channel conditionally corresponds to a high level on it.
Multiplexer operation
Taking channel X0 as 0 °, we see that 90 ° is X1, 180 ° is X3, and 270 ° is X4. The operational amplifiers are connected accordingly. As a result, we get the I and Q signals at the output, offset by 90 °. You can read more about the Teilo mixer in the original article. Then the signals are sent to the line-in of the audio card.
Synthesizer
The ZetaSDR uses a non-tunable oscillator, which gives the receive bandwidth equal to the bandwidth of the audio card around F / 4. I think you will agree that this is not very much, since any audio card rarely has a bandwidth of more than 200 kHz. On the other hand, ZetaSDR was designed as an observer's receiver, and there the 200 kHz band covers the entire amateur band by 40 m. But we want to cover several HF bands! In addition, over the past ten years it has become much easier with synthesizers.
Therefore, we will use the SI5351 microcircuit, which is a frequency synthesizer with a digital interface, capable of capturing multiple signals with a frequency of 8 kHz to 160 MHz. At the same time, only quartz and two pull-up resistors for I2C are required from the harness - everything as you like. For very lazy people in Chinese online stores, sellers offer completely assembled modules on this microcircuit, which is very convenient for prototyping.
As a microcontroller, I took STM32F103C8T6, which is very popular today among radio amateurs thanks to the Bluepill board. We assemble the breadboard on Bluepill and the SI5351 module, and use an I2C OLED display and an encoder as interfaces. The result is such a scheme.
To control the SI5351, I used the STM32-SI5351 library, which is a C port of a similar library for Arduino on Wiring. Since it uses HAL code, and I'm already very used to the LibopenCM3 functions, its source code had to be slightly corrected. Basically, the changes affected the functions of sending and reading data. In addition, a modifier had to be added in the header file before the private variables static, otherwise it would not want to build.
As a result, the adapted functions took the following form:
Code:
/ ** Write multiple bytes
* @param regAddr Register address to write to
* @param length Count Bytes
* @param data Value to write
* @return Status of operation (true = success)
* /
uint8_t si5351_write_bulk (uint8_t regAddr, uint8_t length, uint8_t * data) {
uint8_t temp [255];
temp [0] = regAddr;
memcpy (temp + 1, data, length);
i2c_transfer7 (SI5351_I2C, SI5351_BUS_BASE_ADDR, temp, length + 1, 0, 0);
return 1;
}
/ ** Write single byte to an 8-bit device register.
* @param regAddr Register address to write to
* @param data New word value to write
* @return Status of operation (true = success)
* /
uint8_t si5351_write (uint8_t regAddr, uint8_t data) {
uint8_t temp [2];
temp [0] = regAddr;
temp [1] = data;
i2c_transfer7 (SI5351_I2C, SI5351_BUS_BASE_ADDR, temp, 2, 0, 0);
return 1;
}
uint8_t si5351_read (uint8_t regAddr) {
uint8_t reg_val = 0;
i2c_transfer7 (SI5351_I2C, SI5351_BUS_BASE_ADDR, ®Addr, 1, ®_val, 1);
return reg_val;
}
Code:
si5351_init (SI5351_CRYSTAL_LOAD_10PF, 25005500, 0);
si5351_drive_strength (SI5351_CLK0, SI5351_DRIVE_8MA);
si5351_set_freq (freq_khz * 100000ULL, SI5351_CLK0);
The frequency is specified in si5351_set_freq()hundredths of a hertz, so the value in kilohertz is multiplied by a constant. It is also highly desirable to specify the type of the constant - ULL (uint64). The microcircuit can not only simply synthesize an arbitrary frequency, but also generate several signals with a given phase shift. A function has been implemented that generates two reference signals with a phase shift of 90 °.
Code:
void set_feq_90 (uint64_t freq) {
uint8_t coef = 650000000 / freq;
uint64_t pll_freq = coef * freq;
// We will output 14.1 MHz on CLK0 and CLK1.
// A PLLA frequency of 705 MHz was chosen to give an even
// divisor by 14.1 MHz.
unsigned long long freq = 14100000 00ULL;
unsigned long long pll_freq = 705000000 00ULL;
// Set CLK0 and CLK1 to output 14.1 MHz with a fixed PLL frequency
set_freq_manual (freq * 100, pll_freq * 100, SI5351_CLK0);
set_freq_manual (freq * 100, pll_freq * 100, SI5351_CLK1);
// Now we can set CLK1 to have a 90 deg phase shift by entering
// 50 in the CLK1 phase register, since the ratio of the PLL to
// the clock frequency is 50.
set_phase (SI5351_CLK0, 0);
set_phase (SI5351_CLK1, coef);
// We need to reset the PLL before they will be in phase alignment
pll_reset (SI5351_PLLA);
}
I used this feature at first and the first breadboard receiver did not have a phase shifter. However, the use of a local phase shifter on the 74AC74 gave the best result, so I refused to generate two signals (although this option also turned out to be working).
As a display, an OLED screen on SSD1306 was used here, a library was written for it that implements formatted text output and has limited Unicode support, similar to my MP3 player project, which I wrote about earlier. The encoder has become a real ambush. It looks like a very convenient thing for restructuring. However, the cheap contact encoder began to fail quickly and became unusable. And I wanted it not to be demolished, as in the Bruker AC200. And the solution was found!
In fact, an encoder can be easily made from a stepper motor, and I just had one of these from a printer. Therefore, inspired by one publication and slightly adapting the circuit for the HEF4011 (K561LA7) I had in my stock, I assembled just such a design. Here Schmitt triggers assembled on inverters form a digital output.
The encoder signal decryption algorithm is superbly simple. On the rising edge of one of the encoder outputs, an interrupt occurs, in which the level at the second output is determined. If there is zero, then we consider that the encoder rotates forward, and if there is one, then backward. This is reflected in the graph.
We see that here, too, we have quadrature signals: in one case, the phase lags by 90 °, and in the other, it is ahead.
With a contact encoder, such an algorithm worked without failures, however, with a stepper motor in the windings, a problem arose - it took two steps at once. In addition, when changing direction, the first step was performed incorrectly. I overcame the first problem programmatically, just skipping odd interrupts, and the second bug I ended up ignoring corny.
Code:
void exti0_isr () {
static uint8_t n = 0;
n ++;
if (n% 2) {
exti_reset_request (EXTI0);
return;
}
if (gpio_get (GPIOA, GPIO1)) {
if (encoder <MAX_LIMIT - coef) {
encoder + = coef;
}
} else {
if (encoder> MIN_LIMIT + coef) {
encoder - = coef;
}
}
// The interrupt flag must be cleared manually
exti_reset_request (EXTI0);
}
A curious feature: an interrupt is triggered only when the output is configured as a float input, and when you specify it as input pullup / pulldown, it does not work (although it seems like it should). The buttons switch the frequency step and set the frequency values corresponding to the HF bands. The synthesizer sources are, as always, available on GitHub.
Assembling the receiver
The circuit that I used differs from the reference only slightly.
At first, the receiver and synthesizer were assembled on breadboards, and in the first version there was no phase shifter, and both reference signals were generated in SI5351.
Then a phase shifter was added there (also on snot), and, most interestingly, it all worked! Instead of 74AC74 (K1554ТМ2), you can also take 74HC74 (K555ТМ2), but then you will hardly be able to climb above 10 MHz, since 74HC74 works somewhere up to 40 MHz. But the AC-series confidently holds up to 120 MHz.
After making sure that the structure was working, I transferred the device to printed circuit boards, which slightly improved the signal quality, especially after placing the boards in the screen. Although the difference was not fundamental.
RF signals should be transmitted over coaxial cable using appropriate connectors such as SMA. At worst, the cable can be soldered. The wire going to the audio card also needs a shielded one. Not necessarily high-frequency, but certainly shielded, otherwise everything will drown in interference.
The printed circuit boards are made of double-sided foil-clad fiberglass, the copper layer is preserved on the back side and is connected to the ground, the jumpers are made of insulated wire, and the holes are countersunk at the entrance to the board.
The boards themselves are placed in tin cases that act as a screen.
The synthesizer encoder together with the buttons for switching ranges and changing the tuning step is displayed separately.
Instead of NE5532, you can take the LM358, but the first microcircuit is still preferable, since it makes less noise. And the most important point in the whole business is the antenna. It would be nice, of course, to use a sufficiently long outdoor antenna and preferably outside the city, but for lack of a better piece of wire stretched across the room will come off. Especially if you connect a U-shaped circuit to it and adjust to the maximum of the signal.
Good results can be achieved with a magnetic antenna. The main thing is that when using it, the signal-to-noise ratio will be much better, which is especially important in the city.
The loop itself is made of a coaxial cable and has a diameter of 400 mm, the J309 transistor can be replaced with a BF245 or KP303E. Antenna and preamplifier can also be mounted on a breadboard.
All this was collected literally on the knee, from the stocks available at home (damn coronavirus!). It takes up a little space, but it works quite briskly, covering the range from 5.8 MHz to 19,000 MHz. And if you add capacitance in parallel to the variable capacitor, then you can go lower.
We include
To check the functionality of the receiver, we first connect it to the oscilloscope. On the synthesizer, we set the frequency to 12 MHz (3 MHz after the phase shifter), and instead of the antenna we connect the signal generator (sinusoid 3 MHz with a swing of 300 μV). If the synthesizer is tuned correctly, the output beat frequency should be several hertz. Actually, I calibrated it using the generator, adjusting the frequency of the quartz resonator in the firmware. By the way, instead of editing the frequency, it was possible to set the deviation in ppm in the same function.
Code:
si5351_init (SI5351_CRYSTAL_LOAD_10PF, 25005500, 0);
We also see that when the beat frequency goes through 0, the phase shift between I and Q changes abruptly from 90 ° to –90 °. This means that everything is working correctly. Now you can connect to your audio card. Anyone with a stereo line input will do. In this case, the bandwidth is of little concern to us, since we can always shift the reference signal.
Software
There are many programs for working with SDR receivers, but now they are all focused on working with RTL-SDR and its more specialized varieties, such as HACK-RF, airspy and others. Nevertheless, from the current software SDR # supports capture from an audio card. This is a popular program, and there are a lot of manuals for it on the web, although the interface is already intuitive.
Therefore, we set, run, set the desired range on the synthesizer, adjust the antenna to the maximum signal, turn on the AM demodulator (most of everything interesting on HF is in AM) - and forward. The receiver works very steadily, with regenerative analogs (which are still sometimes assembled), with a similar complexity, there is simply no comparison in quality. Of course, one can see both the mirror channel and the reflections, which are especially distinct at powerful stations, but this is a price to pay for the simplicity of the radio path. You can overcome reflections by using a low-pass filter at the output of the operational amplifier. And the specularity can really be suppressed by balancing the channels at least in amplitude.
Also for Windows there is a very minimalistic and somewhat outdated SDRadio program, which our receiver also supports. However, it was worth mentioning it rather for the sake of retrospective.
Okay, what about Linux? It's a little more complicated here: gqrx is focused only on working with RTL chips and does not support capture from an audio card. So let's use GNU Radio!
We start gnuradio-companionand build a simple graph. We use as a source audio source, in the properties of which we set the number of outputs ( 2) and sample rate=48000. Any audio card can handle such settings. When the number of outputs is audio sourcespecified as two, the left and right capture channels are automatically used.
If necessary, you can select one of several audio cards. Then we put a block float to complex, which creates one complex from two real values, we connect our source to its inputs. It is also useful between audio sourceand float to complexto put the multiplication by a constant, which will allow you to balance the channels in amplitude. Now we put the low-pass filter, in which we indicate the cutoff frequency of 5 kHz. The filter will select the necessary 5 kHz signal bandwidth around zero.
A very useful feature of GNU Radio is the ability to use variables whose values are set separately, or even change them interactively using interface elements. We connect an AM demodulator to the filter output, which finds the complex signal module, and Audio Sink. And since in this case the sample rates of the source and the receiver are equal, we do not need to match them by resampling. The simplest AM receiver is ready!
It receives the station on the local oscillator frequency, that is, in the center of the band falling on the audio card. Okay, how can I see the spectrum of the signal? To do this, add an element QT GUI: Frequency Sinkthat will draw us a signal spectrum. It should be connected to the output of the block float to complex. In a similar way, the element QT GUI: Waterfall Sinkis responsible for the "waterfall".
As if everything is fine in our receiver. But there is no software frequency tuning in the window, and this is an extremely useful thing, given that audio cards often give artifacts in different parts of the window. Mine, for example, is at zero (+/– 100 Hz): apparently, it is interference from the mains that interferes with signal reception.
It is quite simple to make a software rearrangement, you need to add another multiplication block between float to complexand Low Pass Filter, but in this case, not by a constant, but by a function, that is, by the second signal. Let's take a block as the source of the second signal Signal Source, the waveform is a cosine. Its frequency should be equal to the frequency at which you want to shift the signal.
Thus, we have added another frequency converter to the receiver, this time in software. Now, by tuning the frequency Signal Source, we can choose which part of the window to send to the detector. In other words, we just shift zero in our window. The resulting receiver graph looks like the diagram.
If you want to listen to radio amateurs - no problem, only instead of the signal module, we now need its real part (or imaginary, or their sum, it's not important here). There was an AM receiver, but it became a direct conversion! Here, of course, it is worth correcting the filter bandwidth, since we are already on SSB. Better to set it somewhere around 1500 Hz.
At 40 m, radio amateurs are clearly audible. And this is how the confident reception in the AM mode of "China International Radio" looks like, which is perfectly audible in all broadcast HF bands.
Bonus
Okay, but what if the laptop does not have an audio card, and you really want to crawl along the HF range? You can, of course, buy an external audio card or a converter to RTL-SDR, but an up-converter costs several times more than the RTL whistle itself. Also in China, they sell modified RTL-SDR v3 that support direct conversion: the price is acceptable, but still noticeably higher than that of RTL-SDR. And why buy when the device can be hacked.
WARNING
The described manipulations can ruin your RTL-SDR, and under unfavorable circumstances, burn out the USB port and even burn the motherboard. Therefore, repeat these actions at your own peril and risk and only if you know exactly what you are doing. I warned!
As you know, RTL2832U has ADC input. Moreover, if you read an impromptu datasheet written by enthusiasts, you can see that there are two ADCs and both have a differential input. In this case, the chip can digitize the signal up to 30 MHz. In fact, all that is needed is to send a signal to the input, you can even send one. In the simplest case, they do this: they solder the frequency converter chip and solder the antenna. Moreover, sometimes the chip is even left in place by simply cutting the corresponding tracks.
But we are using a more elegant solution. If you followed the recommendations when choosing a whistle, then the RT820 chip is probably used as a converter - and indeed, in our case, it is more convenient. The fact is that the RT820 uses only one input I of the RTL2832U microcircuit (these are pins 1 and 2), and the Q input (pins 4 and 5) remains unused.
That is exactly what we will connect to. Moreover, you can additionally use a transformer, which will allow you to use the input differential, protect against static and match the resistances somewhat. However, we will not bother with the latter. But protection against static is much more important, otherwise in one unexpected and not very pleasant moment the device can turn into a brick. The transformer is wound on a ferrite ring with three wires folded together and contains six turns, the windings are phased, as indicated in the diagram.
In principle, it is not even necessary to wind the transformer, you can use a ready-made one, for example, from an ADSL modem. Everything in this modification is good, except that the RTL2832U has a 0.5 mm pitch and the pins are very short. So I couldn't solder to the MGTF 0.05 contacts themselves. Instead, I soldered a 0.1 mm wire to them, and already to it - the transformer leads. To keep this whole structure in place and not move, I used a thermal tape.
This modification, of course, requires certain skills, but everything is quite real (it took me about half an hour). We run gqrx with device parameters rtl=0,direct_samp=2and see that everything works fine (let's be optimists). We connect the loop antenna, and you can listen to the broadcast. The parameter direct_samp=2indicates that it is necessary to use direct sampling of the signal from the input Q. In addition, the basic functionality of the device is still present and triggering with standard parameters allows VHF to be received.
Of course, such a simple solution also has disadvantages in the form of interference from FM stations, false signals and other delights, but it works comparable to RTL-SDR v3. And if you really want to, then you can try to pump the device further. But this, in my opinion, is superfluous, except that the input filter with a cutoff frequency of about 30 MHz and a good, shielded case have definitely not bothered anyone yet.
