Tutoriel Démodulation PSK

Ceci est la version 3.9 – La version 3.7 en français se trouve dans la deuxième partie

Guided Tutorial PSK Demodulation

Jump to navigationJump to search

In this tutorial, we will be focused on simulation rather than over-the-air transmission. It will discuss many of the issues involved with what goes on when transmitting and receiving signals with real hardware and channel effects. We will go through setting up our simulation and then step-by-step how to recover the signal.

During the tutorial, keep in mind that this is just one way of handling digital signal reception. There are various algorithms and methods that have been designed for these steps, and different types of digital signals will behave differently. Here, we go through a set of stages and use of algorithms readily available in GNU Radio for PSK signal reception and demodulation. This tutorial, however, should in no way be meant to suggest that this is the only way to accomplish this task.



  • Understand issues of signal distortion and channel effects.
  • Recognize the stages required to recover signals.
    • Timing recovery
    • Multipath channels
    • Phase and frequency correction
    • Decoding symbols and bit ordering



The current tutorial has been updated for GNU Radio version 3.9. The CMA Equalizer and LMS DD Equalizer have been deprecated in 3.9 and will be removed in a future release. They have been replaced by the Linear_Equalizer and Adaptive_Algorithm.

It is intended that the reader study the flowgraphs and resulting output, but not necessarily build each one. If needed for reference, the original flowgraphs for version 3.7 can be found in [2] and in the second part of this document.

Transmitting a Signal

The first stage is transmitting the QPSK signal. We generate a stream of bits and modulate it onto a complex constellation. To do this, we use the Constellation Modulator block, which uses a Constellation Rect. Object and other settings to control the transmitted signal. The Constellation parameter of the Constellation Modulator is the id of the Constellation Rect. Object (qpsk_const), even though it shows on the flowgraph as something else.

The constellation object allows us to determine how the symbols are coded. The modulator block can then use this modulation scheme with or without differential encoding. The constellation modulator expects packed bytes, so we have a random source generator providing bytes with values 0 – 255.

When dealing with the number of samples per symbol, we want to keep this value as small as possible (minimum value of 2). Generally, we can use this value to help us match the desired bit rate with the sample rate of the hardware device we’ll be using. Since we’re using simulation, the samples per symbol is only important in making sure we match this rate throughout the flowgraph. We’ll use 4 here, which is greater than what we need, but useful to visualize the signal in the different domains.

Finally, we set the excess bandwidth value. The constellation modulator uses a root raised cosine (RRC) pulse shaping filter, which gives us a single parameter to adjust the roll-off factor of the filter, often known mathematically as ‘alpha’. The mpsk_rrc_rolloff.grc flowgraph below generates the following figure showing different values of the excess bandwidth. Typical values are between 0.2 (red trace) and 0.35 (green trace).

Mpsk rrc rolloff fg.png
Rrc rolloff.png

The example flowgraph mpsk_stage1.grc transmits a QPSK constellation. It plots both the transmitted signal and part of the receiver chain in time, frequency, and the constellation plot. The variable rrc_taps value is firdes.root_raised_cosine(1.0,samp_rate,samp_rate/sps,excess_bw,11*sps).

Stage1 grc.png

In the constellation plot, we see the effects of the up-sampling (generating 4 samples per symbol) and filtering process. In this case, the RRC filter adds intentional self-interference, known as inter-symbol interference (ISI). ISI is bad for a received signal because it blurs the symbols together. We’ll look into this in-depth during the timing recovery section. Right now, let’s just see what we’re doing to the signal. If you are just looking at the transmitted signals from this graph, then you should see that the frequency plot is showing a signal with a nice shape to it and that rolls-off into the noise. If we didn’t put a shaping filter on the signal, we would be transmitting square waves that produce a lot of energy in the adjacent channels. By reducing the out-of-band emissions, our signal now stays nicely within our channel’s bandwidth.


On the receive side, we get rid of ISI by using another filter. Basically, what we’ve done is purposefully used a filter on the transmitter, the RRC filter, that creates the ISI. But when we convolve two RRC filters together, we get a raised cosine filter, which is a form of a Nyquist filter. So, knowing this property of the transmit RRC filter, we can use another RRC filter at the receiver. Filtering is just a convolution here, so the output of the receive-side RRC filter is a raised cosine pulse shaped signal with minimized ISI. The other benefit is that, absent effects of the channel, what we are doing is using a matched filter at the receiver.

Adding Channel Impairments

That first stage example only dealt with the mechanics of transmitting a QPSK signal. We’ll now look into the effects of the channel and how the signal is distorted between when it was transmitted and when we see the signal in the receiver. The first step is to add a channel model, which is done using the example mpsk_stage2.grc below. To start with, we’ll use the most basic Channel Model block of GNU Radio.

This block allows us to simulate a few main issues that we have to deal with. The first issue with receivers is noise. Thermal noise in our receiver causes noise that we know of as Additive White Gaussian Noise (AWGN). We set the noise power by adjusting the noise voltage value of the channel model. We specify the voltage here instead of power because we need to know the bandwidth of the signal in order to calculate the power properly. One of the defining aspects of GNU Radio is the independence of the blocks, so the channel model doesn’t know anything about the incoming signal. We can calculate the noise voltage from a desired power level knowing the other parameters of the simulation.

Another significant problem between two radios is different clocks, which drive the frequency of the radios. The clocks are, for one thing, imperfect, and therefore different between radios. One radio transmits nominally at fc (say, 450 MHz), but the imperfections mean that it is really transmitting at fc + f_delta_1. Meanwhile, the other radio has a different clock and therefore a different offset, f_delta_2. When it’s set to fc, the real frequency is at fc + f_delta_2. In the end, the received signal will be f_delta_1 + f_delta_2 off where we think it should be (these deltas may be positive or negative).

Related to the clock problem is the ideal sampling point. We’ve up-sampled our signal in the transmitter and shaped it, but when receiving it, we need to sample the signal at the original sampling point in order to maximize the signal power and minimize the inter-symbol interference. Like in our stage 1 simulation after adding the second RRC filter, we can see that among the 4 samples per symbol, one of them is at the ideal sampling point of +1, -1, or 0. But again, the two radios are running at different speeds, so the ideal sampling point is an unknown.

The second stage of our simulation allows us to play with these effects of additive noise, frequency offset, and timing offset. When we run this graph we have added a bit of noise (0.2), some frequency offset 0.025), and some timing offset (1.0005) to see the resulting signal.

Stage2 grc.png

The constellation plot shows us a cloud of samples, far worse that what we started off with in the last stage. From this received signal, we now have to undo all of these effects.

Recovering Timing

Now we’ll walk through the recovery process. Keep in mind that there are many algorithms we could use for recovery of each stage. Some can do joint recovery of multiple stages at the same time. We will use the polyphase clock recovery algorithm here.

We will start off with timing recovery. We’re trying to find the best time to sample the incoming signals, which will maximize the Signal to Noise Ratio (SNR) of each sample as well as reduce the effects of Inter Symbol Interference (ISI).

We can illustrate the ISI problem using the example flowgraph symbol_sampling.grc where we simply create four separate symbols of 1’s in a row and then filter them. The first stage of filtering performs up-sampling to the ‘sps’ samples per symbol and uses a root raised cosine filter. We follow this with another root raised cosine filter that does no rate changes. The second RRC filter here converts the signals from using the non-Nyquist RRC filter to a Nyquist raised cosine (RC) filter as we discussed in the first stage of this tutorial. The output, shown in the figures below, shows the differences between the RRC- and RC-filtered symbols. Without Nyquist filtering, we can see how at the ideal sampling point of each symbol, the other symbols have some energy. If we summed these symbols together like we would in a continuous stream of samples, the energy of those other samples add together and distort the symbol at that point. Conversely, in the RC filtered output, the energy from the other samples are at 0 at the ideal sampling point for the given symbol in time. That means that if we sample at exactly the correct sample point, we only get energy from the current symbol with no interference from the other symbols in the stream. Again, what we’re seeing is how the timing recovery applies a matched filter to satisfy the Nyquist ISI criterion.

