EPx professional blog and repository for braindumps

2010/01/12

Modulação AM ilustrada

Rádio é uma coisa com a qual eu gostaria de ter mexido, mas ainda não o fiz. Por diversas razões, este interesse acaba sempre em segundo plano frente a coisas mais urgentes, e quem sabe eu nunca brinque com rádio mesmo.

Para um sinal viajar nas ondas de rádio, ele tem de ser modulado, ou seja, transposto para uma freqüência e formato adequados à transmissão. As técnicas de modulação do rádio têm parentesco próximo com informática e telecomunicações, É possível "brincar" com modulação no computador mesmo. É um tema do qual eu confessadamente não entendo muito, mas acho fascinante. E para ser honesto, acho incrível que técnicas aparentemente simples façam o milagre de modular e demodular um sinal.

Neste post, vou ilustrar as técnicas de modulação AM. Quem tiver interesse em aprofundar-se no tema, tente achar o livro "Modem e transmissão de dados", de Fábio de Azevedo Montoro, editora Érica. Apesar de velho, é um dos poucos livros técnicos escritos por brasileiro que presta.

Bem, vamos começar com um sinal de banda-base, ou seja, que ocupa toda a banda disponível a partir de 0Hz. Uma gravação da minha própria voz, pra sacanear com os ouvidos de todo mundo:

(paralelepipedo.wav)

A propósito, estou usando a tag EMBED para colocar o áudio na página. Se não funcionar, você pode pescar os arquivos em http://epx.com.br/wav.

A modulação AM exige que o sinal original ocupe uma banda limitada, de modo que o sinal modulado também "caiba" dentro da banda desejada. Assim, precisamos pegar o sinal original e passar num filtro passa-baixas, até 1000Hz. O resultado é a mesma voz um pouco mais abafada:

(paralelepipedo_lopass.wav)

Para o próximo post, prometo escrever um filtro em Python. Desta vez bateu a preguiça e usei os recursos do Audacity mesmo para fazer a filtragem. Não é perfeito mas é suficiente para nossos fins.

A modulação AM consiste simplesmente em multiplicar o sinal original por uma onda senoidal, a portadora. No caso, escolhi uma portadora de 3000Hz, bem distante da banda ocupada pela minha voz filtrada (1000Hz). O ruído da portadora em si é:

(carrier3000.wav)

O resultado da modulação (voz x apito) é:

(amsc.wav)

Note que a voz e as vogais ficaram agudas e quase irreconhecíveis. A rigor, esta modulação denomina-se AM-SC (AM com portadora suprimida), por razão que logo esclareço.

A modulação faz minha voz mudar de banda: ela passa a ocupar uma faixa de 2000 a 4000Hz. Na verdade, a modulação AM produz duas "cópias" do sinal original: uma ocupando a banda 2000-3000Hz, e outra ocupando a banda 3000-4000Hz. A modulação AM normal "desperdiça" banda pois o sinal modulado ocupa o dobro de espaço que o original.

Mesmo assim, AM é muito útil, pois obviamente eu consigo "mover" a minha voz para qualquer faixa de freqüências que seja conveniente à transmissão. Mais importante que isso: a modulação permite que diversos sinais ocupem o mesmo meio, bastando que cada sinal tenha uma portadora diferente e as bandas não se sobreponham.

Podemos modular em AM "normal":

(am.wav)

Note que o apito da portadora pode ser claramente ouvido. Esta é a modulação utilizada pela rádio AM tradicional.

Segue o programa Python que gerou as modulações AM-SC e AM "tradicional":


#!/usr/bin/env python

import wave, struct, math

baseband = wave.open("paralelepipedo_lopass.wav", "r")

amsc = wave.open("amsc.wav", "w")
am = wave.open("am.wav", "w")
carrier = wave.open("carrier3000.wav", "w")

for f in [am, amsc, carrier]:
f.setnchannels(1)
f.setsampwidth(2)
f.setframerate(44100)

for n in range(0, baseband.getnframes()):
base = struct.unpack('h', baseband.readframes(1))[0] / 32768.0
carrier_sample = math.cos(3000.0 * (n / 44100.0) * math.pi * 2)

