PLL modif
This commit is contained in:
13400
QAM/constellation.dat
13400
QAM/constellation.dat
File diff suppressed because it is too large
Load Diff
43
QAM/debug.py
43
QAM/debug.py
@ -4,18 +4,27 @@ from pyqtgraph.Qt import QtWidgets, QtCore
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import sys, os
|
import sys, os
|
||||||
|
|
||||||
REF_FILE = "constellation_ref.dat"
|
# -------------------- Fichiers de données --------------------
|
||||||
RX_FILE = "constellation.dat"
|
REF_FILE = "constellation_ref.dat"
|
||||||
|
RX_FILE = "constellation.dat"
|
||||||
|
ERROR_FILE = "pll_error.dat"
|
||||||
|
|
||||||
|
# -------------------- Fonctions de chargement --------------------
|
||||||
def load_points(filename):
|
def load_points(filename):
|
||||||
if os.path.exists(filename):
|
if os.path.exists(filename):
|
||||||
return np.loadtxt(filename)
|
return np.loadtxt(filename)
|
||||||
else:
|
else:
|
||||||
return np.zeros((0,2))
|
return np.zeros((0,2))
|
||||||
|
|
||||||
|
def load_error(filename):
|
||||||
|
if os.path.exists(filename):
|
||||||
|
return np.loadtxt(filename)
|
||||||
|
else:
|
||||||
|
return np.zeros((0,2))
|
||||||
|
|
||||||
# -------------------- Application --------------------
|
# -------------------- Application --------------------
|
||||||
app = QtWidgets.QApplication(sys.argv)
|
app = QtWidgets.QApplication(sys.argv)
|
||||||
win = pg.GraphicsLayoutWidget(show=True, title="Constellation Viewer")
|
win = pg.GraphicsLayoutWidget(show=True, title="Constellation et PLL Error")
|
||||||
win.resize(900, 900)
|
win.resize(900, 900)
|
||||||
win.setBackground('#0a0a0a') # fond noir profond
|
win.setBackground('#0a0a0a') # fond noir profond
|
||||||
|
|
||||||
@ -35,28 +44,36 @@ grid = pg.GridItem()
|
|||||||
grid.setPen(pg.mkPen('#444', width=1, style=QtCore.Qt.DotLine))
|
grid.setPen(pg.mkPen('#444', width=1, style=QtCore.Qt.DotLine))
|
||||||
plot.addItem(grid)
|
plot.addItem(grid)
|
||||||
|
|
||||||
# -------------------- Chargement initial des points --------------------
|
# -------------------- Chargement initial --------------------
|
||||||
ref_data = load_points(REF_FILE)
|
ref_data = load_points(REF_FILE)
|
||||||
rx_data = load_points(RX_FILE)
|
rx_data = load_points(RX_FILE)
|
||||||
|
error_data = load_error(ERROR_FILE)
|
||||||
|
|
||||||
# Points sans contour
|
# Points référence
|
||||||
ref_plot = plot.plot(ref_data[:,0], ref_data[:,1],
|
ref_plot = plot.plot(ref_data[:,0], ref_data[:,1],
|
||||||
pen=None,
|
pen=None,
|
||||||
symbol='o',
|
symbol='o',
|
||||||
symbolSize=10, # cercles un peu plus gros
|
symbolSize=10,
|
||||||
symbolBrush=pg.mkBrush('#1E90FF'), # bleu vif
|
symbolBrush=pg.mkBrush('#1E90FF'), # bleu vif
|
||||||
symbolPen=None,
|
symbolPen=None,
|
||||||
name='Référence')
|
name='Référence')
|
||||||
|
|
||||||
|
# Points reçus
|
||||||
rx_plot = plot.plot(rx_data[:,0], rx_data[:,1],
|
rx_plot = plot.plot(rx_data[:,0], rx_data[:,1],
|
||||||
pen=None,
|
pen=None,
|
||||||
symbol='x',
|
symbol='x',
|
||||||
symbolSize=6, # croix plus petites
|
symbolSize=6,
|
||||||
symbolBrush=pg.mkBrush('#FF4500'), # orange vif
|
symbolBrush=pg.mkBrush('#FF4500'), # orange vif
|
||||||
symbolPen=None,
|
symbolPen=None,
|
||||||
name='Reçu')
|
name='Reçu')
|
||||||
|
|
||||||
# Légende stylée
|
# PLL error en vert
|
||||||
|
error_plot = plot.plot(error_data[:,0], error_data[:,1],
|
||||||
|
pen=pg.mkPen('#00FF00', width=2),
|
||||||
|
symbol=None,
|
||||||
|
name='PLL error')
|
||||||
|
|
||||||
|
# -------------------- Légende stylée --------------------
|
||||||
legend = plot.addLegend()
|
legend = plot.addLegend()
|
||||||
for item in legend.items:
|
for item in legend.items:
|
||||||
item[1].setPen(pg.mkPen('#FFF', width=2))
|
item[1].setPen(pg.mkPen('#FFF', width=2))
|
||||||
@ -65,8 +82,14 @@ for item in legend.items:
|
|||||||
def update():
|
def update():
|
||||||
ref_data = load_points(REF_FILE)
|
ref_data = load_points(REF_FILE)
|
||||||
rx_data = load_points(RX_FILE)
|
rx_data = load_points(RX_FILE)
|
||||||
ref_plot.setData(ref_data[:,0], ref_data[:,1])
|
error_data = load_error(ERROR_FILE)
|
||||||
rx_plot.setData(rx_data[:,0], rx_data[:,1])
|
|
||||||
|
if ref_data.size > 0:
|
||||||
|
ref_plot.setData(ref_data[:,0], ref_data[:,1])
|
||||||
|
if rx_data.size > 0:
|
||||||
|
rx_plot.setData(rx_data[:,0], rx_data[:,1])
|
||||||
|
if error_data.size > 0:
|
||||||
|
error_plot.setData(error_data[:,0], error_data[:,1])
|
||||||
|
|
||||||
timer = QtCore.QTimer()
|
timer = QtCore.QTimer()
|
||||||
timer.timeout.connect(update)
|
timer.timeout.connect(update)
|
||||||
|
|||||||
1340
QAM/pll_error.dat
Normal file
1340
QAM/pll_error.dat
Normal file
File diff suppressed because it is too large
Load Diff
26
QAM/qam.c
26
QAM/qam.c
@ -122,10 +122,10 @@ void demodulate(qam_system* qam, double complex* s, int nb_symbols, uint8_t* bit
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PLL pour corriger le déphasage
|
// PLL pour corriger le déphasage
|
||||||
void pll_qam_symbol(qam_system* qam, double complex* symbols_rx, double complex* r_corr, int nb_symbols, double Kp, double Ki) {
|
void pll_qam_symbol(qam_system* qam, double complex* symbols_rx, double complex* r_corr, int nb_symbols, double Kp, double Ki, double alpha, FILE* fp_error) {
|
||||||
|
|
||||||
double phase_est = 0.0;
|
double phase_est = 0.0;
|
||||||
double integrator = 0.0;
|
double integrator = 0.0;
|
||||||
|
double filtered_error = 0.0;
|
||||||
|
|
||||||
int sm = (int)sqrt(qam->M);
|
int sm = (int)sqrt(qam->M);
|
||||||
int N = qam->N;
|
int N = qam->N;
|
||||||
@ -134,7 +134,7 @@ void pll_qam_symbol(qam_system* qam, double complex* symbols_rx, double complex*
|
|||||||
double complex r_symbol = 0;
|
double complex r_symbol = 0;
|
||||||
for (int n = 0; n < N; n++) {
|
for (int n = 0; n < N; n++) {
|
||||||
int idx = k * N + n;
|
int idx = k * N + n;
|
||||||
r_symbol += symbols_rx[idx] * cexp(2.0 * -I * M_PI * qam->Fc * ((double)idx / qam->Fs));
|
r_symbol += symbols_rx[idx] * cexp(-2.0 * I * M_PI * qam->Fc * ((double)idx / qam->Fs));
|
||||||
}
|
}
|
||||||
r_symbol /= N;
|
r_symbol /= N;
|
||||||
|
|
||||||
@ -154,8 +154,15 @@ void pll_qam_symbol(qam_system* qam, double complex* symbols_rx, double complex*
|
|||||||
|
|
||||||
double error = carg(r_symbol * conj(closest));
|
double error = carg(r_symbol * conj(closest));
|
||||||
|
|
||||||
integrator += Ki * error;
|
filtered_error = (1.0 - alpha) * filtered_error + alpha * error;
|
||||||
phase_est += Kp * error + integrator;
|
integrator += Ki * filtered_error;
|
||||||
|
phase_est += Kp * filtered_error + integrator;
|
||||||
|
|
||||||
|
// Écriture de l'erreur PLL dans le fichier
|
||||||
|
if (fp_error) {
|
||||||
|
fprintf(fp_error, "%d % .8f\n", k, 100 * filtered_error);
|
||||||
|
fflush(fp_error);
|
||||||
|
}
|
||||||
|
|
||||||
for (int n = 0; n < N; n++) {
|
for (int n = 0; n < N; n++) {
|
||||||
int idx = k * N + n;
|
int idx = k * N + n;
|
||||||
@ -265,7 +272,7 @@ int main () {
|
|||||||
double snr_dB = 5; // SNR en dB
|
double snr_dB = 5; // SNR en dB
|
||||||
double snr_lin = pow(10.0, snr_dB / 10.0);
|
double snr_lin = pow(10.0, snr_dB / 10.0);
|
||||||
double sigma = sqrt(signal_power / snr_lin);
|
double sigma = sqrt(signal_power / snr_lin);
|
||||||
add_noise(s, total_samples, 20);
|
add_noise(s, total_samples, 10);
|
||||||
|
|
||||||
|
|
||||||
FILE *fp_ref = fopen("constellation_ref.dat", "w");
|
FILE *fp_ref = fopen("constellation_ref.dat", "w");
|
||||||
@ -296,9 +303,12 @@ int main () {
|
|||||||
//memmove(s + offset_samples, s, (total_samples - offset_samples) * sizeof(double complex));
|
//memmove(s + offset_samples, s, (total_samples - offset_samples) * sizeof(double complex));
|
||||||
|
|
||||||
double complex* r_corr = malloc(sizeof(double complex) * total_samples);
|
double complex* r_corr = malloc(sizeof(double complex) * total_samples);
|
||||||
double Kp = 0.25;
|
double Kp = 0.2;
|
||||||
double Ki = 0.02;
|
double Ki = 0.02;
|
||||||
pll_qam_symbol(&qam, s, r_corr, nb_symbols, Kp, Ki);
|
double alpha = 0.1;
|
||||||
|
FILE* fp_error = fopen("pll_error.dat", "w");
|
||||||
|
pll_qam_symbol(&qam, s, r_corr, nb_symbols, Kp, Ki, alpha, fp_error);
|
||||||
|
fclose(fp_error);
|
||||||
|
|
||||||
// Démodulation
|
// Démodulation
|
||||||
uint8_t* output_bits = (uint8_t*)malloc(nb_bits * sizeof(uint8_t));
|
uint8_t* output_bits = (uint8_t*)malloc(nb_bits * sizeof(uint8_t));
|
||||||
|
|||||||
Reference in New Issue
Block a user