_______________________________________________________
Trabalho III
Trabalho realizado por:
André Cunha, nº53757
João Romão, nº67919
Lisboa, 24 de março de 2016
Introdução
Um sonar (Sound Navigation and Ranging) é um aparelho de medida que permite
determinar a distância em relação a um alvo através de ondas sonoras de alta frequência,
utilizado essencialmente como auxiliar de navegação marítima.
Este projecto consiste na elaboração de um sonar activo, isto é, o sonar emite uma onda
e espera pelo retorno do eco. Posteriormente, realizam-se cálculos que convertem o
tempo cronometrado entre a emissão e recepção na distância entre o sonar e o objecto
que causou a reflexão da onda.
Numa primeira abordagem, a distância foi medida tendo em conta a diferença de fase
entre as ondas emitida e reflectida. Porém este método é limitado e foi substituído pelo
método convencional supracitado.
O projecto consistiu então em programar um microcontrolador de forma a configurar o
funcionamento do sonar, ou seja, criar a onda de alta frequência, registar a diferença de
tempo entre a emissão da onda e o regresso do eco e, por fim, calcular a distância.
Projecto e implementação do processo de aquisição
Pretende-se inicialmente criar um PWM com uma frequência de 40 kHz. Relembrando
que a frequência do cristal do microprocessador, fOSC, é de 117.9648 MHz, define-se o
período do timer2 como 734 contagens, para se obter a frequência desejada.
fPWM =
fOSC
⇡ 40.178kHz
4(1 + T2 )
Impõe-se então esse sinal ao sensor do sonar de forma a que este emita ondas sonoras
com essa frequência. O propósito do sonar é medir a distância entre um objecto e os
sensores. Numa primeira abordagem utiliza-se a diferença de fase entre a onda emitida e
a sua reflexão para determinar essa distância. Para tal é necessário calcular o
comprimento de onda associado a essa perturbação.
=
v
340 m/s
=
⇡ 8.65 mm
f
40 kHz
Ora, um comprimento de onda está associado a uma onda completa, porém a distância
percorrida pela onda será apenas uma fracção deste comprimento de onda.
d=
⇤
2⇥
Contudo, a distância d corresponde ao percurso de ida e volta da onda, que é o dobro da
distância D a que o objecto está do sonar.
D=
d
⇤
=
2
4⇥
Para medir a diferença de fase, observam-se ambos os sinais no osciloscópio e adquire-se
a informação necessária.
Iniciou-se então uma nova abordagem para medir distâncias através do sonar. O
procedimento consiste em emitir um pacote de ondas e contar o tempo até ao retorno
do eco.
!
Projecto e implementação do processo de aquisição
O circuito apresentado constitui o sonar. Realiza-se agora uma breve análise conceptual
ao mesmo.
O ampop A1 é um seguidor de tensão que garante uma impedância de saída mínima após
o divisor de tensão constituído pelas resistências R7 e R8. Essa tensão serve de referência
para os ampops A2 e A3, que estão isolados de qualquer contribuição de corrente DC
devido à presença dos condensadores C7 e C8 e têm uma configuração amplificadora
inversora com ganhos -R9/R11 e -R10/R12, respectivamente.
O último amplificador, A4, faz a comparação entre os sinais de ambos os sensores e não
é retro-alimentado, pelo que tem uma forte probabilidade de saturar quando recebe um
impulso.
Acrescenta-se ainda que o emissor SENS1 é alimentado por sinais simétricos de forma a
maximizar a potência aplicada no cristal piezoeléctrico, que converte sinais eléctricos em
vibrações.
É portanto necessário programar o microcontrolador através da implementação de um
código, cujo funcionamento vai ser descrito de seguida, para configurar o sonar.
Com o objectivo de criar um PWM com uma amplitude de 10V foi necessária a
elaboração de dois sinais quadrados desfasados, como indica a figura. O output controler
OC3, a azul, aplica uma tensão de +5V e o OC4, a vermelho, aplica uma tensão de -5V.
Ou seja, há uma alternância entre +5V e -5V de forma a criar a amplitude desejada.
O timer2 controla os OC3 e OC4, pelo que podemos configurar o número de ondas
emitidas através da função de interrupt. Há uma variável, ‘contadorT2’ que conta o número
de vezes que o timer2 reinicia, quando esta se torna superior a 20, isto é, depois de emitir
20 pulsos, interrompe o ciclo de emissão de ondas e inicia o timer3 .
O tempo do timer3 (t3) é registado no input capture IC1 cada vez que um eco é detectado e,
caso o contador chegue ao fim e reinicie, há uma variável que interrompe o ciclo que
controla a espera pelo eco.
Projecto e implementação do processo de aquisição
A distância do objecto é calculada em função deste contador, tendo em conta o factor de
pre-scaler de 256.
D=
1 256 · 4 · 340 3
t3
10 mm
2
fOSC
3
t3 mm
2
Tendo em conta que o timer3 tem conta até 65535, o alcance do sonar é
aproximadamente 98.3 m.
Como foram emitidos 20 pulsos, array ‘IC1buffer’ guarda 20 valores do timer3 e a variável
‘contadorIC1’ indica a quantidade de pulsos que regressaram. Portanto, quando esta chega
a 20 o timer3 é interrompido e o programa procede à determinação da distância do
objecto. Por fim o programa converte a média dos valores registados em ‘IC1buffer’ numa
distância e imprime-o na porta série.
É ainda utilizada uma função para criar um tempo de espera de 100 ms e o programa
reinicia e imprime um novo valor na porta série.
#include
#include
#include
#include
#include
#include
#include
registo dos dspics
biblioteca standard de IO (Input/Output) em C
definições do compilador C30
biblioteca UART (porta série)
biblioteca do timer
// frequência de instruções em kHz
//Configuration bits
_FOSC(CSW_FSCM_OFF & XT_PLL16);
_FWDT(WDT_OFF);
char RXbuffer[80];
int str_pos = 0;
int IC1buffer[20];
int contadorIC1 = 0;
int contadorT3 = 0;
int contadorT2 = 0;
int controlo = 0;
int controlo2 = 0;
// oscilador a 16x PLL
// desligar o watchdog timer
// buffer para armazenar informação da porta série
// posição no RXbuffer
/* declaração da função delay_ms */
void delay_ms(unsigned int delay);
// atraso em milisegundos
void main(void)
{
unsigned int UMODEvalue, U2STAvalue;
int i, periodo2 = 734, periodo3 = 65535;
int IC1media = 0;
int distancia_objecto;
Desligar o timer
Definir o número de bits ate voltar ao inicio da contagem
Usar o clock interno
Prescaler 1:1
/* Configuração do Timer 3 */
T3CONbits.TON =0;
// Desligar o timer
PR3 = periodo3;
// Definir o numero de bits ate voltar ao inicio da contagem
T3CONbits.TCS = 0;
// Usar o clock interno
T3CONbits.TCKPS = 3;
// Prescaler 1:256
/* Interrupções
IEC0bits.T2IE =
IPC1bits.T2IP =
IEC0bits.T3IE =
IPC1bits.T3IP =
dos Timers 2 e 3*/
1; // Permite a interrupção do Timer 2
3; // Prioridade de interrupção do Timer 2
1; // Permite a interrupção do Timer 3
2; // Prioridade de interrupção do Timer 3 interrupt priority
// Caso o eco não regresse
// desliga o Timer
// desliga a interrupção
// desliga o Timer
// desliga a interrupção
for (i = 1; i <= 20; i++) {
IC1media += IC1buffer[i];
}
IC1media /= 20;
distancia_objecto = IC1media * 3/2; // 1/(16*Fcristal)*256*4*346*10E3 mm
printf ("\n\r%d", distancia_objecto);
for (i=0; i<80; i++) { RXbuffer[i] = '\0'; }
str_pos=0;
delay_ms(100);
}
/****************************************************
*
*
*
Funcoes auxiliares
*
*
*
****************************************************/
/* This is T2 interrupt handler*/
void __attribute__((__interrupt__,auto_psv)) _T2Interrupt(void) {
contadorT2++;
if(contadorT2 >= 20) {
T2CONbits.TON = 0;
// desliga o Timer
controlo = 1;
}
IFS0bits.T2IF = 0;
// reinicia a flag de interrupção T2
}
/* This is T3 interrupt handler */
void __attribute__((__interrupt__,auto_psv)) _T3Interrupt(void)
{
contadorT3++;
// por cada volta passaram 2^16*8.5*10^(-9)*256*346=49.342 metros (ida e volta)
IFS0bits.T3IF = 0; // reinicia a flag de interrupção T3
}
/*This is IC1 interrup handler*/
void __attribute__((__interrupt__,auto_psv)) _IC1Interrupt(void) {
contadorIC1++;
IC1buffer[contadorIC1] = IC1BUF;
IFS0bits.IC1IF = 0;
// reinicia a flag de interrupção IC1
}
/* 1ms delay function */
void delay_ms(unsigned int delay) {
unsigned int cycles;
for(;delay;delay--)
for(cycles=FCY;cycles;cycles--);
}
// quantidade de ciclos
// ciclo de ~1ms
// This is UART2 receive ISR
void __attribute__((__interrupt__,auto_psv)) _U2RXInterrupt(void) {
// reinicia a flag de interrupção Rx2
IFS1bits.U2RXIF = 0;
// Ciclo de leitura do buffer
while(U2STAbits.URXDA) {
RXbuffer[str_pos] = U2RXREG;
str_pos++;
if(str_pos >= 80) {str_pos = 0;}
}
}
Testes
Através da diferença de fase não foi possível medir com precisão nenhuma distância
relevante, como se observa neste exemplo.
V
5
4
3
2
1
0.01
0.02
0.03
0.04
0.05
t ms⇥
Verifica-se que o sinal azul, que representa o eco, está deformado e cerca de 6 µs
atrasado em relação ao sinal original (a vermelho). O que representa uma distância de
aproximadamente 1 mm.
Esta abordagem é limitada, pois só é possível medir diferenças de fase até 2π, pelo que o
alcance máximo deste modo de funcionamento é apenas metade do comprimento de
onda.
2
⇡ 4.325 mm
Já com o programa elaborado para contar o tempo que o eco demora a retornar foi
medido inicialmente a distância entre a mesa de trabalho e o tecto, que é cerca de 1.7 m.
O valor medido variou ligeiramente, mas foi registado como 1740 ± 4 mm, o que é
bastante próximo do valor esperado.
De seguida fez-se um registo de um movimento oscilatório. Utilizou-se uma placa de
acrílico flexível numa posição horizontal e com um ponto de apoio a cerca de 50 cm de
uma das extremidades. Aplicou-se um impulso de forma a gerar uma oscilação e
registou-se a altura da placa em relação ao sonar.
O instrumento registou a posição da placa aproximadamente a cada 100 ms, que
corresponde ao tempo imposto na função delay_ms. Há então que ter em conta o erro do
sonar a determinar a posição e o erro do tempo entre cada ponto adquirido. Portanto
assumiu-me que cada medição teria um erro de 2.5 mm. Procedeu-se então a um ajuste
experimental de um movimento oscilatório atenuado.
z(t) = h + Ae
t
cos(2 f t
⇥)
Em que h representa a altura de equilíbrio, A é a amplitude, λ o coeficiente de atenuação,
f a frequência de oscilação e φ a fase inicial.
Fit report produced with the fit results of function:
y=a + b*exp(-l*x)*cos(2*pi*f*x-p)
to the 30 experimental points, considering 5 free parameters.
report 1.0
fitteia
a = 53.655 ± 0.45833
b = 33.84 ± 1.9243
l = 0.70575 ± 0.063229
2
z (mm)
LATEX@ http://lince.ist.utl.pt, IST, Departamento de F´ısica (printed on Friday 8th June, 2012)
Abstract
85
80
75
70
65
60
55
50
45
40
35
30
f = 2.7759 ± 0.010087
p = 4.1797 ± 0.052872
[1] = 34.5521
2
t
= 34.5521
h = 53.66 ± 0.46 mm
A = 33.84 ± 1.92 mm
= 0.71 ± 0.06 s
1
f = 2.78 ± 0.01 Hz
⇥ = 4.12 ± 0.05
⇤2 = 34.55
0.5
1.0
1.5
t (s)
recta.pdf
2.0
2.5
3.0
⇤2
= 1.33
gdl
A frequência obtida é inferior a 3 oscilações por segundo, o que está de acordo com as
observações experimentais. O valor de χ2 por grau de liberdade (gdl) é próximo de 1, que
indica a qualidade do ajuste, pelo que o modelo teórico representa com fidelidade a
realidade.
Ou seja, o sonar fez uma aquisição correcta do movimento e por isso foi possível aplicar
o modelo teórico do movimento oscilatório atenuado aos dados experimentais.
Conclusões
Através da diferença de fase é apenas possível medir correctamente objectos a distância
muito pequenas, inferiores ao centímetro. A única possibilidade de aumentar o alcance é
contar o número de ondas completas emitidas até ao retorno do eco, porém contar o
tempo é mais eficaz.
Foi exactamente através da cronometragem do tempo entre a emissão e recepção de
ondas no sonar que se determina a distância. Neste modo de funcionamento, o alcance
teórico do sonar é quase 100 m, supondo que tem potência suficiente no processo de
emissão de ondas para que o ecos destas seja detectável.
A medição da distância tem um erro associado, que varia com a distância dos objectos.
Por exemplo, a 2 m o erro é aproximadamente 4 mm e a 50 cm estimou-se uma imprecisão
de 2.5 mm.