Symbol sampling grc.png
Symbol sync rx.png

This simulation allows us to adjust things easily like the number of samples per symbol, excess bandwidth of the RRC filters, and the number of taps. Then we can play with these different values to see how they affect the behavior of the sampling point.

Next, let’s look at what happens due to the different clocks affecting the sampling points between the transmitter and receiver. Using the example flowgraph in symbol_sampling_diff.grc, we simulate the effect of the different clocks in the transmitter and receiver. Each clock is imperfect and so (a) will start at a different point in time and (b) drift relative to the other clocks. We simulate this by adding a resampler that adjusts the symbol sampling time slightly between the transmitted signal (in the transmit image above) and the receiver, shown below. The clock difference shown here of 1.125 is extreme as a way of showing it in this setup as a visualization technique. In reality, timing differences are on the order of a few parts per million. But here, notice that with the samples being collected at different points in time, the ideal sampling period is not known and any sampling done will also include ISI.

Symbol samp diff grc.png
Symbol sampling rate rx.png

Our task here is to synchronize the transmit and receiver clocks using only information at the receiver from the incoming samples. This job is known as clock or timing recovery.

Details of the Polyphase Clock Sync Block

There are various algorithms that we can use to recover the clock at the receiver, and almost all of them involve some kind of feedback control loop. Those that don’t are generally data aided using a known word like a preamble. We’ll use a polyphase filterbank clock recovery technique that can be found in Multirate Signal Processing for Communications Systems by fred harris [3]. This block does three things for us. First, it performs the clock recovery. Second, it does the receiver matched filter to remove the ISI problem. Third, it down-samples the signal and produces samples at 1 sps.

The block works by calculating the first differential of the incoming signal, which will be related to its clock offset. If we simulate this very simply at first, we can see how the differential filter will work for us. First, using the example flowgraph symbol_differential_filter.grc, we can see how everything looks perfect when our rate parameter is 1 (i.e., there is no clock offset). The sample we want is obviously at 0.22 ms. The difference filter ([-1, 0, 1]) generates the differential of the symbol, and as the following figure shows, the output of this filter at the correct sampling point is 0. We can then invert that statement and instead say when the output of the differential filter is 0 we have found the optimal sampling point.

Symbol differential filter grc.png
Symbol differential filter0.png

What happens when we have a timing offset? That output is shown below shows that the timing offset where the peak of the symbol is off and the derivative filter does not show us a point at zero.

Symbol differential filter1.png

Instead of using a single filter, what we can do is build up a series of filters, each with a different phase. If we have enough filters at different phases, one of them is the correct filter phase that will give us the timing value we desire. Let’s look at a simulation that builds 5 filters, which means 5 different phases. Think of each filter as segmenting the unit circle (0 to 2pi) into 5 equal slices. Using the example flowgraph symbol_differential_filter_phases.grc, we can see how this helps us. Notice here that we are using the fractional resampler here because it makes it easy to do the phase shift (between 0 and 1), but it also changes the filter delays of the signals, so we correct for that using the follow-on delay blocks.

Symbol differential filter phases grc.png

The figure below now gives us an idea of what we’re dealing with, although it’s a bit inexact. What we can see is that the signal labeled as d(sym0)/dt + phi3 has a sample point at 0. This tells us that our ideal sampling point occurs at this phase offset. Therefore, if we take the RRC filter of our receiver and adjust its phase by phi3 (which is 3*2pi/5), then we can correct for the timing mismatch and select the ideal sampling point at this sample time.

Symbol differential filter2.png

But as we have discussed, this is only a simulated approximation; in reality, the samples of each filter wouldn’t occur at the same point in time. We have to up-sample by the number of filter (e.g., 5) to really see this behavior. However, that can clue us into what’s happening a bit farther. We can look at these different filters as parts of one big filter that is over-sampled by M, where M=5 in our simple example here. We could up-sample our incoming signal by this much and select the point in time where we get the 0 output of the difference filter. The trouble with that is we are talking about a large amount of added computational complexity, since that is proportional to our sample rate. Instead, we’re working on filters of different phases at the incoming sample rate, but with the bank of them at these different phases, we can get the effect of working with the over-sampled filter without the added computational cost.

So in our example above, we offset our sampling rate by some known factor of 1.2 and found that we could use one of five filters as the ideal sampling point. Unfortunately, we really only have 5 different phases we can exactly produce and correct for here. Any sampling offset between these phases will still produce a mistimed sample with added ISI as we explored previously. So instead, we use way more than 5 filters in our clock recovery algorithm. Without exploring the math (see harris’ book referenced above), we can use 32 filters to give us a maximum ISI noise factor that is less than the quantization noise of a 16 bit value. If we want more than 16 bits of precision, we can use more filters.

So what? We have a large bank of filters where one of them is at (or very close to) the ideal sampling phase offset. How do we automatically find that? Well, we use a 2nd order control loop, like we almost always do in these recovery situations. The error signal for the recovery is the output of the differential filter. The control loop starts at one of the filters and calculates the output as the error signal. It then moves its way up or down the bank of filters proportionally to the error signal, and so we’re trying to find where that error signal is closest to 0. This is our optimal filter for the sampling point. And because we expect the transmit and receive clocks to drift relative to each other, we use a second order control loop to acquire both the correct filter phase as well as the rate difference between the two clocks.

GNU Radio comes with an example found in the digital examples directory called example_timing.py. You can run this script on your own to see the convergence behavior of the Polyphase Clock Sync recovery block.

Using the Polyphase Clock Sync Block in Our Receiver

Now let’s put this block to use in our simulation. The example flowgraph mpsk_stage3.grc takes the output of the channel model and passes it through our Polyphase Clock Sync block. This block is setup with 32 filters, for the reasons we discussed above, and a loop bandwidth of 2pi/100. The block also takes in a value for the expected samples per symbol, but this is just our guess at what we think this value should be. Internally, the block will adapt around this value based on the rates of the incoming signal. Notice, however, that I have set this simulation up where the estimate is slightly off of the 4 sps we transmit with. This is to simulate an initial timing offset between the transmitter and receiver since we initialize our Timing Offset control to 1.0. It makes things slightly harder so that we can observe the convergence of the constellation.

Stage3 grc.png

When running this script, we see the constellation on the left as the received signal before timing recovery and on the right after timing recovery. It’s still a little noisy as a result of the ISI after the 32 filters, which is quickly absorbed by noise once we adjust the channels Noise Voltage setting to be more than 0.

We can then play around with changing the timing and frequency offset. Moving the timing bar around shows us how the clock sync block keeps the signal locked in time and outputs samples at (or very near) the ideal constellation points. When we add frequency offset, we can see that the constellation becomes a circle. The constellation is still on the unit circle, so we know that it’s still keeping the correct timing, but the block isn’t allowing us to correct for a frequency offset. We still need to handle this, but later.

Likewise, we can change the multipath simulation environment by changing which version of the taps variable we use. Adding multipath will show us that the clock recovery block is robust to multipath but won’t correct for it, so again, we need something else to handle that.


