Engee documentation
Notebook

Modulation analysis

In this example, we will explore the possibilities of constellations of different signals and compare the BER of bitstream modulation variants at a common noise level.

The realised demonstration model is shown below.

image_2.png

As we can see, this example uses 3 types of modulations.

  1. Quadrature phase-shift keying (QPSK - quadrature phase-shift keying, or 4-PSK) uses a constellation of four points placed at equal distances on a circle.
  2. Binary phase shift keying (BPSK, binary phase shift keying). This modulation uses two phase shifts (one for logic one and one for logic zero).
  3. Quadrature Modulation (QAM - Quadrature Amplitude Modulation) - a type of amplitude modulation of the signal, which is the sum of two carrier oscillations of the same frequency, but shifted in phase relative to each other by 90 ° (π/2 radians).

First, let's connect the Plots library to plot the graphs and declare the ratio of the energy of information bits per symbol to the noise power spectral density.

In [ ]:
using Plots
In [ ]:
EbNo = 25;

Now let's declare a function to run the model and run the simulation.

In [ ]:
function run_model(name_model)
    Path = string(@__DIR__) * "/" * name_model * ".engee"
    
    if name_model in [m.name for m in engee.get_all_models()] # Проверка условия загрузки модели в ядро
        model = engee.open( name_model ) # Открыть модель
        model_output = engee.run( model, verbose=true ); # Запустить модель
    else
        model = engee.load( Path, force=true ) # Загрузить модель
        model_output = engee.run( model, verbose=true ); # Запустить модель
        engee.close( name_model, force=true ); # Закрыть модель
    end
    return model_output
end
Out[0]:
run_model (generic function with 1 method)
In [ ]:
run_model("demo_model")
Building...
Progress 100%
Out[0]:
Dict{String, DataFrame} with 3 entries:
  "Selector-1.1" => 1001×2 DataFrame…
  "Selector.1"   => 1001×2 DataFrame…
  "Selector-2.1" => 1001×2 DataFrame

Let's extract BER statistics from simout.

In [ ]:
# Считывание из simout сохранённых сигналов
BER_qpsk = simout["demo_model/Selector-1.1"];
BER_qpsk = collect(BER_qpsk);
BER_bpsk = simout["demo_model/Selector.1"];
BER_bpsk = collect(BER_bpsk);
BER_qam = simout["demo_model/Selector-2.1"];
BER_qam = collect(BER_qam);

BER_qpsk.value[1:2]
Out[0]:
2-element Vector{Vector{Float64}}:
 [0.0]
 [0.0]

As we can see, the data are written in matrix vector format. Let's convert them into scalar vectors.

In [ ]:
BER_qpsk_new = [(i...)+0 for i in BER_qpsk.value];
BER_bpsk_new = [(i...)+0 for i in BER_bpsk.value];
BER_qam_new = [(i...)+0 for i in BER_qam.value];

BER_qam_new[1:2]
Out[0]:
2-element Vector{Float64}:
 0.0
 0.0

Let's construct BER graphs.

In [ ]:
plot(title="BER")
plot!(BER_qpsk_new, label = "qpsk")
plot!(BER_bpsk_new, label = "bpsk")
plot!(BER_qam_new, label = "qam")
Out[0]:

As we can see, in this example 8-PSK has the highest error rate.

Now let's perform the constructions for each of the modulations. Let's start with QPSK and then build BPSK and 8-PSK.

In [ ]:
qpsk = collect(qpsk);
qpsk_new = [(i...)+0 for i in qpsk.value];
In [ ]:
plot(title="QPSK")
plot!(ComplexF64.(qpsk_new), seriestype=:scatter)
plot!([0.75+0.75im, 0.75-0.75im, -0.75+0.75im, -0.75-0.75im], seriestype=:scatter)
Out[0]:
In [ ]:
bpsk = collect(bpsk);
bpsk_new = [(i...)+0 for i in bpsk.value];
In [ ]:
plot(title="BPSK")
plot!(ComplexF64.(bpsk_new), seriestype=:scatter)
plot!([-1+0im, 1+0im], seriestype=:scatter)
Out[0]:
In [ ]:
qam = collect(qam);
qam_new = [(i...)+0 for i in qam.value];
In [ ]:
plot(title="8-PSK")
plot!(ComplexF64.(qam_new), seriestype=:scatter)
plot!(cis.(2pi*[0:7...]/8), seriestype=:scatter)
Out[0]:

As we can see from the above constellations, the first two modulations have a more pronounced point spread. And in the first two variants there are significantly less areas of intersection of points, in connection with which we and received in QPSK and BPSK bit error values four times less than when using 8-PSK.

Conclusion

In this example we have looked at ways of constructing and analysing modulated signals using QPSK, BPSK and QAM modulations as examples.