Engee documentation
Notebook

Calculation of BER for BPSK

The Error Rate Calculation block calculates the error rate by bits (bit error rate, BER). Using this block, we can obtain BER data for the communication system and analyze the effectiveness of our system. In this example, we will look at a simple BPSK receiver and transmitter model. It is shown in the picture below.

image.png

Next, we will set an auxiliary function to run the model.

In [ ]:
# Подключение вспомогательной функции запуска модели.
function run_model( name_model)
    
    Path = (@__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
    sleep(1)
    return model_output
end
Out[0]:
run_model (generic function with 1 method)

Next, we will initialize the signal-to-noise ratio indicators for our model and declare a bit error variable.

In [ ]:
EbNoArr = collect(-7:3:7);
Eb_No = 0;
ber = zeros(length(EbNoArr));
BER = 0;

Now let's run the model at different values of the signal-to-noise ratio.

In [ ]:
for i in 1:length(EbNoArr)
    Eb_No = EbNoArr[i]
    run_model("BPSK_BER") # Запуск модели.
    BER = collect(BER)
    ber[i]=BER.value[end]
    println("BER: $(ber[i])")
end
Building...
Progress 0%
Progress 100%
Progress 100%
BER: 0.28515625
Building...
Progress 0%
Progress 100%
Progress 100%
BER: 0.2021484375
Building...
Progress 0%
Progress 100%
Progress 100%
BER: 0.091796875
Building...
Progress 0%
Progress 100%
Progress 100%
BER: 0.03515625
Building...
Progress 0%
Progress 100%
Progress 100%
BER: 0.005859375

We will construct a BER graph from both the model and theoretical calculations.

In [ ]:
using SpecialFunctions
function berawgn_psk(EbNo_dB, M)
    EbNo = 10 .^ (EbNo_dB ./ 10)
    if M == 2
        return 0.5 .* erfc.(sqrt.(EbNo))# аналогично для QPSK с Gray-кодированием
    else
        k = log2(M)
        return 2 * erfc.(sqrt.(k .* EbNo) .* sin(π/M)) / k
    end
end
ber_ref = berawgn_psk(EbNoArr, 2)
println("__Eb_No__: $EbNoArr")
println("_ber_ref_: $(round.(ber_ref, digits=3))")
println("ber_model: $(round.(ber, digits=3))")

p1 = plot(EbNoArr, ber_ref, seriestype = :scatter, marker = :rect, label = "Theoretical BPSK", yscale = :log10)
plot!(p1, EbNoArr, ber, seriestype = :scatter, marker = :diamond, label = "Model BPSK")
xlabel!(p1, "Eb/No (dB)")
ylabel!(p1, "BER")
title!(p1, "Bit Error Rate (Log Scale)")
# Второй график: обычный масштаб
p2 = plot(EbNoArr, ber_ref, seriestype = :scatter, marker = :rect, label = "")
plot!(p2, EbNoArr, ber, seriestype = :scatter, marker = :diamond, label = "")
ylabel!(p2, "BER")
title!(p2, "Bit Error Rate (Linear Scale)")

# Общий вывод: два графика рядом
plot(p2, p1, layout = (2, 1), size=(1000,400))
__Eb_No__: [-7, -4, -1, 2, 5]
_ber_ref_: [0.264, 0.186, 0.104, 0.038, 0.006]
ber_model: [0.285, 0.202, 0.092, 0.035, 0.006]
Out[0]:

Conclusion

As you can see in this example, the higher the signal-to-noise ratio, the lower the error.
Here we have figured out how to build a BER graph for a simple communication system model and learned how to apply this method to analyze the system.