Let’s first understand what multipath is. There is already quite a lot written on the subject of multipath, we’ll just explore it enough here to get a general sense of where it comes from and how it affects our communications capabilities. We won’t be going into details about real fading channels or how to analyze their properties.

Multipath results from that fact that in most communication environments, we don’t have a single path for the signal to travel from the transmitter to the receiver. Like the cartoon below shows, any time there is an object that is reflective to the signal, a new path can be established between the two nodes. Surfaces like buildings, signs, trees, people, etc. can all produce signal reflections. Each of these reflective paths will show up at the receiver at different times based on the length of the path. Summing these together at the receiver causes distortions, both constructively and destructively.


The impact of the combination of these signals at the receiver is distortions of the signal. If the difference in time between reflections is small enough relative to the width of the symbol, the distortion can be within the symbol — intra-symbol interference. When the reflections are longer than the symbol time, the reflection from one symbol will affect the signals following — another reason for inter-symbol interference.

We need to correct for this behavior, and we can do so using a mechanism very much like a stereo equalizer. In fact, we call them equalizers. With a stereo equalizer, we can change the gain of certain frequencies to either suppress or enhance those signals — bass and treble being the common ones. I’ve created a very simple example called multipath_sim.grc to help us explore what this looks like in the frequency domain.

Multipath sim grc.png

This simulation sets up a channel model to provide a channel with five equalizer controls, four of which we can change. These controls are set up equally in frequency and we can adjust them from 0 to 1. At a value of 1, the control will allow those frequencies to pass without hindrance. At a value of 0, they will produce a deep null in the spectrum, which will affect all those frequencies around it. The frequency plot is set to average.

While in this example, we are controlling the frequency domain explicitly, what we’re really playing with is the ability to create an equalizer that can correct or adjust the frequency response of a received signal. Ultimately, the goal is shown in the figure below where the multipath channel is creating some distortion in the signal as shown in the frequency domain. The task of the equalizer is to invert that channel. Basically, we want to undo the distortion that’s caused by the channel such that the output of the equalizer is flat. But, instead of adjusting the taps by hand, we have algorithms that update these taps for us. Our job is to use the right equalizer algorithm and set up the parameters. One important parameter here is the number of taps in the equalizer. As we can see in our simulation, five taps gives fairly coarse control over the frequency response. Alternatively, the more taps, the more time it takes to both compute the taps as well as run the equalizer against the signal.

Multipath sim.png


The CMA Equalizer and LMS DD Equalizer have been deprecated in 3.9 and will be removed in a future release. They have been replaced by the Linear_Equalizer and Adaptive_Algorithm. The Adaptive Algorithm has a CMA algorithm type, so it works as a direct replacement for the CMA Equalizer. The CMA, or Constant Modulus Algorithm, is a blind equalizer, but it only works on signals that have a constant amplitude, or modulus. This means that digital signals like MPSK are good candidates since they have points only on the unit circle (think back to the experiment we did where we locked the signal timing but had a frequency offset; what we were seeing was the unit circle).

Mpsk stage4 fg.png

We can watch the CMA algorithm converge. Note, too, that since we have both a clock sync and equalizer block, they are converging independently, but the one stage will affect the next stage. So there is some interaction going on here while both are locking on to the signal. In the end, though, we can see the effect of the time-locked multipath signal before and after the equalizer. Before the equalizer, we have a very ugly signal, even without noise. The equalizer nicely figures out how to invert and cancel out this channel so that we have a nice, clean signal again. We can also see the channel itself and how it flattens out nicely after the equalizer.

Mpsk stage4 out.png

Play with the taps provided to the channel model block to change the multipath. The current taps were simply randomly generated to provide a multipath profile with no real mathematical basis for them. For more complex channel models with fading simulations, see the Channel Models page in the GNU Radio manual.

Phase and Fine Frequency Correction

Given that we’ve equalized the channel, we still have a problem of phase and frequency offset. Equalizers tend not to adapt quickly, and so a frequency offset can be easily beyond the ability of the equalizer to keep up. Also, if we’re just running the CMA equalizer, all it cares about is converging to the unit circle. It has no knowledge of the constellation, so when it locks, it will lock at any given phase. We now need to correct for any phase offset as well as any frequency offset.

Two things about this stage. First, we’ll use a second order loop so that we can track both phase and frequency (which is the derivative of the phase) over time. Second, the type of recovery we’ll deal with here assumes that we are doing fine frequency correction. So we must be sure that we are already within a decent range of the ideal frequency. If we are too far away, our loop here won’t converge and we’ll continue to spin. There are ways to do coarse frequency correction, but we won’t get getting into those here.

For this task, we’re going to use the Costas Loop in example mpsk_stage5.grc (the Constellation Receiver can also be used here). The Costas Loop block can synchronize BPSK, QPSK, and 8PSK. The Constellation Receiver will lock to any given constellation object, though depending on the constellation, the decision making function may be more or less complex.

Mpsk stage5 fg.png

This block, like all of our others, uses a second order loop and is therefore defined with a loop bandwidth parameter. The other thing it needs to know is the order of the PSK modulation, so 2 for BPSK, 4 for QPSK, and 8 for 8PSK. In the next image, we have set noise, timing offset, a simple multipath channel, and a frequency offset. After the equalizer, we can see that the symbols are all on the unit circle, but rotating due to the frequency offset that nothing is yet correcting for. At the output of the Costas loop block, we can see the locked constellation like we started with plus the extra noise, which we can’t do anything about.

Mpsk stage5 out.png


The mpsk_stage6.grc example flowgraph shown below has been updated to version 3.9.

Now that the hard part is done, we get to decode the signal. First, we insert a Constellation Decoder after the Costas loop, but our work is not quite done. At this point, we get our symbols from 0 to 3 because this is the size of our alphabet in a QPSK scheme. But, of those 0-3 symbols, how do we know for sure that we have the same mapping of symbols to constellation points that we did when we transmitted? Notice in our discussion above that nothing we did had any knowledge of the transmitted symbol-to-constellation mapping, which means we might have an ambiguity of 90 degrees in the constellation. Luckily, we avoided this problem by transmitting differential symbols. We didn’t actually transmit the constellation itself, we transmitted the difference between symbols of the constellation by setting the Differential setting in the Constellation Modulator block to True. So now we undo that.

Mpsk stage6 fg.png

The flowgraph uses the Differential Decoder block to translate the differential coded symbols back to their original symbols due to the phase transitions, not the absolute phase itself. But even out of here, our symbols are not exactly right. This is the hardest part about demodulation, really. In the synchronization steps, we had basic physics and math on our side. Now, though, we have to interpret some symbol based on what someone else said it was. We, basically, just have to know this mapping. And luckily we do, so we use the Map block to convert the symbols from the differential decoder to the original symbols we transmitted. At this point, we now have the original symbols from 0-3, so lets unpack those 2 bits per symbol into bits using the unpack bits block. Now, we have the original bit stream of data!

But how do we know that it’s the original bit stream? To do so, we’ll compare to the input bit stream, which we can do because this is a simulation and we have access to the transmitted data. But of course, the transmitter produced packed bits, so we again use the unpack bit block to unpack from 8-bits per byte to 1-bit per byte. We then convert these streams to floating point values of 0.0 and 1.0 simply because our time sinks only accept float and complex values. Comparing these two directly would show us… nothing. Why? Because the receiver chain has many blocks and filters that delay the signal, so the received signal is some number of bits behind. To compensate, we have to delay the transmitted bits by the same amount using the Delay block. You can then adjust the delay to find the correct value and see how the bits synchronize. You can also subtract one signal from the other to see when they are synchronized as the output will be 0. Adding noise and other channel affects can then be easily seen as bit errors whenever this signal is not 0. Note: wait a few seconds after each change of the delay value.

