Está en la página 1de 14

MODULACIN Y DEMODULACIN IQ: APLICACIN A DATOS REALES

Fecha de entrega: hasta el 10 de febrero


Modulacin y demodulacin FM usando un modulador IQ
Vamos a crear una seal FM a partir de una sencilla seal
sinusoidal (con una frecuencia de 5 Hz), siguiendo la filosofa
de un modulador IQ. Los datos se muestrearn con una frecuencia
fs = 20000 Hz:
fs = 20000; % Frecuencia muestreo
% Seal a modular
t = [0:1/fs:2]; % 2 sec @ fs muestras/segundo
x = cos(2*pi*5*t); % 5 Hz baseband signal
Lo primero es simular el procesador en banda base donde
generamos las seales I y Q, como I = A cos(phi) y Q = A
sin(phi).
En modulacin FM la amplitud A es constante y la fase se
construye como la integral de la seal x(t) multiplicada por una
constante. En MATLAB podemos calcular numricamente la integral
de la secuencia x[n] con la funcin cumsum() que suma
acumulativamente los contenidos de una secuencia:
A = 1; % amplitud constante
k=0.05; phi = k*cumsum(x); % Integral de seal
Las seales I y Q se generan ahora como:
I = A*cos(phi); Q = A*sin(phi); % Construccin de las seales I y Q
Con esto ya hemos concluido el procesado en banda base. Ahora
solo resta combinar las seales I/Q con la portadora (cos/sin)
para generar la seal IQ modulada (en este caso usando FM).
Usaremos una frecuencia portadora de 2000 Hz:
wc = 2*pi*2000; % Frecuencia 2000 Hz portadora
IQ = I .* cos(wc*t) - Q .* sin(wc*t); % Seal IQ modulada en frecuencia
Podemos escuchar dicha seal de audio usando:
sound(IQ,fs);
Cmo la describirais?
ApeIIidos: Nombre:
ApeIIidos: Nombre:
Para ver visualmente cmo se altera la frecuencia de la
portadora en funcin de la seal, podemos usar la funcin
stft2d() que visualiza el espectrograma de una seal:
figure; stft2d(IQ,512,fs);
Dibujad la figura resultante. Se aprecia la forma de la seal
original? Qu parmetro de la portadora varia con el tiempo?
Cambiar la variable k por 0.1. Qu cambia en la imagen
resultante? Qu influencia tiene la variable k en el ancho de
banda de la seal FM?
Consideremos ahora el problema de la demodulacin. Lo primero es
recuperar las seales I y Q por separado despus de haberlas
juntado. Para ello hemos escrito la funcin demodula_IQ que
recibe como argumento la seal modulada IQ y devuelve las
seales I y Q por separado:
function [I,Q] = demodula_IQ(IQ,f_local,ph_local,fs)
% Parametros de entrada:
% IQ : seal modulada
% f_local: frecuencia del oscilador local (en Hz)
% ph_local: fase del oscilador local
% fs: frecuencia de muestreo (Hz)
% Parametros salida:
% I,Q: seales I y Q demoduladas.
Apliquemos esta funcin a la seal IQ obtenida anteriormente. En
principio usaremos una frecuencia local de 2000 Hz y una fase de
0, que coinciden exactamente con las usadas al modular:
[I_fm Q_fm]=demodula_IQ(IQ,2000,0.0,fs);
Sabemos que la informacin de la seal est contenida en la fase
(de hecho la derivada de la fase) de los nmeros complejos cuya
parte real es I y parte imaginaria Q. Construyamos dichos nmeros:
R = I_fm + i*Q_fm;
En principio parecera que para recuperar la seal bastara
calcular la fase de R (funcin angle en MATLAB) y diferenciarla:
ph = angle(R); dph = ph(2:end)-ph(1:end-1); plot(dph)
Recuperamos la seal original? Se os ocurre qu est pasando?
El problema es que la fase devuelta por angle() est siempre
entre -pi y pi. Imaginad que en la muestra n la fase esta
creciendo y vale justo pi. Al instante siguiente n+1 la fase vale
(pi + dx), pero la funcin angle() nos devuelve -pi+dx (volviendo
a meterla en el intervalo -pi,pi), lo que es correcto
trigonomtricamente hablando, pero estropea mi derivada. Nosotros
esperbamos hallar la diferencia (pi+dx)-pi = dx y en lugar de
eso calculamos la derivada como (-pi+dx)-pi = -2*pi + dx.
Es posible corregir este efecto en nuestra seal dph. Cada vez
que veamos un gran salto hacia abajo (caso anterior), sumamos 2pi
(y recuperamos el valor deseado dx). Si el salto es hacia arriba,
restamos 2pi. Esto es lo que se denomina phase unwrapping.
Sin embargo hay otro mtodo ms automtico de arreglar las
cosas. Consideremos R(n) = A(n) exp[i phi_n] y el valor anterior
R(n-1) = A(n-1) exp[i phi(n-1)]. Multipliquemos R(n) por el
conjugado de R(n-1):
R(n) R(n-1)* = A(n) exp(i phi(n)) A(n-1) exp(-i phi(n-1))
= A(n) A(n-1) exp[i {phi(n)-phi(n-1)} ]
Luego la fase de dicho nmero complejo es justo la diferencia de
fases buscada {phi(n)-phi(n-1)} y adems no muestra los saltos de
+/- 2pi de antes. Sabiendo que la funcin para calcular el
conjugado es conj( ) en MATLAB, escribir el cdigo necesario para
extraer la seal de esta forma (una lnea) y pintar la seal
resultante. Se recupera ahora a la seal original?
Una de las ventajas de una seal modulada FM es que es muy
resistente a cambios en la frecuencia o fase del oscilador local.
Repetir la demodulacin usando una frecuencia correcta de de 2000
Hz pero con una fase local de pi/2. Despus usar una frecuencia
de 2200 Hz y la fase correcta (0.0):
[I Q]=demodula_IQ(IQ,2000,pi/2,fs);
[I Q]=demodula_IQ(IQ,2200,0.0,fs);
Qu efecto tiene sobre la seal demodulada un desajuste de fase?
Y de la frecuencia?
OPCIONAL: en una hoja aparte, demostrar analticamente los
efectos anteriores de un desajuste en frecuencia o fase del
demodulador FM sobre la seal recuperada:
Demodulacin de una seal BPSK:
Examinaremos ahora la demodulacin de una seal binaria
codificada con modulacin de fase binaria (bit 0 = fase 0, bit 1
= fase pi).
En el archivo IQ_bpsk tenemos una seal binaria (16 bits,
alternando 0 y 1) codificada sobre una portadora de 2000 Hz,
usando la misma frecuencia de muestro (fs=20000 Hz) que antes.
Cargar la seal y usar demodula_IQ para remodularla. En un
principio usaremos una frecuencia y fase en perfecto ajuste con
las usadas al modular:
load IQ_bpsk;
[I Q]=demodula_IQ(IQ,2000,0.0,fs);
Sabemos que idealmente en una modulacin de este tipo los bits
aparecen como 1's (bit = 0 -> fase = 0 -> cos(0) = 1) y -1's
(bit = 1 -> fase = pi -> cos(pi) = -1) en el canal I, mientras
que el canal Q debe mantenerse a cero. Comprobmoslo:
figure; plot(I); hold on; plot(Q,'r'); hold off
Se distinguen claramente los bits? En que rama?
Otra forma muy ilustrativa de visualizar los resultados es
dibujar Q frente a I como la parte real (X) e imaginaria (Y) de
un nmero complejo:
plot(I,Q,'b.','MarkerSize',1); set(gca,'Xlim',[-1 1],'Ylim',[-1 1]);
Como se ve las muestras se concentran en la fase 0 y pi del plano
complejo. Dibujar la figura resultante. A que se deben los
puntos entre las zonas de acumulacin?
La figura anterior muestra todas las muestras (I_n,Q_n) durante
todo el tiempo, superponindolas en un solo grfico. Es muy
instructivo ver como se veran dichas muestras en un osciloscopio
segn van llegando. Para verlo usaremos la funcin show_IQ( ) que
simula un osciloscopio, pintando sucesivas muestras de (I,Q) y
borrando las anteriores:
show_IQ(I,Q);
Describid lo que veis en la pantalla:
Vamos a repetir ahora lo que hicimos antes de utilizar un
demodulador desajustado en frecuencia y/o fase. En primer lugar,
veremos el efecto de un desajuste en frecuencias de 10 Hz:
[I Q]=demodula_IQ(IQ,2010,0.0,fs);
Pintad los canales I y Q como antes y adjuntad la imagen
resultante: aparecen ahora claramente los bits?
Observar ahora los canales (I,Q) con la funcin show_IQ(I,Q).
Describid la evolucin de la seal en el plano (I,Q):
Finalmente repetir con un desajuste en fase del modulador:
[I Q]=demodula_IQ(IQ,2000,1.0,fs);
Pintad los canales I y Q resultantes. Usad show_IQ() y describir
el comportamiento de la seal (I,Q) resultante. Qu podemos
concluir de lo crtico que es la correcta sintonizacin en este
tipo de modulacin comparada con la modulacin FM anterior?
Como curiosidad podis usar show_IQ( ) con las seales I,Q de la
seal modulada FM anterior:
show_IQ(I_fm,Q_fm);
para ver el aspecto de una seal modulada FM en el plano IQ.
Recordad que en la modulacin FM la informacin va en la derivada
de la fase, es decir, en la velocidad de giro del vector IQ en el
plano complejo.
Demodulacin de estacin real FM:
En el archivo IQdata_FM.mat hemos guardado los datos I y Q
obtenidos a partir de una software radio (USRP) sintonizado a una
emisora de radio en la banda de FM (aproximadamente 100 MHz).
El ancho de banda de una emisin FM es de 100 KHz, y la
frecuencia de muestreo usada es de 247.000 muestras/segundo, por
encima del lmite e Nyquist. En total tenemos grabadas unas
2,400,000 muestras, casi 10 segundos de seal.
load IQdata_FM
Como antes, a partir de los datos I y Q construimos un array
complejo cuya parte real sea I y la imaginaria Q:
r = I+i*Q;
Recordando la operacin realizada antes, para demodular una seal
FM, podemos hallar la seal enviada:
x = angle( r(2:end) .* conj(r(1:end-1)) ); % Phase difference
x = 0.9*x/max(abs(x)); % Escalamos para "subir" volumen.
Veamos si hemos recuperado el audio:
sound(x,fs)
Usando ver_tf podemos visualizar el aspecto del espectro de la
seal demodulada:
ver_tf(x,fs,'r','semi');
Representar el grfico que veis indicando los distintos
componentes presentes en la seal x(t):
Segn se aprecia en la TF anterior, la seal consta de varios
otros componentes adems del audio en la banda base. Sin embargo,
no hemos apreciado nada raro al escucharla. Por qu creis que
sucede esto?
Decodificacin del stream de datos RDS
La seal demodulada anterior, adems del audio, contiene un
stream de bits RDS (Radio Data System) en una sub-portadora a
57000 Hz, modulados con el sistema BiPhase Shift Keying
Modulation, en el que cada bit enviado se codifica con uno de los
siguientes smbolos:
La seal resultante de la superposicin de los bits a enviar se
usa para modular en amplitud la portadora de 57 KHz.
Los bits enviados se mandan con una velocidad de 57000/48 =
1187.5 Hz, lo que corresponde a un periodo T = 842 milisegundos
aproximadamente. A la velocidad de muestreo usada en esta
prctica (247000 muestras/segundo) un bit corresponde exactamente
a 247000/(57000/48) = 208 muestras. Como se ve, para decidir si
un bit es un 0 o un 1 deberemos muestrear la seal en +-T/4
(correspondientes a 208/4 = 52 muestras) respecto al centro del
bit y restar los valores obtenidos. Si dicha resta es positiva
tendremos un bit 0, si es negativa un bit 1.
Suponiendo que los bits de nuestro mensaje estn contenidos en
el string data(), lo que en realidad mandamos es el resultado de
una codificacin diferencial de dicho stream, donde el bit k
mandado es un XOR entre el bit (k-1) previamente enviado y el bit
k del mensaje original:
sent(1) = data(1);
for k=1:L, sent(k) = sent(k-1) XOR data(k); end
La decodificacin del mensaje se lleva a cabo haciendo un XOR
entre bits sucesivos del mensaje enviado:
rec(k) = sent(k) XOR sent(k-1)
La consecuencia de esta codificacin es que es irrelevante que
durante el proceso de demodulacin y extraccin de los bits
intercambiemos 0's por 1's. En ambos casos, tras pasar por el
decodificador obtendremos el mismo mensaje.
Comprobad en MATLAB esta propiedad. A partir de la cadena de bits
sent = [0 1 0 1 1 1 0 0 1 0 1 0 1 1 0] ,
decodificar los bits del mensaje original (la funcin de MATLAB
para XOR es bitxor()). Repetir usando como entrada los bits
invertidos (1-sent). Escribir el cdigo usado (una sentencia)
Listar ambas salidas. Son iguales?
Cdigo:
rec1 =
rec2 =
Esta ltima propiedad es importante porque como sabemos un filtro
de tipo Costas puede "engancharse" a la seal en fase
(dif_fase=0) o en contrafase (dif_fase=pi). En el segundo caso el
signo de la seal recuperada se invierte, lo que supondra la
inversin de los bits. El esquema diferencial anterior asegura
que dicha eventualidad carezca de importancia.
Lo primero que vamos a hacer es un filtrado pasobanda de la seal
demodulada FM, centrado en 57 KHz y con un ancho de banda de +/-
3 KHz, para asegurarnos de que slo trabajamos con la seal RDS:
[B A]=fir1(192,(57000+3000*[-1 1])/(fs/2)); % Filtro paso_banda 54 a 60 KHz
rds = filter(B,A,x); % Filtramos x[n]
Para no complicarnos la vida implementando un Costas que se
ajuste a la frecuencia y fase de la portadora vamos a asumir que
la frecuencia nominal de 57000 Hz es correcta y que la fase es 0.
La recuperacin de los bits en la banda I ser:
fc=57000.0; % Frecuencia del observador local
N=length(rds); t=[0:N-1]/fs; % Base de tiempos
I= rds.* cos(2*pi*fc*t); % Rama I del demodulador
Finalmente, un filtrado pasobajo elimina la doble frecuencia
(57000 x 2 = 114 KHz) introducida por la multiplicacin y slo
deja pasar los bits en banda base:
[b a]=fir1(192,2400/(fs/2)); % Filtro pasobajo @ 2400 Hz
I = filter(b,a,I);
Para observar el aspecto de los bits haremos lo mismo que en la
prctica anterior: dibujar su eye-diagram. Para ello, sabiendo
que el ancho de un bit es de 208 muestras y que nuestra seal
contiene 11500 bits (un total de 208 x 11500 = 2392000 muestras),
convertiremos nuestra array en una matriz de 208 filas y 11500
columnas usando reshape, para luego pintar todas esas columnas
(bits) usando plot:
Nbits=11500; BIT_SIZE=208;
r=reshape(I,BIT_SIZE,Nbits); plot(r)
Adjuntad la figura resultante. Creeis que se podrn decodificar
los bits o tendremos altas probabilidades de error?
La frecuencia usada de 57000 Hz es claramente no exacta.
Tanteando he encontrado que una frecuencia de 56999.5 Hz es ms
parecida a la que realmente nos est llegando. Repetir los pasos
anteriores usando la frecuencia anterior y adjuntar el eye-
diagram resultante. Podremos ahora decodificar los bits sin
errores?
Notad que an parece haber un corrimiento de los bits (el cuello
parece que se va desplazando), lo que indica que la frecuencia
usada no es totalmente correcta (o que la frecuencia del emisor o
del receptor oscilaba ligeramente con el tiempo)
Esto resalta la importancia de usar filtros como el Costas o
similares que sean capaces de adaptarse a la frecuencia de la
portadora.
OPCIONAL: decodificacin del mensaje RDS
Finalmente vamos a decodificar el mensaje contenido en esos 11500
bits. Lo primero es determinar el centro del bit en el eye
diagram anterior
A partir del eye-diagram determinar en que posicin cae el centro
de cada bit (aproximadamente). Cul es el resultado? Justificar
vuestra eleccin.
Una vez decidido el centro del bit y recordando la figura
anterior sobre la forma de los bits, sabemos que el paso
siguiente es muestrear a +/- T/4 de dicho centro (T/4 equivalen a
208/4 = 52 muestras a la derecha e izquierda). Luego restaremos
dichos valores y declarararemos un 1 si es positivo y 0 si es
negativo (o viceversa, ya que sabemos que la inversin de bits no
importa).
Notad que al igual que hicimos en la prctica anterior, con la
nueva disposicin de los datos muestraer en un instante de tiempo
es simplemente extraer una columna de la matriz r. Escribir un
par de lneas de cdigo que hagan las operaciones descritas
anteriormente:
Los datos as obtenidos son los enviados, pero no los del mensaje
original. Para llegar al mensaje original debemos deshacer la
codificacin diferencial de la forma explicada antes. Cul sera
el cdigo a usar (1 lnea)?
Por ltimo, para comprobar que todo ha salido correctamente
mandaremos dichos datos a un parser RDS para ver si son
decodificados correctamente. He escrito un sencillo programa
rds_decoder que recibe un array de 1's y 0's como el que habis
generado y descifra los principales mensajes. Aplicarlo. Os
funciona? Qu tipo de mensajes recibimos? De qu emisora y
frecuencia son los datos con los que hemos estado trabajando?
Como ejercicio adicional podis intentar repetir el proceso con
los datos obtenidos de la demodulacin con la frecuencia
incorrecta de 57000 Hz. Se decodifican los datos? Hay errores?
Las pruebas anteriores demuestran lo crtico que puede ser un
desajuste de slo una fraccin de hertzio en un demodulador de
frecuencia no ajustable. Para apreciar lo til que resulta un
filtro de Costas (u otros filtros adaptativos similares) en la
demodulacin de la seal RDS podis usar el programa rds_costas:
Veris que los bits no se mueven, incluso aunque empecemos con
una frecuencia local apartada algunos hertzios de la de la seal.
Podis variar dicha frecuencia local para ver cual sera la zona
de enganche del filtro de Costas y el tiempo que tarda en
engancharse. Yo he probado hasta con una desviacin de unos 100
Hz (w_local = 57100) y el filtro termina enganchndose y pudiendo
decodificar los bits.
Podis tambin probar a usar slo un filtro de 1er orden (ajuste
de frecuencia pero no de fase) o a desactivar el filtro de Costas
para ver como poco a poco (dependiendo del error en frecuencia)
se va desajustando la fase de la seal RDS y el oscilador local.
El la figura adjunta podis ver un aspecto de la aplicacin,
mostrando informacin sobre el desajuste en frecuencias, trmino
de error del Costas, canales I y Q, mensaje decodificado, etc.

También podría gustarte