Unidad 4 · Transmisión en banda base y banda pasante · dos PAM en cuadratura, constelación, demodulador y análisis en MATLAB
QAM manda dos PAM a la vez por la misma banda: una sobre un coseno y otra sobre un seno de la misma portadora. Cada símbolo es un número complejo. Su parte real viaja en el coseno, su parte imaginaria en el seno, y el receptor las separa porque el coseno y el seno son ortogonales. Esa ortogonalidad tiene una condición que se olvida fácil: la portadora tiene que estar por encima del ancho del pulso. Todo lo demás —la envolvente compleja, la constelación, el demodulador— sale de escribir bien una suma.
El mapper toma los bits de a grupos y entrega un símbolo complejo:
La parte real y la imaginaria se eligen al azar e independientes. Cada una pasa por su propio filtro transmisor, con el mismo pulso real , y cada rama sube en su propia portadora:
Es la filmina de la cátedra tal cual, con su y su signo menos. Las dos sumas son PAM banda base con el mismo pulso y el mismo reloj —cada una es una modulación PAM completa— y se llaman la componente en fase y la componente en cuadratura:
Con esos nombres la definición se lee corta:
«En cuadratura» quiere decir un cuarto de ciclo corrida: el seno es el coseno atrasado 90°.
Como es real, las dos ramas se pueden juntar en una sola señal compleja, la envolvente compleja:
Es una PAM banda base con símbolos complejos. La filmina recupera la señal real desde ella con el upconverter, , y de ahí sale la definición de la sección anterior, signo incluido.
Paso 1: Euler. La exponencial de la portadora es un coseno y un seno, .
Paso 2: el producto. Se multiplica término a término y se separa lo real de lo imaginario:
El menos sale de : es el producto de las dos partes imaginarias, por el seno, que cae en la parte real con el signo cambiado. No es una convención: es aritmética.
Paso 3: quedarse con la parte real. tira el segundo paréntesis y el multiplica lo que queda. Es la definición.
La filmina muestra dos maneras de armar el transmisor, y son las dos puntas de esta cuenta. Dos multiplicadores reales y una resta no calculan nunca el paréntesis imaginario; un mapper complejo con un upconverter lo calcula y lo descarta en el . Dan la misma .
El está para que la energía de sea la de . Al elevar al cuadrado, , así que el 2 de se come el ½ y queda , más términos que oscilan en . Que esos términos se integren a cero es exactamente la condición de la sección siguiente.
El receptor separa las ramas multiplicando por su portadora y filtrando. Para ver por qué la rama en cuadratura no aparece en la de fase alcanza con un solo pulso: un símbolo en que sólo tiene parte imaginaria. Lo que de él ve el receptor de la rama en fase es la proyección del pulso sobre el seno contra el mismo pulso sobre el coseno:
Paso 1: centrar el pulso. Con , el seno de la suma se abre en dos términos:
Paso 2: el término impar se va. El pulso es simétrico, así que es par, y por un seno es impar: la segunda integral es cero siempre, para cualquier portadora.
Paso 3: la primera es un espectro. La primera integral es la transformada de evaluada en . Normalizada por la energía del pulso:
La transformada de es la convolución de consigo misma, y ocupa el doble de banda que . Si el pulso vive en , su cuadrado vive en , y es cero en cuanto . La condición es
con el ancho unilateral del coseno realzado de rolloff . Por encima, el coseno y el seno son ortogonales sobre cualquier pulso y en cualquier instante . Por debajo, cada símbolo le pasa a la otra rama una fracción de sí mismo, que cambia de símbolo a símbolo con la fase de la portadora. Medido sobre la raíz de coseno realzado de la cátedra —rolloff 0,5, 201 taps, 8 muestras por símbolo—, donde :
| 0,25 | 0,637 |
| 0,50 | 0,159 |
| 0,60 | 0,0406 |
| 0,70 | 1,63 × 10⁻³ |
| 0,75 | −2,3 × 10⁻⁶ |
| 1,00 | 2,1 × 10⁻⁷ |
| 2,50 | −1,1 × 10⁻⁷ |
Por encima de no da cero exacto porque el pulso de 201 taps está truncado y no está estrictamente limitado en banda: el piso es del orden de 10⁻⁷. En mismo vale 2×10⁻⁶, y cinco centésimas de BR más abajo ya vale 1,6×10⁻³, más de setecientas veces más. Es un borde, no una pendiente.
Hay una segunda condición que la frecuencia no arregla: la fase del oscilador del receptor. Un error de fase gira el plano y mezcla las ramas con la portadora tan alta como se quiera. Cuánto, y por qué a 90° la constelación se ve perfecta con la mitad de los bits cambiados, está medido en Dos flujos en la misma banda.
Con niveles por rama hay símbolos. Sin opciones, qammod pone los niveles de cada eje en los impares:
Es una grilla cuadrada de puntos, a distancia 2 entre vecinos: el producto cartesiano de dos PAM de niveles. Cada símbolo lleva bits, la mitad por eje. Y como las dos coordenadas se eligen por separado, el slicer también se parte en dos: my_slicer.m redondea la parte real y la imaginaria cada una a su nivel más cercano.
La energía media sale del mismo reparto.
Paso 1: separar en ejes. , y como los dos ejes tienen el mismo alfabeto, .
Paso 2: la suma de los impares al cuadrado. Cada nivel sale con probabilidad . La suma de los cuadrados de los primeros impares es ; con los positivos y sus espejos negativos:
| M | niveles por eje | bits | con | |
|---|---|---|---|---|
| 4 | 2 | 2 | 2 | 1,414 |
| 16 | 4 | 4 | 10 | 0,632 |
| 64 | 8 | 6 | 42 | 0,309 |
| 256 | 16 | 8 | 170 | 0,153 |
La columna de la devuelve mean(abs(qammod(0:M-1, M)).^2) igual a en las cuatro filas, y tiene que ser así: es la misma suma hecha por MATLAB. La columna que enseña es la última. Con la energía fija, la distancia entre vecinos es , y cada vez que se cuadruplica cae 7,0 dB, 6,2 dB y 6,1 dB. Dos bits más por símbolo cuestan unos 6 dB de relación señal a ruido, y el límite es la regla de bolsillo: con grande, crece como .
Los bits se reparten por eje: la primera mitad del grupo elige el nivel de I y la segunda, el de Q. En cada eje el código es Gray —00, 01, 11, 10—, así que dos niveles vecinos difieren en un solo bit. Los vecinos más cercanos de un punto de la grilla están en su fila o en su columna, y un error hacia cualquiera de ellos cuesta un bit. Los de la diagonal, a distancia , difieren en dos.
Falta decidir hacia dónde se recorre cada eje, y eso lo fija qammod: es lo que usa el transmisor del simulador de la cátedra, transmisor_MQAM.m, y lo que deshace my_ber_checker.m con qamdemod. En I el código va de izquierda a derecha; en Q, de arriba abajo. La 16-QAM queda así, con los bits de I adelante:
| Q \ I | −3 | −1 | +1 | +3 |
|---|---|---|---|---|
| +3 | 0000 | 0100 | 1100 | 1000 |
| +1 | 0001 | 0101 | 1101 | 1001 |
| −1 | 0011 | 0111 | 1111 | 1011 |
| −3 | 0010 | 0110 | 1110 | 1010 |
El PAM-4 de la filmina de modulación PAM usa el orden del eje Q: 00 en el nivel más alto. Armando el mapeo a mano con Q de abajo arriba —la costumbre de recorrer los dos ejes igual— sale la constelación conjugada. Sigue siendo Gray y tiene la misma tasa de error de bit, pero no es la de qammod: leída con qamdemod, el primer bit de Q sale invertido en los dieciséis símbolos. Si los bits de la fuente se mapean así y del otro lado se los recupera con qamdemod, un cuarto de los bits llega mal sin que haya pasado nada en el canal.
La filmina define la eficiencia espectral como bits por segundo por hertz, . Con coseno realzado, la PAM banda base de niveles ocupa y da
QAM ocupa otra cosa. La envolvente compleja vive en la misma banda que la PAM banda base, pero al subirla aparecen las dos mitades de su espectro alrededor de : el ancho pasabanda es , el doble. Como la envolvente es compleja, esas dos mitades no son espejo una de la otra, y las dos llevan información. Con puntos:
Es la misma eficiencia que la PAM banda base con los niveles de un eje: 16-QAM rinde lo que PAM-4. La que pierde es la PAM pasabanda con símbolos reales —DSB, una PAM sobre un coseno solo—, que paga el mismo ancho que QAM y lleva la mitad de los bits. Con rolloff 0,5, en b/s/Hz:
| niveles por eje | PAM banda base | PAM sobre un coseno | QAM |
|---|---|---|---|
| 2 | 1,333 | 0,667 | 1,333 (4-QAM) |
| 4 | 2,667 | 1,333 | 2,667 (16-QAM) |
| 8 | 4,000 | 2,000 | 4,000 (64-QAM) |
Son cuentas cerradas. La medición de los anchos —la envolvente ocupa exactamente la mitad que la señal pasabanda, y QPSK lo mismo que BPSK— está en Dos flujos en la misma banda, y la PSD de la PAM con la que se hace la cuenta, en La modulación PAM.
El demodulador en cuadratura de la filmina deshace el modulador con las mismas dos portadoras: multiplica por en una rama y por en la otra, y filtra cada una con un pasabajos. En la rama en fase, con y :
y en la de cuadratura, con :
Cada rama trae lo que busca en banda base, más una copia de las dos componentes subida a . El pasabajos tiene que dejar pasar y frenar la copia, que empieza en . Eso pide : otra vez , la condición de la sección 03 vista desde el filtro. En la cadena de la cátedra el pasabajos es el filtro adaptado, la misma raíz de coseno realzado del transmisor, que corta justo en : no hay margen, y la condición se cumple o no se cumple.
Juntando las dos ramas en un complejo se ve qué es la copia:
Es la envolvente conjugada. Lo que se cuela cuando el filtro no la frena no es sino , girado por la fase de la portadora en ese instante: una portadora baja no le suma ruido a cada rama por separado, le mete la otra. Qué pasa si directamente se saltea el filtro también está medido en el ensayo.
Con la cadena entera se puede medir el error de recuperación: se manda una tira de símbolos, se sube, se baja, se filtra, se muestrea una vez por símbolo y se compara lo recibido con lo mandado. La métrica es la potencia del error sobre la de la constelación:
Tiene forma cerrada. Los símbolos son independientes y de media cero, y en una QAM cuadrada además , porque los dos ejes tienen la misma potencia y son independientes. Con eso todos los productos cruzados se promedian a cero y quedan dos sumas que dependen sólo del pulso y de la portadora:
Las son las muestras del pulso total —transmisor por filtro adaptado— en los instantes de símbolo, y las las de la imagen que el filtro deja pasar, , con y el retardo del pulso total. La primera suma es la ISI del pulso truncado y no depende de la portadora; la segunda es la imagen. Ninguna depende de , porque la métrica está normalizada por la energía de la constelación. Con la cadena de la sección 09 —el pulso de la cátedra, 8 muestras por símbolo, —, la cuenta cerrada contra la simulación de 10⁵ símbolos de 16-QAM, y cuántos símbolos se deciden mal:
| cerrada | simulada | errores 4-QAM | 16-QAM | 64-QAM | |
|---|---|---|---|---|---|
| 2,50 | 0,0504 % | 0,0505 % | 0 | 0 | 0 |
| 1,00 | 0,0517 % | 0,0515 % | 0 | 0 | 0 |
| 0,80 | 0,0552 % | 0,0554 % | 0 | 0 | 0 |
| 0,75 | 0,0653 % | 0,0654 % | 0 | 0 | 0 |
| 0,70 | 0,565 % | 0,568 % | 0 | 0 | 0 |
| 0,65 | 3,10 % | 3,11 % | 0 | 0 | 0 |
| 0,60 | 8,16 % | 8,11 % | 0 | 0 | 868 |
| 0,55 | 15,6 % | 15,6 % | 0 | 251 | 26 623 |
| 0,50 | 25,0 % | 25,0 % | 0 | 8086 | 55 440 |
| 0,40 | 45,5 % | 45,4 % | 942 | 43 644 | 81 647 |
| 0,25 | 70,7 % | 70,7 % | 19 924 | 66 112 | 90 842 |
| 0 | 100,0 % | 100,0 % | 49 630 | 80 784 | 94 971 |
Por encima de el error se queda en 0,05 %, y ese número no es de la portadora: sin portadora, en banda base, el pulso truncado solo deja 0,0484 %. Es el control. Lo que agrega la portadora arriba de son unas milésimas de punto, lo que se filtra por los lóbulos del pulso truncado. Debajo de el error se dispara: a 0,70 ya es once veces el de 2,5·BR, y a 0,60, ciento sesenta veces. En es 100 %, y es una cuenta exacta: sin portadora el seno se anula, la rama Q no existe, y lo que llega es , con un error del tamaño del símbolo entero.
Las tres últimas columnas dicen lo que no dice. El error es el mismo para las tres constelaciones, pero la distancia entre fronteras no: a 0,60 la 64-QAM ya pierde 868 símbolos de cada 10⁵ mientras 16-QAM y 4-QAM no pierden ninguno, y la 4-QAM aguanta sin errores hasta 0,50. Una constelación más densa pide la condición con más margen, no con menos. Y ninguna simulación de esta tabla lleva ruido: todo lo que se decide mal es una rama metida en la otra.
Arriba de se puede mover la portadora de punta a punta y los tres gráficos cambian de lugar sin cambiar de forma: los lóbulos se corren, la imagen se corre, y la constelación sigue siendo una grilla de puntos exactos. Al cruzar aparecen dos manchas rojas a la vez, una en cada panel, y son la misma cosa vista dos veces: el lóbulo de empieza a pisar a su espejo, y la imagen en empieza a entrar en el filtro. Con 64-QAM las decisiones se rompen antes que con 16-QAM a la misma portadora, con el mismo .
La cadena entera, con la forma de D_basic_tx_and_rx.m: símbolos, upsample, filtro conformador, y del otro lado filtro adaptado y downsample. Lo nuevo es lo del medio, la subida a la portadora y la bajada, que los scripts de la clase no hacen porque trabajan en la envolvente. Usa root_raised_cosine.m y my_slicer.m de la carpeta de scripts de la Unidad 4. Lo que figura como comentario es la salida real de correrlo en R2026a.
%% QAM pasabanda: del símbolo a la portadora y de vuelta clear; close all; clc; %% 1. Parámetros (los de la cátedra, con más muestras para la portadora) M = 16; % 16-QAM L = 1e5; % Largo de la simulación BR = 32e9; % Baud rate N = 8; % Sobremuestreo: la portadora necesita lugar rolloff = 0.5; % Rolloff del conformador h_taps = 201; % Taps: 25 símbolos, como los 101 taps con N = 4 fc = 2.5*BR; % Portadora fs = N*BR; T = 1/BR; Ts = 1/fs; %% 2. Símbolos: qammod contra el mapeo a mano k = (0:M-1).'; ig = [0 1 3 2]; % etiqueta Gray de 2 bits -> posición bI = floor(k/4); bQ = mod(k,4); % primeros dos bits: I; últimos dos: Q a_mano = (2*ig(bI+1).' - 3) + 1j*(3 - 2*ig(bQ+1).'); % Q de arriba abajo a_otro = (2*ig(bI+1).' - 3) + 1j*(2*ig(bQ+1).' - 3); % Q de abajo arriba a_mod = qammod(k, M); a_bits = qammod(int2bit(k, 4), M, 'InputType', 'bit'); fprintf('mano == qammod: %d otro == qammod: %d otro == conj(qammod): %d bits == enteros: %d\n', ... isequal(a_mano, a_mod), isequal(a_otro, a_mod), isequal(a_otro, conj(a_mod)), isequal(a_bits, a_mod)) bits_rx = qamdemod(a_otro, M, 'OutputType', 'bit'); % el otro, leído por la cátedra fprintf('bits cambiados por posición: %s\n', mat2str(sum(reshape(bits_rx ~= int2bit(k, 4), 4, []), 2).')) % mano == qammod: 1 otro == qammod: 0 otro == conj(qammod): 1 bits == enteros: 1 % bits cambiados por posición: [0 0 16 0] for MM = [4 16 64 256] Ea = mean(abs(qammod((0:MM-1).', MM)).^2); fprintf('M = %3d: %d bits, Ea = %.4f, 2(M-1)/3 = %.4f\n', MM, log2(MM), Ea, 2*(MM-1)/3) end % M = 4: 2 bits, Ea = 2.0000, 2(M-1)/3 = 2.0000 % M = 16: 4 bits, Ea = 10.0000, 2(M-1)/3 = 10.0000 % M = 64: 6 bits, Ea = 42.0000, 2(M-1)/3 = 42.0000 % M = 256: 8 bits, Ea = 170.0000, 2(M-1)/3 = 170.0000 rng(1); ak = qammod(randi([0 M-1], L, 1), M); %% 3. Pulso y banda base: upsample y filtro, como en D_basic_tx_and_rx h = root_raised_cosine(BR/2, fs, rolloff, h_taps, 0); h = h(:); h_delay = (h_taps-1)/2; xup = upsample(ak, N); yup = filter(h, 1, [xup; zeros(h_delay,1)]); yup = yup(1+h_delay:end); % envolvente compleja: sI + j sQ %% 4. Subida a la portadora t = (0:length(yup)-1).' * Ts; s = sqrt(2)*real(yup).*cos(2*pi*fc*t) - sqrt(2)*imag(yup).*sin(2*pi*fc*t); %% 5. Bajada: por sqrt(2)cos y -sqrt(2)sen, y el filtro adaptado como pasabajos ri = sqrt(2)*s.*cos(2*pi*fc*t); rq = -sqrt(2)*s.*sin(2*pi*fc*t); h_mf = h(end:-1:1); ymf = filter(h_mf, 1, [ri + 1j*rq; zeros(h_delay,1)]); ymf = ymf(1+h_delay:end); %% 6. Muestreo y error de recuperación p0 = sum(h.^2); % ganancia del par Tx-Rx en el pico ak_rx = ymf(1:N:end) / p0; g = 200; % guarda en los bordes e = ak_rx(g:end-g) - ak(g:end-g); evm = sqrt(mean(abs(e).^2) / mean(abs(ak).^2)); fprintf('fc = %.2f BR: error de recuperación %.4f %% (%.2f dB)\n', fc/BR, 100*evm, 20*log10(evm)) % fc = 2.50 BR: error de recuperación 0.0507 % (-65.90 dB) scatterplot(ak_rx(g:end-g)); %% 7. Barrido de la portadora: simulado contra la cuenta cerrada p = conv(h, h); D = h_taps - 1; % pulso total; el pico está en D jj = -24:24; n = (0:h_taps-1).'; pj = p(D + 1 + jj*N); piso = (sum(pj.^2) - p0^2) / p0^2; % ISI del pulso truncado fprintf('piso sin portadora: %.4f %%\n', 100*sqrt(piso)) fprintf(' fc/BR cerrada %% simulada %% errores 4/16/64 en %d símbolos\n', L) for fcBR = [3 2.5 2 1.5 1 0.8 0.75 0.7 0.65 0.6 0.55 0.5 0.4 0.25 0] w0 = 2*pi*fcBR/N; % imagen en 2fc que el filtro deja pasar: r_j = sum h[n] h[jN+D-n] e^{j 2 w0 n} rj = zeros(size(jj)); for q = 1:numel(jj) m = jj(q)*N + D - n; v = m >= 0 & m < h_taps; rj(q) = sum(h(n(v)+1) .* h(m(v)+1) .* exp(1j*2*w0*n(v))); end evm_c = sqrt(piso + sum(abs(rj).^2) / p0^2); nerr = zeros(1,3); evm_s = 0; for i = 1:3 MM = 4^i; a = qammod(randi([0 MM-1], L, 1), MM); u = filter(h, 1, [upsample(a, N); zeros(h_delay,1)]); u = u(1+h_delay:end); tt = (0:length(u)-1).' * Ts; x = sqrt(2)*real(u.*exp(1j*2*pi*fcBR*BR*tt)); y = filter(h_mf, 1, [sqrt(2)*x.*exp(-1j*2*pi*fcBR*BR*tt); zeros(h_delay,1)]); y = y(1+h_delay:end); y = y(1:N:end) / p0; nerr(i) = sum(my_slicer(y(g:end-g), MM) ~= a(g:end-g)); if MM == 16 evm_s = sqrt(mean(abs(y(g:end-g) - a(g:end-g)).^2) / mean(abs(a).^2)); end end fprintf('%5.2f %10.4f %10.4f %6d %6d %6d\n', fcBR, 100*evm_c, 100*evm_s, nerr) end % piso sin portadora: 0.0484 % % fc/BR cerrada % simulada % errores 4/16/64 en 100000 símbolos % 3.00 0.0517 0.0517 0 0 0 % 2.50 0.0504 0.0505 0 0 0 % 2.00 0.0502 0.0502 0 0 0 % 1.50 0.0504 0.0504 0 0 0 % 1.00 0.0517 0.0515 0 0 0 % 0.80 0.0552 0.0554 0 0 0 % 0.75 0.0653 0.0654 0 0 0 % 0.70 0.5654 0.5683 0 0 0 % 0.65 3.1044 3.1120 0 0 0 % 0.60 8.1563 8.1145 0 0 868 % 0.55 15.6445 15.5986 0 251 26623 % 0.50 25.0018 25.0224 0 8086 55440 % 0.40 45.4590 45.4267 942 43644 81647 % 0.25 70.7104 70.7314 19924 66112 90842 % 0.00 100.0000 100.0031 49630 80784 94971 %% 8. La ortogonalidad, sola: cuánto de g^2 vive en 2fc c = (0:h_taps-1).' - h_delay; for fcBR = [0.25 0.5 0.6 0.7 0.75 1 2.5] kappa = sum(h.^2 .* cos(2*2*pi*fcBR/N*c)) / sum(h.^2); fprintf('fc = %.2f BR: kappa = %+.2e\n', fcBR, kappa) end % fc = 0.25 BR: kappa = +6.37e-01 % fc = 0.50 BR: kappa = +1.59e-01 % fc = 0.60 BR: kappa = +4.06e-02 % fc = 0.70 BR: kappa = +1.63e-03 % fc = 0.75 BR: kappa = -2.25e-06 % fc = 1.00 BR: kappa = +2.08e-07 % fc = 2.50 BR: kappa = -1.12e-07
Cuatro detalles que muerden si no se los conoce:
qammod sin opciones no normaliza. Devuelve niveles impares, con de 10 para 16-QAM. El slicer de la cátedra decide sobre esos niveles, así que lo recibido hay que dividirlo por la ganancia del par transmisor–receptor, p0 = sum(h.^2), y no por la energía.qammod, no el que parece natural. int2bit entrega el bit más significativo primero, y los dos primeros eligen I; el eje Q va de arriba abajo. El bloque 2 lo verifica con isequal, y muestra qué bit se invierte si se lo recorre al revés.g = 200 los deja afuera del promedio, como hace la guarda de my_ber_checker.m.qammod, I de izquierda a derecha y Q de arriba abajo; al revés sale la conjugada.