Mpsk stage6 out.png

As a final experiment, notice that we are using a finite length random number generator, so we should be able to see the pattern in the received signal. Using the QT GUI Time Raster Sink, set it up so that you can see this pattern. Keep in mind that the Time Raster plot samples the stream, so the resulting display might not be exactly what you would expect. But the pattern itself should be visible if you have set it up correctly.

Tutoriel Démodulation PSK (V. 3.7)

Dans ce didacticiel, nous nous concentrerons sur la simulation plutôt que sur la transmission en direct. Il discutera de nombreux problèmes liés à ce qui se passe lors de la transmission et de la réception de signaux avec des effets matériels et de canal réels. Nous allons passer par la configuration de notre simulation, puis étape par étape comment récupérer le signal.

Pendant le didacticiel, gardez à l’esprit que ce n’est qu’une façon de gérer la réception du signal numérique. Il existe différents algorithmes et méthodes qui ont été conçus pour ces étapes, et différents types de signaux numériques se comporteront différemment. Ici, nous passons par un ensemble d’étapes et l’utilisation d’algorithmes facilement disponibles dans GNU Radio pour la réception et la démodulation du signal PSK. Cependant, ce didacticiel ne doit en aucun cas signifier que c’est la seule façon d’accomplir cette tâche.


  • Comprendre les problèmes de distorsion du signal et les effets de canal.
  • Reconnaître les étapes requises pour récupérer les signaux.
    • Récupération de synchronisation
    • Canaux à trajets multiples
    • Correction de phase et de fréquence
    • Décodage des symboles et ordre des bits

Conditions préalables

Transmettre un signal

N.B. tous les diagrammes logiques de ce tutoriel sont téléchargeables avec un clic droit sur les liens en italique de cette page. Certains liens font référence à des définitions qui sont décrites dans une page GNU Radio ou font l’objet d’articles sur Wikipedia dont la plupart seront en anglais

La première étape transmet le signal QPSK. Nous générons un flux de bits et le modulons sur une constellation complexe. Pour ce faire, nous utilisons le bloc Constellation Modulator , qui utilise un objet constellation et d’autres paramètres pour contrôler le signal transmis.

L’objet constellation nous permet de déterminer comment les symboles sont codés. Le bloc modulateur peut alors utiliser ce schéma de modulation avec ou sans codage différentiel. Le modulateur de constellation attend des octets compressés, nous avons donc un générateur de source aléatoire fournissant des octets avec des valeurs de 0 à 255.

Lorsque nous traitons le nombre d’échantillons par symbole, nous voulons garder cette valeur aussi petite que possible (valeur minimale de 2). Généralement, nous pouvons utiliser cette valeur pour nous aider à faire correspondre le débit binaire souhaité avec le taux d’échantillonnage du périphérique matériel que nous utiliserons. Puisque nous utilisons la simulation, les échantillons par symbole ne sont importants que pour nous assurer que nous correspondons à ce taux tout au long du diagramme. Nous allons utiliser 4 ici, ce qui est supérieur à ce dont nous avons besoin, mais utile pour visualiser le signal dans les différents domaines.

Enfin, nous définissons la valeur de bande passante excédentaire. Le modulateur de constellation utilise un filtre de mise en forme d’impulsion de cosinus surélevé (RRC), qui nous donne un paramètre unique pour ajuster le facteur de décroissance du filtre, souvent connu mathématiquement comme «alpha». La figure suivante est générée à partir de l’exemple mpsk_rrc_rolloff.grc montrant différentes valeurs de la bande passante excédentaire. Les valeurs typiques se situent entre 0,2 et 0,35.

Rrc rolloff.png

L’exemple de diagramme de flux ‘mpsk_stage1.grc‘ transmet une constellation QPSK (cliquez à droite et « enregistrez le lien sous… » le fichier afin de pouvoir le télécharger et l’exécuter avec GRC). Il trace à la fois le signal transmis et une partie de la chaîne du récepteur dans le temps, la fréquence et le tracé de la constellation.

Stage1 grc.png

Dans le graphique de constellation, nous voyons les effets du suréchantillonnage et processus de filtrage. Dans ce cas, le filtre RRC ajoute une auto-interférence intentionnelle, connue sous le nom d’interférence inter-symboles (ISI). ISI est mauvais pour un signal reçu car il mélange les symboles ensemble. Nous examinerons cela en profondeur lors de la section de récupération de synchronisation. Pour l’instant, voyons ce que nous faisons pour le signal. Si vous regardez simplement les signaux transmis à partir de ce graphique, vous pourrez voir que le tracé de fréquence montre un signal avec une belle forme et qui se déroule dans le bruit. Si nous ne mettons pas de filtre de mise en forme sur le signal, nous transmettons des ondes carrées qui produisent beaucoup d’énergie dans les canaux adjacents. En réduisant les émissions hors bande, notre signal reste désormais bien dans la bande passante de notre canal.


Mais il y a un léger problème avec ce signal qui peut être mieux vu dans le graphique du domaine temporel. Désactivons tous les signaux du diagramme de domaine temporel à l’exception de la partie réelle du signal transmis (c’est-à-dire «Re {TX}»). Ensuite, en cliquant sur le bouton central de la souris pour ouvrir un menu, augmentez le nombre de points de 200 à 5000. En utilisant le même menu, sous le libellé de ligne Re {TX}, allez dans «Marqueur de ligne» et cliquez sur cercle. Ce que vous devriez voir, c’est un peu de désordre. Comment sommes-nous censés recevoir ces échantillons lorsque nous pensions transmettre des 1 et des 0 ? Utilisez le bouton déroulant pour afficher le signal transmis.

Stage1 tx.png

Ce que nous voyons dans cette image est en fait l’ISI que nous avons mentionné précédemment. Nous nous débarrassons de l’ISI en utilisant un autre filtre sur le récepteur. Fondamentalement, ce que nous avons fait est de délibérément utiliser un filtre sur l’émetteur, le filtre RRC, qui crée l’ISI. Mais lorsque nous convoluons deux filtres RRC ensemble, nous obtenons un filtre en cosinus surélevé, qui est une forme de filtre de Nyquist. Donc, connaissant cette propriété du filtre RRC, nous pouvons utiliser un autre filtre RRC au niveau du récepteur. Le filtrage n’est ici qu’une convolution, donc la sortie du filtre RRC côté réception est un signal en forme d’impulsion cosinus élevé avec un ISI minimisé. L’autre avantage est que, en l’absence d’effets du canal, nous utilisons un filtre adapté au niveau du récepteur.

À quoi ressemble le signal reçu via le filtre RRC adapté ? Dans le diagramme temporel, nous pouvons réactiver le signal «Re {RX}» et en utilisant les commandes du menu déroulant ajouter un symbole à cette sortie. Contrairement au désordre du signal transmis, cette version reçue a trois lignes distinctes à +1, -1 et 0 (les zéros peuvent être difficiles à voir, vous devrez donc regarder de près). Utilisez le bouton déroulant pour afficher le signal nettoyé sur le récepteur. Pour ceux qui conservent un score, ce filtre adapté satisfait au critère de Nyquist ISI. Nous le verrons à nouveau dans un format différent lors de la phase de récupération de synchronisation.

Stage1 rc.png

Ajout d’une chaîne

Cet exemple de première étape ne concernait que le mécanisme de transmission d’un signal QPSK. Nous allons maintenant examiner les effets du canal et comment le signal est déformé entre le moment où il a été transmis et le moment où nous voyons le signal dans le récepteur. La première étape consiste à ajouter un modèle de canal, ce qui se fait à l’aide de l’exemple mpsk_stage2.grc . Pour commencer, nous utiliserons le bloc de modèle de canal le plus basique de GNU Radio.

