Escolar Documentos
Profissional Documentos
Cultura Documentos
Sinais
Mestrado Integrado em Engenharia Electrotécnica e de
Computadores
Introdução ao Matlab
Objectivos
Introdução
a manipulação simbólica.
1
http://www.mathworks.com
1
O Matlab existe em várias plataformas e sistemas operativos: Windows, MacOS, Linux
e diversas variantes de Unix (workstations). As várias implementações são bastante
próximas entre si. Iremos apenas abordar a existente no Windows.
Figura 1 Estrutura funcional do Matlab e do Simulink. Imagem retirada da página da Mathworks onde é possível
consultar informação detalhada sobre os vários blocos: http://www.mathworks.com/products/pfo/ .
e que são parte integrante da aplicação “Test & Measurement” que consta da Figura 1.
Estas estão, no entanto, disponíveis nos computadores do laboratório, e na sala LTI do
DEEC.
2
A constituição exacta do pacote oferecido na versão para estudante do Matlab varia um pouco com a versão.
2
Início e conceitos básicos
Figura 2 Janela de funcionamento típico do Matlab e que surge na primeira vez que o programa é executado.
Data Acquisition Toolbox.
É igualmente útil instalar a toolbox “Excel Link” que permite transferir com facilidade
estruturas de dados (variáveis) entre o Matlab e o Excel.
Funções externas – são ficheiros editáveis, com extensão “.m” que executam
uma operação, com uma estrutura similar às funções das linguagens de
programação, como o Pascal ou o C, e com espaço de memória próprio.
Aceitam argumentos e devolvem argumentos – por valor e por referência.
3
Execução em „fornada‟3 - ficheiros com extensão “.m”, que contêm linhas de
O primeiro, disp, é utilizado para visualizar uma matriz sem que o nome do
identificador da mesma seja apresentado, e o segundo, whos, é empregue para mostrar
na janela de comando o conteúdo do espaço de memória geral acessível ao utilizador.
Neste caso, apenas está definida a variável „s‟, assinada na primeira linha de comando
com o conteúdo de uma linha de texto (string). É pertinente observar que no final da
primeira linha de comando, aparece um „;‟. Se este não estiver presente o Matlab
apresenta na linha de comando o conteúdo da variável, neste caso seria o conteúdo de
„s‟.
3
Batch processing.
4
Importa aqui esclarecer que assinar significa atribuir, fixar, determinar, aprazar, dar, designar, marcar, intimar, aplicar,
repartir, distribuir, mostrar, apontar etc e corresponde à forma moderna, pós 1911, do verbo assignar.
4
habitual em linguagens estruturadas como o Pascal ou o C. No Matlab as variáveis são
todas dinâmicas, sendo possível criar, apagar, redimensionar ou modificar a sua
natureza (data type) em qualquer momento, sem que com esse procedimento se torne
instável. Como veremos adiante, por esta extremamente conveniente comodidade, é
necessário “pagar” um preço elevado em termos de desempenho.
Para criar de forma directa uma matriz, por exemplo na linha de comandos, existem
várias possibilidades. Iremos de seguida apresentar alguns exemplos,
2
h = [2;3;4]; …vector coluna 3 .
4
2 3 4
h = [2,3,4;5,6,7;8,9,0]; …matriz bidimensional 5 6 7 .
8 9 0
Tabela 1 Tabela com uma descrição mais pormenorizada dos tipos e estruturas de dados no Matlab.
int8, uint8, Inteiros com ou sem sinal. Alguns tipos de inteiros requerem menor
int16, uint16, espaço de armazenamento que os tipos single ou double. Todos os tipos
uint16(65000)
int32, uint32, de inteiros, com a excepção de int64 e uint64, podem ser empregues
int64, uint64 em operações matemáticas.
5
Data structures, no anglo-saxónico.
6
Data types, no anglo-saxónico.
5
Números de precisão simples (32 bits). Menor espaço de
single single(3 * 10^38)
armazenamento mas menor precisão e alcance inferior.
3 * 10^300 Números de precisão dupla (64 bits). É o tipo de dados que o Matlab
double
5 + 6i utiliza por defeito. Matrizes bidimensionais podem ser esparsas.
a{1,1} = 12; Matriz ou vector de células indexadas, cada uma delas capaz de
cell array a{1,2} = 'Red'; armazenar uma matriz ou vector de dimensão diferente e de tipo de
a{1,3} = magic(4); dados diferente.
a.day = 12; Estruturas de dados por campos no estilo do Pascal e do C. Cada campo
structure a.color = 'Red'; da estrutura pode armazenar uma matriz ou vector de dimensão e tipo
a.mat = magic(3); diferentes.
user class polynom([0 -2 -5]) Objectos construídos a partir de classes definidas pelo utilizador.
Ex. 1
Sol.
>>Fa = 500;
>>t = 0:1/Fa:(1-1/Fa);
>>length(t)
ans =
500
Suponhamos que queremos que o vector dos instantes temporais corresponda não a 1 mas a 2
segundos.
6
Sol.
Neste caso a variável „t‟ é redimensionada para corresponder a um novo vector linha no qual a
primeira metade do vector se mantém inalterada e ao qual é acrescentado uma réplica do
vector adicionado de uma constante, neste caso 1s. Internamente o Matlab elimina a variável
antiga e cria uma nova.
Se em vez de „,‟ tivéssemos utilizado „;‟ em [;], a variável „t‟ seria uma matriz de 2 linhas, com
a primeira linha correspondente aos instantes de 0 a 1-1/Fa e a segunda correspondente aos
instantes de 1 a 2-1/Fa.
ans =
Columns 1 through 10
1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000
Columns 11 through 20
1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000
Column 21
1.0000
7
esta possa conter. É fundamental, depois de adicionadas as directorias, gravar a
configuração utilizando o botão save presente nessa janela.
Sol.
function o = odd(x)
o = mod(x,2);
Pode não ser óbvio como é que esta rotina funciona. Para o Matlab, qualquer número diferente
de zero, se analisado na perspectiva de booleano7, é considerado como verdadeiro. A função
mod devolve o resto da divisão inteira de x por 2, neste caso. Isto significa que apenas se x for
par é que a função mod devolve 0, correspondente a falso, cumprindo as especificações do
enunciado.
function o = odd(x)
7
Booleano é uma estrutura de dados que só pode assumir dois valores: verdadeiro e falso.
8
if mod(x,2) == 0
o = False;
else
o = True;
end
>>daqhelp
>>doc daq
A lista é extensa e não iremos abordar todos os comandos e/ou funções. Iremos apenas
abordar o conjunto de funções e procedimentos necessários para uma aquisição de
sinais relativamente básica.
Um dos primeiros comandos que deve ser executado, prévio ao início de qualquer sessão
de aquisição de dados, é a averiguação de quais placas de aquisição estão disponíveis no
computador,
>>daqhwinfo
ans =
ToolboxName: 'Data Acquisition Toolbox'
ToolboxVersion : '2.9 (R2006b)'
MATLABVersion: '7.3 (R2006b)'
InstalledAdaptors : {2x1 cell}
Esta função é de execução obrigatória a primeira vez que se corre o Matlab após a
instalação de uma nova placa de aquisição. A saída desta função é uma estrutura de
dados que consiste em 4 campos, o mais importante dos quais corresponde ao Installed
9
Adaptors que, no caso do exemplo anterior consiste num vector coluna de 2 células 8.
Para conhecer as designações dos 2 sistemas de aquisição identificados é suficiente
escrever,
>>ans.InstalledAdaptors
ans =
'parallel'
'winsound'
i) Aquisição
>>ai = analoginput('winsound')
Display Summary of Analog Input (AI) Object Using 'Realtek AC97 Audio'.
>>ai = analoginput('nidaq',‟dev1‟)
Display Summary of Analog Input (AI) Object Using „National Instruments PCI-6013‟.
8
Ver Tabela 1.
10
Acquisition Parameters: 1000 samples per second on each channel.
1000 samples per trigger on each channel.
1 sec. of data to be logged upon START.
Log data to 'Memory' on trigger.
>>get(ai)
BufferingConfig = [512 30]
BufferingMode = Auto
Channel = [0x1 aichannel]
ChannelSkew = 0
ChannelSkewMode = None
ClockSource = Internal
DataMissedFcn = @daqcallback
EventLog = [1x0 struct]
InitialTriggerTime = [0 0 0 0 0 0]
InputOverRangeFcn = []
InputType = AC-Coupled
LogFileName = logfile.daq
Logging = Off
LoggingMode = Memory
LogToDiskMode = Overwrite
ManualTriggerHwOn = Start
Name = winsound0-AI
Running = Off
RuntimeErrorFcn = @daqcallback
SampleRate = 8000
SamplesAcquired = 0
SamplesAcquiredFcn = []
SamplesAcquiredFcnCount = 1024
SamplesAvailable = 0
SamplesPerTrigger = 8000
StartFcn = []
StopFcn = []
Tag =
Timeout = 1
TimerFcn = []
TimerPeriod = 0.1
TriggerChannel = [1x0 aichannel]
TriggerCondition = None
TriggerConditionValue = 0
TriggerDelay = 0
TriggerDelayUnits = Seconds
TriggerFcn = []
TriggerRepeat = 0
TriggersExecuted = 0
TriggerType = Immediate
Type = Analog Input
UserData = []
11
Como se pode ver, a lista de propriedades é consideravelmente extensa e completa.
Destas, há algumas que são mais importantes: i) ChannelSkew, ii) InputType, iii)
SampleRate, iv) SamplesPerTrigger, v) TriggerType por serem recorridas mais vezes que
as restantes. É possível saber mais informação sobre a funcionalidade de cada
propriedade escrevendo daqhelp seguido do nome da propriedade,
>>daqhelp channelskew
CHANNELSKEW double
>>propinfo(ai,'channelskew')
ans =
Type: 'double'
Constraint: 'bounded'
ConstraintValue: [0 0]
DefaultValue: 0
ReadOnly: 'whileRunning'
DeviceSpecific: 0
Neste caso, e por se tratar de uma placa de som que, como todas, dispõe de aquisição
simultânea, o atraso entre canais é necessariamente 0 e não pode ser alterado – o valor
mínimo e máximo são iguais.
O passo seguinte para a aquisição de dados via placa de som consiste na adição de um
canal físico. A placa de som dispõe de 2 canais para aquisição – esquerdo e direito que,
numericamente, correspondem aos canais 1 e 2,
Agora que temos criadas estruturas que indexam e programam a placa e os canais de
aquisição que nos interessam, é necessário alterar a frequência de aquisição e o tempo
de aquisição ou número de amostras.
>>set(ai,'samplerate',20000)
Warning: This hardware could not support the requested value of 20000.00 for SampleRate. SampleRate has been set to
22050.00.
Este exemplo de código é em tudo igual ao seguinte, mostrando uma forma alternativa
de alterar as propriedades das estruturas, em particular, da analoginput,
>>ai.SampleRate = 20000;
Warning: This hardware could not support the requested value of 20000.00 for SampleRate. SampleRate has been set to
22050.00.
Neste caso o Matlab avisa-nos que a frequência de aquisição de 20000 amostras por
segundo não é permitida pela placa de som e que colocou a frequência de 22050Aps. De
facto, a limitação pode não ser da placa de som mas resulta antes da propriedade
específica da placa de som, StandardSampleRates, ter o valor On. Com esta propriedade
activa, o conjunto de frequências de amostragem disponíveis é extremamente reduzido
e quase sempre o resultado de 44100/n. As placas de aquisição dedicadas normalmente
não apresentam esta limitação, mas é fundamental, sempre que se altera a frequência
de aquisição, verificar se esta foi aceite pela placa de aquisição e utilizar, em contas
futuras, o valor que ela efectivamente actualiza no campo SampleRate.
Uma vez estabelecida a frequência de aquisição, há que indicar o tempo de aquisição ou,
alternativamente, o número de amostras. Naturalmente que o tempo de aquisição, ,
se relaciona com o número de amostras, , e frequência de amostragem, , pela
relação,
>>ai.SampleRate = 44100/4;ai.SamplesperTrigger=44100/2
Display Summary of Analog Input (AI) Object Using 'Realtek AC97 Audio'.
Embora na placa de som seja irrelevante o tipo de canal utilizado, uma vez que é fixo e
referenciado com gama de entrada de 1V, numa placa dedicada normalmente é possível
alterar o tipo de canal para Differential e ReferencedSingleEnded. A primeira
corresponde a uma entrada diferencial para medida de tensões flutuantes e a segunda
para tensões em que um dos terminais é o comum electrónico da placa de aquisição. Em
algumas placas existem mais variantes mas que, por serem demasiadamente
específicas, não iremos abordar aqui. Em qualquer caso, esta informação está contida no
campo ou propriedade, InputType,
>>ai.InputType
ans =
AC-Coupled
Outra propriedade que neste caso não deverá ser alterada mas que por vezes é
importante configurar é a origem do trigger ou disparo. O disparo, por defeito, é
imediato, i.e., ocorre assim que se dá o comando, start(ai). Não iremos entrar em
pormenores sobre as inúmeras variantes de disparo, mesmo porque muitas são
específicas de cada placa. Contudo, importa referir que com algumas condições de
disparo, e em algumas placas, é possível adquirir amostras anteriores à condição de
disparo, i.e., existe a possibilidade de recuperar pre-trigger data. Na placa de som
iremos utilizar o que vem por defeito,
>>propinfo(ai,'triggertype')
ans =
Type: 'string'
Constraint: 'enum'
ConstraintValue: {'Manual' 'Immediate' 'Software'}
DefaultValue: 'Immediate'
ReadOnly: 'whileRunning'
DeviceSpecific: 0
e que é Immediate.
Como foi indicado anteriormente, este tipo de disparo implica a necessidade de execução
do comando start(ai) para a sua ocorrência,
>>start(ai)
Este comando é relativamente simples e inóquo, mas convém esclarecer que o Matlab
lança a aquisição de sinal mas não fica à espera dos dados. É possível tentar obter os
dados antes de estes estarem terminados, traduzindo-se em incoerência de dados uma
vez que em algumas placas será devolvido o conteúdo de dados da última aquisição.
Para garantir que tal não acontece, é possível bloquear o Matlab adicionando a instrução,
wait,
>>start(ai),wait(ai,3)
14
O segundo argumento de wait é o intervalo de tempo máximo, em segundos, a esperar
(timeout).
>>dados = getdata(ai);
>>whos dados
Name Size Bytes Class Attributes
verificamos que corresponde a uma matriz com 2 colunas. De facto, cada coluna
corresponde ao seu canal. Podemos fazer a visualização simples dos dados adquiridos
fazendo,
>>figure(1),plot(dados)
Se prestarmos atenção aos eixos do gráfico, vemos que nas abcissas temos amostras.
Isso normalmente não é interessante, pretendendo-se, de facto, a identificação do
instante de cada amostra, o que pode ser conseguido, por exemplo, construindo o
vector,
>> t = 0:1/ai.SampleRate:(2-1/ai.SampleRate);
Analisando o conteúdo deste vector observamos que consiste num vector linha com um
comprimento que é o dobro da frequência de amostragem. Nem sempre a configuração
de vector linha é a mais adequada. A transposição do vector pode ser conseguida de
forma extremamente simples recorrendo ao operador ´,
>>t = t‟;
Tendo construído o vector com os instantes temporais é agora simples tornar próprio o
eixo das abcissas, nomeadamente fazer com que corresponda aos instantes temporais,
>>figure(1),plot(t,dados(:,1),t,dados(:,2))
O gráfico criado pode agora ser tornado um pouco mais legível acrescentando uma
grelha, títulos para os 2 eixos, para o gráfico e uma legenda por canal.
Assim, para criar uma grelha, é suficiente utilizar o comando, grid. A adição de um título
para as abcissas pode ser feito utilizando o comando xlabel, e para o eixo das ordenadas
utilizando o comando, ylabel. A inserção de um título geral para o gráfico é feito
utilizando o comando title e a legenda é inserida através do comando legend.
15
O aspecto final do gráfico deverá ser qualquer coisa do género do representado na
Figura 7.
Aquisição Placa de Som
0.5
Esquerdo
0.4 Direito
0.3
0.2
0.1
A/V
0
-0.1
-0.2
-0.3
-0.4
0 0.2 0.4 0.6 0.8 1 1.2 1.4 1.6 1.8 2
t/s
ii) Geração
Vimos até agora como adquirir sinais a partir da placa de som do computador, mas é
igualmente possível enviar sinais para a placa de som. O envio de sinais para a placa de
som permite a audição dos mesmos nos altifalantes do sistema, por um lado, e a
utilização da placa de som como um Arbitrary Waveform Generator recorrendo à sua
saída analógica (line out). À semelhança da entrada (line in), a versatilidade é reduzida.
>>ao = analogoutput('winsound')
Display Summary of Analog Output (AO) Object Using 'Realtek AC97 Audio'.
De forma similar ao que aconteceu para a aquisição de sinal, para a saída é igualmente
necessário especificar o canal físico através da função addchannel,
>>cho = addchannel(ao,[1 2])
16
>>get(ao)
BufferingConfig = [512 2]
BufferingMode = Auto
Channel = [2x1 aochannel]
ClockSource = Internal
EventLog = [1x0 struct]
InitialTriggerTime = [0 0 0 0 0 0]
MaxSamplesQueued = 2.0112e+008
Name = winsound0-AO
RepeatOutput = 0
Running = Off
RuntimeErrorFcn = @daqcallback
SampleRate = 8000
SamplesAvailable = 0
SamplesOutput = 0
SamplesOutputFcn = []
SamplesOutputFcnCount = 1024
Sending = Off
StartFcn = []
StopFcn = []
Tag =
Timeout = 1
TimerFcn = []
TimerPeriod = 0.1
TriggerFcn = []
TriggersExecuted = 0
TriggerType = Immediate
Type = Analog Output
UserData = []
>>putdata(ao,dados)
Neste caso a variável dados é uma matriz com 2 colunas correspondentes aos 2 canais
de saída da placa de som. A geração propriamente dita só tem início após a execução do
comando start(ao), no pressuposto da condição de disparo (triggertype) ser do tipo
immediate.
Ex. 4
17
Sol.
Fa = 44100;
Ta = 5;
ai = analoginput('winsound');
chi = addchannel(ai,[1 2]);
ao = analogoutput('winsound');
cho = addchannel(ao,[1 2]);
ai.SampleRate = Fa;
Fa = ai.SampleRate;
ao.SampleRate = Fa;
ai.SamplesPerTrigger = Ta*Fa;
disp('Aquisição.....');
start(ai);
wait(ai,Ta*1.1);
dados = getdata(ai);
putdata(ao,dados);
ao.RepeatOutput = 1;
disp('Geração.....');
start(ao);
wait(ao,Ta*(ao.RepeatOutput+1)*1.1);
daqreset
18