signal_am = signal_amsc = base * carrier_sample
signal_am += carrier_sample
signal_am /= 2

amsc.writeframes(struct.pack('h', signal_amsc * 32767))
am.writeframes(struct.pack('h', signal_am * 32767))
carrier.writeframes(struct.pack('h', carrier_sample * 32767))


A modulação AM-SC é simplesmente a multiplicação do sinal original, cuja banda é previamente confinada numa faixa, por uma portadora, que é nada mais que uma onda senoidal.

A modulação AM tradicional é a mesma coisa, exceto que a portadora é adicionada ao sinal modulado, depois da multiplicação. Isto permite que o receptor seja consideravelmente mais simples, conforme veremos.

Bem, agora tá na hora de demodular, ou seja, tentar recuperar o sinal original, usando os arquivos WAV modulados. A demodulação AM-SC consiste em nova multiplicação pela portadora, seguida de um filtro passa-baixas. Segue os resultados, antes e depois do filtro:

(demod_amsc_ok.wav)

(demod_amsc_ok_lopass.wav)

A demodulação AM-SC é essencialmente igual à modulação. O efeito de multiplicar duas vezes pela mesma portadora joga de volta o sinal para sua banda original (0-1000Hz), criando uma nova cópia indesejável em torno de 6000Hz, que removemos com o filtro.

Segue o código do demodulador AM-SC:


modulated = wave.open("amsc.wav", "r")

demod_amsc_ok = wave.open("demod_amsc_ok.wav", "w")
demod_amsc_nok = wave.open("demod_amsc_nok.wav", "w")
demod_amsc_nok2 = wave.open("demod_amsc_nok2.wav", "w")

for f in [demod_amsc_ok, demod_amsc_nok, demod_amsc_nok2]:
f.setnchannels(1)
f.setsampwidth(2)
f.setframerate(44100)

for n in range(0, modulated.getnframes()):
signal = struct.unpack('h', modulated.readframes(1))[0] / 32768.0
carrier = math.cos(3000.0 * (n / 44100.0) * math.pi * 2)
carrier_phased = math.sin(3000.0 * (n / 44100.0) * math.pi * 2)
carrier_freq = math.cos(3100.0 * (n / 44100.0) * math.pi * 2)

base = signal * carrier
base_nok = signal * carrier_phased
base_nok2 = signal * carrier_freq

demod_amsc_ok.writeframes(struct.pack('h', base * 32767))
demod_amsc_nok.writeframes(struct.pack('h', base_nok * 32767))
demod_amsc_nok2.writeframes(struct.pack('h', base_nok2 * 32767))


Um problema da demodulação AM-SC é que a portadora do receptor tem de ser EXATAMENTE igual à do transmissor. Qualquer diferença em fase ou frequência causa distorções graves no sinal. No código acima, procurei simular problemas com moduladora fora de fase (usando seno em vez de cosseno) e com frequência errada (3100Hz em vez de 3000). Os resultados desastrosos podem ser ouvidos abaixo, já filtrados pelo passa-baixas:

(demod_amsc_nok_lopass.wav)

(demod_amsc_nok2_lopass.wav)

Esta necessidade de manter uma portadora precisa no receptor, sem que haja muitos meios de recuperá-la a partir do sinal modulado, acaba tornando o AM-SC uma modulação pouco prática. Um dos poucos usos reais é a trasnsmissão estéro FM, onde o segundo canal é embutido dentro do próprio áudio, com portadora em 38KHz e sinal-piloto transmitido o tempo todo para garantir a perfeita demodulação no receptor.

Vejamos agora o código do demodulador AM tradicional:


modulated = wave.open("am.wav", "r")

f = demod_am = wave.open("demod_am.wav", "w")
f.setnchannels(1)
f.setsampwidth(2)
f.setframerate(44100)

for n in range(0, modulated.getnframes()):
signal = struct.unpack('h', modulated.readframes(1))[0] / 32768.0
signal = abs(signal)
demod_am.writeframes(struct.pack('h', signal * 32767))


Note que este demodulador nem usou seno ou cosseno. Ele é meramente um detector, ou seja, transforma sinais negativos em positivos, o que num rádio real seria feito por um diodo ou ponte de diodos. É isto que permite um receptor AM galena funcionar: basta um diodo e um capacitor.