Ce bloc nous permet de simuler quelques problèmes principaux auxquels nous devons faire face. Le premier problème avec les récepteurs est le bruit. Le bruit thermique dans notre récepteur provoque un bruit que nous connaissons sous le nom de bruit blanc gaussien additif (AWGN) . Nous définissons la puissance de bruit en ajustant la valeur de tension de bruit du modèle de canal. Nous spécifions ici la tension au lieu de la puissance car nous devons connaître la bande passante du signal afin de calculer correctement la puissance. L’un des aspects déterminants de GNU Radio est l’indépendance des blocs, donc le modèle de canal ne sait rien du signal entrant. On peut calculer la tension de bruit à partir d’un niveau de puissance souhaité en connaissant les autres paramètres de la simulation.

Un autre problème important entre deux radios est celui des horloges différentes, qui pilotent la fréquence des radios. Les horloges sont, d’une part imparfaites, et donc différentes entre les radios. Une radio émet nominalement à fc (disons, 450 MHz), mais les imperfections signifient qu’elle émet réellement à fc + f_delta_1. Pendant ce temps, l’autre radio a une horloge différente et donc un décalage différent, f_delta_2. Lorsqu’il est réglé sur fc, la fréquence réelle est à fc + f_delta_2. Au final, le signal reçu sera décalé de f_delta_1 + f_delta_2 par rapport à ce qu’il devrait être (ces deltas peuvent être positifs ou négatifs).

Le point d’échantillonnage idéal est lié au problème d’horloge. Nous avons suréchantillonné notre signal dans l’émetteur et l’avons façonné, mais lors de sa réception, nous devons échantillonner le signal au point d’échantillonnage d’origine afin de maximiser la puissance du signal et de minimiser les interférences entre les symboles. Comme dans notre simulation de l’étape 1 après l’ajout du deuxième filtre RRC, nous pouvons voir que parmi les 4 échantillons par symbole, l’un d’eux est au point d’échantillonnage idéal de +1, -1 ou 0. Mais encore une fois, les deux radios fonctionnant à des vitesses différentes, le point d’échantillonnage idéal est donc inconnu.

La deuxième étape de notre simulation nous permet de jouer avec ces effets de bruit additif, de décalage de fréquence et de décalage temporel. Lorsque nous exécutons ce graphique pour la première fois, illustré ci-dessous, nous avons désactivé tous ces effets, mais nous avons des curseurs pour ajuster les paramètres. Nous pouvons ajouter un peu de bruit (0,2), un décalage de fréquence 0,025) et un décalage de synchronisation (1.0005) pour voir le signal résultant par rapport où nous avons commencé.

Stage2 grc.png

Le tracé de la constellation nous montre un nuage d’échantillons, bien pire que ce avec quoi nous avons commencé à la dernière étape. À partir de ce signal reçu, nous devons maintenant annuler tous ces effets.

Récupérer l’horloge (timing)

Nous allons maintenant parcourir le processus de récupération. Gardez à l’esprit qu’il existe de nombreux algorithmes que nous pourrions utiliser pour la récupération de chaque étape. Certains peuvent effectuer une récupération conjointe de plusieurs étapes en même temps. Nous utiliserons ici l’algorithme de récupération d’horloge polyphasée.

Nous allons commencer par la récupération de l’horloge. Nous essayons de trouver le meilleur moment pour échantillonner les signaux entrants, ce qui maximisera le rapport signal / bruit (SNR) de chaque échantillon et réduira les effets des interférences inter-symboles (ISI).

Nous pouvons illustrer le problème ISI en utilisant l’exemple de diagramme de flux symbol_sampling.grc où nous créons simplement quatre symboles de valeur 1 séparés sur la ligne, puis les filtrons. La première étape du filtrage effectue un suréchantillonnage des échantillons par symbole «sps» et utilise un filtre en cosinus surélevé. Nous suivons cela avec un autre filtre cosinus surélevé qui ne modifie pas le taux. Le deuxième filtre RRC convertit ici les signaux provenant de l’utilisation du filtre RRC non Nyquist en un filtre cosinus augmenté (RC) Nyquist comme nous l’avons vu dans la première étape de ce didacticiel. La sortie, illustrée dans les figures ci-dessous, montre les différences entre les symboles filtrés RRC et RC. Sans filtrage de Nyquist, nous pouvons voir comment au point d’échantillonnage idéal de chaque symbole, les autres symboles ont une certaine énergie. Si nous additionnons ces symboles ensemble comme nous le ferions dans un flux continu d’échantillons, l’énergie de ces autres échantillons s’ajoute et déforme le symbole à ce point. Inversement, dans la sortie filtrée RC, l’énergie des autres échantillons est à 0 au point d’échantillonnage idéal pour le symbole donné dans le temps. Cela signifie que si nous échantillonnons exactement au point d’échantillonnage correct, nous n’obtenons de l’énergie qu’à partir du symbole actuel sans interférence des autres symboles du flux. Encore une fois, ce que nous voyons, c’est comment la récupération de synchronisation applique un filtre adapté pour satisfaire le critère ISI Nyquist.

Synchronisation des symboles tx.png
Synchronisation des symboles rx.png

Cette simulation nous permet d’ajuster facilement des choses comme le nombre d’échantillons par symbole, la bande passante excessive des filtres RRC et le nombre de « taps ». On peut alors jouer avec ces différentes valeurs pour voir comment elles affectent le comportement du point d’échantillonnage.

Ensuite, regardons ce qui se passe en raison des différentes horloges affectant les points d’échantillonnage entre l’émetteur et le récepteur. Utilisation de l’exemple de diagramme de flux dans symbol_sampling_diff.grc, nous simulons l’effet des différentes horloges de l’émetteur et du récepteur. Chaque horloge est imparfaite et donc a) commencera à un moment différent dans le temps et b) dérivera par rapport aux autres horloges. Nous simulons cela en ajoutant un rééchantillonneur qui ajuste légèrement le temps d’échantillonnage des symboles entre le signal transmis (dans l’image de transmission ci-dessus) et le récepteur, illustré ci-dessous. La différence d’horloge extrême montrée ici de 1.125 pour montrer dans cette configuration de technique de visualisation. En réalité, les différences de synchronisation sont de l’ordre ou des parties par million. Mais ici, notez que les échantillons étant collectés à différents moments, la période d’échantillonnage idéale n’est pas connue et tout échantillonnage effectué inclura également l’ISI.

Taux d'échantillonnage des symboles rx.png

Notre tâche ici est de synchroniser les horloges d’émission et de réception en utilisant uniquement les informations sur le récepteur des échantillons entrants. Ce travail est connu sous le nom de récupération d’horloge ou de synchronisation.

Détails du bloc de synchronisation d’horloge polyphasée

Il existe différents algorithmes que nous pouvons utiliser pour récupérer l’horloge du récepteur, et presque tous impliquent une sorte de boucle de contrôle de rétroaction. Ceux qui ne le sont généralement pas sont assistés par des données en utilisant un mot connu comme un préambule. Nous utiliserons une technique de récupération d’horloge de banc de filtres polyphasés qui peut être trouvée dans le traitement du signal multi-débit pour les systèmes de communication par Fred Harris [2] . Ce bloc fait trois choses pour nous. Tout d’abord, il effectue la récupération d’horloge. Deuxièmement, il fait le filtre correspondant au récepteur pour supprimer le problème ISI. Troisièmement, il sous-échantillonne le signal et produit des échantillons à 1 échantillon par symbole (sps).

Le bloc fonctionne en calculant la dérivée première du signal entrant, qui sera liée à son décalage d’horloge. Si nous simulons cela très simplement au début, nous pouvons voir comment le filtre différentiel fonctionnera pour nous. Tout d’abord, en utilisant l’exemple de diagramme de flux symbol_differential_filter.grc , nous pouvons voir comment tout semble parfait lorsque notre paramètre de vitesse est 1 (c’est-à-dire qu’il n’y a pas de décalage d’horloge). L’échantillon que nous voulons est évidemment à 0,25 ms. Le filtre de différence ([-1, 0, 1]) génère la dérivée du symbole (courbe rouge), et comme le montre la figure suivante, la sortie de ce filtre au point d’échantillonnage correct est 0. Nous pouvons ensuite inverser cette déclaration et dire à la place quand la sortie du filtre différentiel est 0 nous avons trouvé le point d’échantillonnage optimal.

Filtre différentiel de symboles0.png

Que se passe-t-il lorsque nous avons un décalage temporel ? L’image montre ci-dessous qu’au moment du pic du symbole décalé temporellement (courbe bleue) le filtre dérivé ne nous montre pas un point à zéro.

Symbole filtre différentiel1.png

Au lieu d’utiliser un seul filtre, nous pouvons créer une série de filtres, chacun avec une phase différente. Si nous avons suffisamment de filtres à différentes phases, l’un d’eux est la phase de filtre correcte qui nous donnera la valeur de synchronisation que nous désirons. Regardons une simulation qui construit 5 filtres, ce qui signifie 5 phases différentes. Considérez chaque filtre comme une segmentation du cercle unitaire (0 à 2pi) en 5 tranches égales. En utilisant l’exemple de diagramme de flux symbol_differential_filter_phase.grc , nous pouvons voir comment cela nous aide. Notez ici que nous utilisons le rééchantillonneur fractionné ici car il facilite le décalage de phase (entre 0 et 1), mais il modifie également les retards de filtrage des signaux, nous corrigeons donc cela en utilisant les blocs de retard de suivi .

La figure ci-dessous nous donne maintenant une idée de ce que nous traitons, bien que ce soit un peu inexact. Ce que nous pouvons voir, c’est que le signal étiqueté d(sym0) / dt + phi3 a un point d’échantillonnage à exactement 0. Cela nous indique que notre point d’échantillonnage idéal se produit à ce décalage de phase. Par conséquent, si nous prenons le filtre RRC de notre récepteur et ajustons sa phase par phi3 (qui est 3 * 2pi / 5), nous pouvons corriger le décalage temporel et sélectionner le point d’échantillonnage idéal à ce moment d’échantillonnage.

Symbole différentiel filter2.png

Mais comme nous l’avons vu, ce n’est qu’une approximation simulée; en réalité, les échantillons de chaque filtre ne se produiraient pas au même moment. Nous devons suréchantillonner par le nombre de filtres (par exemple, 5) pour vraiment voir ce comportement. Cependant, cela peut nous indiquer ce qui se passe un peu plus loin. Nous pouvons regarder ces différents filtres comme des parties d’un grand filtre suréchantillonné par M, où M = 5 dans notre exemple simple ici. Nous pourrions sur-échantillonner notre signal entrant de cette façon et sélectionner le moment où nous obtenons la sortie 0 du filtre de différence. Le problème avec cela est que nous parlons d’une grande quantité de complexité de calcul supplémentaire, car cela est proportionnel à notre taux d’échantillonnage. Au lieu de cela, nous travaillons sur des filtres de différentes phases à la fréquence d’échantillonnage entrante, mais avec une banque de filtres à ces différentes phases,

Ainsi, dans notre exemple ci-dessus, nous avons compensé notre taux d’échantillonnage par un facteur connu de 1,2 et avons constaté que nous pouvions utiliser l’un des cinq filtres comme point d’échantillonnage idéal. Malheureusement, nous n’avons vraiment que 5 phases différentes que nous pouvons produire et corriger exactement ici. Tout décalage d’échantillonnage entre ces phases produira toujours un échantillon erroné avec ISI ajouté comme nous l’avons exploré précédemment. Donc, à la place, nous utilisons bien plus de 5 filtres dans notre algorithme de récupération d’horloge. Sans explorer les mathématiques (voir le livre de Harris référencé ci-dessus), nous pouvons utiliser 32 filtres pour nous donner un facteur de bruit ISI maximum qui est inférieur au bruit de quantification d’une valeur de 16 bits. Si nous voulons plus de 16 bits de précision, nous pouvons utiliser plus de filtres.

Et maintenant ? Nous avons une grande banque de filtres dont l’un est à (ou très proche) du décalage de phase d’échantillonnage idéal. Comment trouvons-nous automatiquement cela ? Eh bien, nous utilisons une boucle de contrôle de 2e ordre, comme nous le faisons presque toujours dans ces situations de récupération. Le signal d’erreur pour la récupération est la sortie du filtre différentiel. La boucle de commande commence à l’un des filtres et calcule la sortie comme signal d’erreur. Il se déplace ensuite vers le haut ou vers le bas de la banque de filtres proportionnellement au signal d’erreur, et nous essayons donc de trouver où ce signal d’erreur est le plus proche de 0. C’est notre filtre optimal pour le point d’échantillonnage. Et parce que nous nous attendons à ce que les horloges d’émission et de réception dérivent l’une par rapport à l’autre, nous utilisons une boucle de commande de second ordre pour acquérir à la fois la phase de filtre correcte ainsi que la différence de débit entre les deux horloges.

GNU Radio est livré avec un exemple trouvé dans le répertoire des exemples numériques appelé example_timing.py . Vous pouvez exécuter ce script par vous-même pour voir le comportement de convergence du bloc de récupération Synchronisation d’horloge polyphasée.

Utilisation du bloc de synchronisation d’horloge polyphasée dans notre récepteur

Maintenant, utilisons ce bloc dans notre simulation. L’exemple de diagramme de flux mpsk_stage3.grc prend la sortie du modèle de canal et la transmet à travers notre bloc Synchronisation d’horloge polyphasée. Ce bloc est configuré avec 32 filtres, pour les raisons évoquées ci-dessus, et une bande passante de boucle de 2pi / 100. Le bloc prend également une valeur pour les échantillons attendus par symbole, mais ce n’est que notre estimation de ce que nous pensons que cette valeur devrait être. En interne, le bloc s’adaptera autour de cette valeur en fonction des débits du signal entrant. Notez, cependant, que j’ai mis en place cette simulation où l’estimation est légèrement hors des 4 sps avec lesquels nous transmettons. Il s’agit de simuler un décalage de synchronisation initial entre l’émetteur et le récepteur puisque nous initialisons notre commande de décalage de synchronisation à 1,0. Cela rend les choses un peu plus difficiles afin que nous puissions observer la convergence de la constellation.

Stage3 grc.png

Lors de l’exécution de ce script, nous voyons la constellation à gauche comme signal reçu avant la récupération de synchronisation et à droite après la récupération de synchronisation. C’est toujours un peu bruyant à cause de l’ISI après les 32 filtres, qui est rapidement absorbé par le bruit une fois que nous avons ajusté le paramètre de tension de bruit des canaux à plus de 0.