Segue o resultado antes e depois do filtro passa-baixas:

(demod_am.wav)

(demod_am_lopass.wav)

Ficou um ruidozinho de portadora mesmo na versão filtrada, mas isto se deve muito à filtragem ruim (seria mais fácil filtrar se a freqüencia da portadora fosse muito mais alta que a do sinal original, como é o caso da transmissão de rádio).

Tanto a modulação AM-SC quanto AM tem a séria desvantagem de desperdiçar banda, pois geram duas "cópias" do mesmo sinal ao redor da portadora. Além disso, AM transmite a portadora o tempo todo junto com as cópias. No fim das contas, um transmissor AM gasta 75% da energia transmitindo "bobagens", que não aumentam seu alcance, servem apenas para facilitar o trabalho do receptor.

Mas existe uma forma de resolver isto. Já que o sinal AM-SC possui duas cópias, podemos filtrar uma fora, transmitindo apenas a outra. Isto denomina-se AM-SSB (AM com banda suprimida). Segue o sinal AM-SSB com a cópia inferior (2000-3000Hz) filtrada:

(amssb.wav)

Não parece muito diferente do sinal AM-SC, e de fato o mesmo demodulador AM-SC consegue recuperar a voz original a partir do sinal AM-SSB:

(demod_amssb_ok.wav)

(demod_amssb_ok_lopass.wav)

Além de não desperdiçar nenhuma energia (apenas uma cópia do sinal é transmitida, sem a portadora), o AM-SSB tem uma outra vantagem, ainda mais surpreendente. Veja o que acontece com a voz demodulada com uma portadora fora de fase:

(demod_amssb_nok_lopass.wav)

A voz foi recuperada normalmente. Desta forma, o receptor AM-SSB não precisa se preocupar com a fase da portadora gerada localmente, o que facilita muito as coisas. A freqüência ainda é importannte, qualquer desvio causa a mesma distorção que a observada em AM-SC:

(demod_amssb_nok2_lopass.wav)

AM-SSB é a modulação padrão utilizada pela radiocomunicação em geral (radioamador, polícia, aviação, etc. etc.). Além disso, a mesma técnica básica é utilizada em multiplexadores FDM, no sinal de vídeo da TV analógica, e na transmissão do canal estéreo das rádios FM (o segundo canal é modulado dentro do áudio, com portadora de 38KHz e largura de 19KHz).

A remoção da cópia excedente no transmissor pode ser feita com um filtro analógico, embora seja difícil e caro construir o filtro com as características necessárias. Rádios com processamento digital de sinais podem utilizar uma técnica denominada Transformada de Hilbert, o que dispensa este componente.

2 comentários:

Mark disse...

Este post lembrou das minhas aventuras de 10 anos atrás, como um entusiasta estudando eletrônica e fascinado com essas maravilhas analógicas. Naquela época eu tinha uma paciência enorme para testar circuitos em matriz de contatos e, quando se tratava de radiofrequência, baixar o nível e partir para o percloreto e a solda -- e, claro, sempre ter que refazer soldas e caçar uma ou outra capacitância/indutância parasita: RF sempre teve, para mim, uma certa semelhança bruxaria por causa do número de assombrações afetando as montagens =)

Vez ou outra tenho uma recaída para meu esse lado nerd de hardware e ainda gostaria de brincar com aquelas placas de rádio por software (software defined radio), comandas por programas como o GNU Radio -- a ideia parece boa: agilidade de software para implementação e emoção de hardware para experimentação =) Você já usou algo assim?

PS. Tive que puxar os fones de ouvido aqui para evitar que algum vizinho de audição mais apurada achasse que eu estava pirando -- afinal, que razão alguém em sã consciência teria para ouvir tantos "paralelepípedos"?

EPx disse...

@Mark, nunca mexi com GNU Radio, mas acho do c******, seria o lugar certo para começar, ou recomeçar. Já tem um monte de rotinas prontas pra modulação etc.

Quanto aos 'paralelepípedos', da próxima vez prometo usar um pedaço de música sertaneja, daquelas que o copyright já expirou, bem apropriado para programação AM :)

Postar um comentário