Nous pouvons alors jouer avec la modification du timing et du décalage de fréquence. Déplacer la barre de synchronisation nous montre comment le bloc de synchronisation d’horloge maintient le signal verrouillé dans le temps et génère des échantillons aux points de constellation idéaux (ou très proches). Lorsque nous ajoutons un décalage de fréquence, nous pouvons voir que la constellation devient un cercle. La constellation est toujours sur le cercle unitaire, nous savons donc qu’elle garde toujours le bon timing, mais le bloc ne nous permet pas de corriger un décalage de fréquence. Nous devons encore gérer cela, mais plus tard.

De même, nous pouvons changer l’environnement de simulation à trajets multiples en changeant la version de la variable taps que nous utilisons. L’ajout de chemins multiples nous montrera que le bloc de récupération d’horloge est robuste aux chemins multiples mais ne le corrigera pas, donc encore une fois, nous avons besoin d’autre chose pour gérer cela.

Trajets multiples (multichemin)

Voyons d’abord ce qu’est le multichemin. Il y a déjà pas mal d’écrits sur le sujet des trajets multiples, nous allons juste l’explorer suffisamment ici pour avoir une idée générale d’où il vient et comment il affecte nos capacités de communication. Nous n’entrerons pas dans les détails sur les canaux de fondu réels ou sur la façon d’analyser leurs propriétés.

Les trajets multiples résultent du fait que dans la plupart des environnements de communication, nous n’avons pas un seul chemin pour que le signal passe de l’émetteur au récepteur. Comme le montre le dessin ci-dessous, à chaque fois qu’un objet réfléchit le signal, un nouveau chemin peut être établi entre les deux nœuds. Des surfaces telles que des bâtiments, des panneaux, des arbres, des personnes, des chats, etc. peuvent toutes produire des réflexions de signaux. Chacun de ces chemins réfléchissants apparaîtra sur le récepteur à différents moments en fonction de la longueur du chemin. Leur sommation au récepteur provoque des distorsions, à la fois de manière constructive et destructive.


L’impact de la combinaison de ces signaux au niveau du récepteur est une distorsion du signal. Si la différence de temps entre les réflexions est suffisamment petite par rapport à la largeur du symbole, la distorsion peut être à l’intérieur du symbole – interférence intra-symbole. Lorsque les réflexions sont plus longues que la durée du symbole, la réflexion d’un symbole affectera les signaux suivants – une autre raison d’interférence entre symboles.

Nous devons corriger ce comportement, et nous pouvons le faire en utilisant un mécanisme très semblable à un égaliseur stéréo. En fait, nous les appelons égaliseurs. Avec un égaliseur stéréo, nous pouvons changer le gain de certaines fréquences pour supprimer ou améliorer ces signaux – les graves et les aigus étant les plus courants. J’ai créé un exemple très simple appelé multipath_sim.grc pour nous aider à explorer à quoi cela ressemble dans le domaine fréquentiel.

Le multipath_sim.grc configure simplement un modèle de canal pour fournir un canal avec cinq boutons d’égalisation, dont quatre peuvent être modifiés. Ces boutons sont simplement configurés également en fréquence et nous pouvons les ajuster de 0 à 1. À une valeur de 1, le bouton permettra à ces fréquences de passer sans entrave. À une valeur de 0, ils produiront un zéro profond dans le spectre, ce qui affectera toutes ces fréquences autour de lui. Lors de l’exécution du script, il est préférable de définir le tracé de fréquence sur la moyenne (en cliquant avec le bouton droit sur le graphique et en sélectionnant «Moyenne»; une valeur de «Moyenne» est bonne pour cela).

Alors que dans cet exemple, nous contrôlons explicitement le domaine fréquentiel, ce avec quoi nous jouons vraiment, c’est la possibilité de créer un égaliseur qui peut corriger ou ajuster la réponse en fréquence d’un signal reçu. En fin de compte, l’objectif est illustré dans la figure ci-dessous, où le canal à trajets multiples crée une certaine distorsion dans le signal, comme indiqué dans le domaine fréquentiel. La tâche de l’égaliseur est d’inverser ce canal. Fondamentalement, nous voulons annuler la distorsion causée par le canal de sorte que la sortie de l’égaliseur soit plate. Mais, au lieu d’ajuster les ‘taps’ à la main, nous avons des algorithmes qui mettent à jour ces ‘taps’ pour nous. Notre travail consiste à utiliser le bon algorithme d’égalisation et à configurer les paramètres. Un paramètre important ici est le nombre de ‘taps’ dans l’égaliseur. Comme nous pouvons le voir dans notre simulation, cinq pressions donnent un contrôle assez grossier sur la réponse en fréquence. Alternativement, plus il y a de ‘taps’, plus il faut de temps pour calculer les ‘taps’ ainsi que pour exécuter l’égaliseur par rapport au signal.

Multipath equalizing.png


GNU Radio est livré avec deux égaliseurs facilement utilisables . L’égaliseur CMA et l’égaliseur LMS DD. Le CMA, ou Constant Modulus Algorithm, est un égaliseur aveugle , mais il ne fonctionne que sur les signaux qui ont une amplitude ou un module constant. Cela signifie que les signaux numériques comme le MPSK sont de bons candidats car ils n’ont des points que sur le cercle unitaire (repensez à l’expérience que nous avons faite où nous avons verrouillé la synchronisation du signal mais avec un décalage de fréquence; ce que nous voyions était le cercle unitaire).

L’algorithme CMA accepte le nombre de ‘taps’ à utiliser dans l’égaliseur, qui sera basé sur une combinaison d’une supposition éclairée, de meilleures pratiques connues et peut-être d’une certaine connaissance réelle du canal lui-même. Nous voulons garder ce nombre petit pour réduire la surcharge de l’algorithme tout en nous assurant qu’il y a suffisamment de degrés de liberté pour corriger notre canal.

Dans l’ exemple mpsk_stage4.grc , nous utilisons l’algorithme CMA avec 11 taps. Il s’agit d’une simulation, et ce nombre a bien fonctionné par le passé. Jouez avec lui et voyez comment il affecte les performances, à la fois d’un point de vue informatique et signal.

Stage4 grc.png

Nous pouvons regarder l’algorithme CMA converger. Notez également que, comme nous avons à la fois une synchronisation d’horloge et un bloc d’égalisation, ils convergent indépendamment, mais la première étape affectera la suivante. Il y a donc une interaction qui se passe ici pendant que les deux se verrouillent sur le signal. En fin de compte, cependant, nous pouvons voir l’effet du signal à trajets multiples verrouillé dans le temps avant et après l’égaliseur. Avant l’égaliseur, nous avons un signal très moche, même sans bruit. L’égaliseur comprend bien comment inverser et annuler ce canal afin que nous ayons à nouveau un signal agréable et propre. Nous pouvons également voir le canal lui-même et comment il s’aplatit bien après l’égaliseur.


Jouez avec les taps fournis sur le bloc de modèle de canal pour modifier le multichemin. Les prises actuelles ont été simplement générées de façon aléatoire pour fournir un profil à trajets multiples sans aucune base mathématique réelle pour elles. Pour des modèles de canaux plus complexes avec des simulations d’évanouissement, consultez la page Modèles de canaux dans le manuel de GNU Radio.

Égaliseur LMS-DD

Un bon défi consiste maintenant à utiliser le bloc de décision orientée moindre carrés [égaliseur LMS-DD (Least Mean Squared Decision-Directed)]. Il y a beaucoup de chevauchement entre les paramètres, à l’exception d’une caractéristique majeure. Au lieu d’un égaliseur aveugle comme le CMA, cet égaliseur nécessite la connaissance du signal reçu. L’égaliseur doit connaître les points de constellation afin de corriger, et il utilise les décisions concernant les échantillons pour indiquer comment mettre à jour les prises pour l’égaliseur.

Cet égaliseur est idéal pour les signaux qui ne correspondent pas aux exigences de module constant de l’algorithme CMA, il peut donc fonctionner avec des choses comme les modulations de type QAM. En revanche, si le SNR est suffisamment mauvais, les décisions prises sont incorrectes, ce qui peut ruiner les performances du récepteur. Le bloc est également plus complexe en termes de calcul dans ses performances. Cependant, lorsque le signal est de bonne qualité, cet égaliseur peut produire des signaux de meilleure qualité car il a une connaissance directe du signal. Un modèle courant consiste à utiliser un égaliseur aveugle pour l’acquisition initiale afin d’obtenir un signal suffisamment bon pour qu’un égaliseur dirigé prenne le relais. Nous n’essaierons pas de faire quelque chose comme ça ici, cependant.

En tant que défi, prenez le fichier mpsk_stage4.grc et remplacez la récupération de l’égaliseur CMA par l’égaliseur LMS-DD et voyez si vous pouvez le faire converger. Ce bloc utilise un objet de constellation , donc une partie de la difficulté ici est de créer l’objet de constellation approprié pour le signal QPSK et de l’appliquer.

Correction fine de phase et fréquence

Étant donné que nous avons égalisé le canal, nous avons toujours un problème de décalage de phase et de fréquence. Les égaliseurs ont tendance à ne pas s’adapter rapidement, et donc un décalage de fréquence peut facilement dépasser la capacité de l’égaliseur à suivre. De plus, si nous exécutons simplement l’égaliseur CMA, tout ce qui compte c’est de converger vers le cercle unitaire. Il n’a aucune connaissance de la constellation, donc quand il se verrouille, il se verrouille à n’importe quelle phase donnée. Nous devons maintenant corriger tout décalage de phase ainsi que tout décalage de fréquence.

Deux choses à propos de cette étape. Tout d’abord, nous utiliserons une boucle de second ordre afin de pouvoir suivre à la fois la phase et la fréquence, qui est la dérivée de la phase dans le temps. Deuxièmement, le type de récupération dont nous traiterons ici suppose que nous effectuons une correction de fréquence fine . Nous devons donc être sûrs que nous sommes déjà dans une plage décente de la fréquence idéale. Si nous sommes trop loin, notre boucle ici ne convergera pas et nous continuerons de tourner. Il existe des moyens de faire une correction de fréquence grossière, mais nous n’entrerons pas dans ceux-ci ici.

Pour cette tâche, nous allons utiliser la boucle Costas dans l’exemple mpsk_stage5.grc (le récepteur de constellation peut également être utilisé ici). Le bloc Costas Loop peut synchroniser BPSK, QPSK et 8PSK. Le récepteur de constellation se verrouillera sur n’importe quel objet de constellation donné, mais selon la constellation, la fonction de prise de décision peut être plus ou moins complexe.

Stage5 grc.png

Ce bloc, comme tous nos autres, utilise une boucle de second ordre et est donc défini avec un paramètre de bande passante de boucle. L’autre chose qu’il doit savoir est l’ordre de la modulation PSK, donc 2 pour BPSK, 4 pour QPSK et 8 pour 8PSK. Dans l’image suivante, nous avons défini le bruit, le décalage temporel, un simple canal à trajets multiples et un décalage de fréquence. Après l’égaliseur, nous pouvons voir que les symboles sont tous sur le cercle unitaire, mais tournent en raison du décalage de fréquence que rien ne corrige encore. À la sortie du bloc de boucle Costas, nous pouvons voir la constellation verrouillée comme nous avons commencé avec plus le bruit supplémentaire, auquel nous ne pouvons rien faire.



Maintenant que la partie difficile est terminée, nous pouvons décoder le signal. En utilisant l’ exemple de diagramme de flux mpsk_stage6.grc, nous insérons un démodulateur en quadrature après la boucle Costas à la place du my_qpsk_demodulator , mais notre travail n’est pas tout à fait terminé. À ce stade, nous obtenons des symboles de 0 à 3 car c’est la taille de notre alphabet dans un schéma QPSK. Mais, de ces symboles 0-3, comment savoir avec certitude que nous avons le même mappage de symboles aux points de constellation que nous avons fait lorsque nous avons transmis? Remarquez dans notre discussion ci-dessus que rien de ce que nous avons fait ne connaissait le mappage symbole-constellation transmis, ce qui signifie que nous pourrions avoir une ambiguïté de 90 degrés dans la constellation. Heureusement, nous avons évité ce problème en transmettant le codage différentiel. Nous n’avons pas réellement transmis la constellation elle-même, nous avons transmis la différence entre les symboles de la constellation en définissant le paramètre Différentiel dans le bloc Constellation Modulator sur True. Alors maintenant, nous l’annulons.

Stage6 grc.png

L’organigramme utilise le bloc décodeur différentiel pour traduire les symboles codés différentiels en leurs symboles d’origine en raison des transitions de phase, pas la phase absolue elle-même. Mais même ici, nos symboles ne sont pas tout à fait exacts. C’est vraiment la partie la plus difficile de la démodulation. Dans les étapes de synchronisation, nous avions la physique et les mathématiques de base de notre côté. Maintenant, cependant, nous devons interpréter un symbole en fonction de ce que quelqu’un d’autre a dit qu’il était. Nous devons simplement connaître cette cartographie. Et heureusement, nous utilisons donc le bloc Map pour convertir les symboles du décodeur différentiel en symboles originaux que nous avons transmis. À ce stade, nous avons maintenant les symboles originaux de 0 à 3, donc décompressons ces 2 bits par symbole en bits en utilisant la décompression par Unpack_K_Bits. Maintenant, nous avons le flux de données original !

Mais comment savons-nous qu’il s’agit du flux binaire d’origine ? Pour ce faire, nous comparerons le flux binaire d’entrée, ce que nous pouvons faire car il s’agit d’une simulation et nous avons accès aux données transmises. Mais bien sûr, l’émetteur a produit des bits emballés, nous utilisons donc à nouveau le bloc de bits de décompression pour décompresser de 8 bits par octet à 1 bit par octet. Nous convertissons ensuite ces flux en valeurs à virgule flottante de 0,0 et 1,0 simplement parce que nos puits de temps n’acceptent que des valeurs flottantes et complexes. Comparer ces deux directement nous montrerait… rien. Pourquoi ? Parce que la chaîne réceptrice a de nombreux blocs et filtres qui retardent le signal, le signal reçu est donc en retard d’un certain nombre de bits. Pour compenser, nous devons retarder les bits transmis de la même quantité en utilisant le bloc [[Delay | delay]. J’ai programmé cela pour régler le retard à 0 pour commencer. Vous pouvez ensuite ajuster le retard pour trouver la valeur correcte et voir comment les bits se synchronisent.


Pour la réponse cliquez ici

Vous pouvez également soustraire un signal de l’autre pour voir quand ils sont synchronisés car la sortie sera 0. L’ajout de bruit et d’autres effets de canal peuvent alors être facilement considérés comme des erreurs de bit chaque fois que ce signal n’est pas 0.

Comme dernière expérience, notez que nous utilisons un générateur de nombres aléatoires de longueur finie, nous devrions donc être en mesure de voir le motif dans le signal reçu. À l’aide de l’afficheur temporel QT_GUI_Time_Raster_Sink, configurez-le de sorte que vous puissiez voir ce modèle. Gardez à l’esprit que le tracé Time Raster échantillonne le flux, de sorte que l’affichage résultant peut ne pas être exactement ce à quoi vous vous attendez. Mais le motif lui-même doit être visible si vous l’avez configuré correctement.