Sensores de ultra som são componentes muito úteis no desenvolvimento de projetos microcontrolados por serem fáceis de implementar e ter uma resposta linear diretamente proporcional a distância em que se encontra de um determinado objeto.
Veremos agora como funciona o sensor de ultrasom DYP-ME007 que pode ser adquirido diretamente da China através do site www.goodluckbuy.com
O Sensor de ultrasom pode detectar objetos a distâncias que variam entre 2 e 350cm de distância com uma precisão de 3mm, sendo que o modelo testado retornou uma precisão de 2mm.
A detecção de distância é feita através do disparo de um pulso de nível alto com duração de 10us no pino de Trigger do sensor, assim que ele detectar este sinal, emite uma sequencia de 8 pulsos na frequência de 40KHz, frequência esta que define o termo Ultra-sônico utilizado na nomenclatura. Após este som emitido “Bater” em algum objeto, retorna e é capturado pelo microfone do sensor para processamento das informações.
A distância “D” corresponde a real distância do objeto, como o sensor recebe a informação de distância de emissão e recepção, obtêm duas vezes a distância real, como a velocidade do som no ar a temperatura média de 25°C é de 340m/s, facilmente se obtém a relação de distância em milímetros através da equação:
Distância = Velocidade * Tempo
2 * Distância = 340 * Tempo
Distância = 170 * Tempo
Todos estes cálculos são efetuados diretamente pelo sensor DYP-ME007 que ao final entrega no pino Echo um pulso ativo correspondente a distância real do objeto como mostra a figura abaixo:
Para se transformar o tempo (us) retornado pelo sensor em distância(mm), basta dividir valor do tempo por 58.
Este valor é obtido da seguinte relação:
Um metro corresponte a um pulso de aproximadamente 5764us, transformando em cm temos 57,64cm que arredondamos para 58 para facilitar os cálculos no microcontrolador.
Este sensor possui quatro pinos de conexão sendo:
VCC – Alimentação de 5V (Consumo médio de 20ma)
GND – Alimentação GND
Trigger- Pino para disparo de leitura (10ms)
Echo – Pino de retorno de informações referente a distância medida
Out – Este pino NÃO deverá ser conectado
Podemos detectar a largura de pulso do sensor de várias maneiras, porém a maneira mais elegante de se fazer isto com microcontroladores PIC, é utilizando o módulo CCP na função CAPTURE.
Para isto temos que conhecer um pouco mais sobre este módulo interno do microcontrolador.
O módulo CCP utiliza os Timers internos do microcontrolador como base de tempo, neste caso específico do modo CCP que é o CAPTURE, é utilizado o TIMER1 incrementando a cada us.
Desta forma quando o módulo CCP detecta a borda alta correspondente ao pino ECHO do sensor, ativa a contagem do TIMER,(incrementeado a cada us) e muda a configuração da borda de sensibilidade para baixa, aguardando assim o término do pulso referente a distância, com isto conseguimos saber qual o período do pulso entrege pelo sensor em já em us.
Após esta informação ser processada temos que alterar novamente a borda de sensibilidade para alta afin de estarmos prontos para uma nova informação proveniente so sensor.
Através do uso deste módulo, trabalhamos apenas com interrupções liberando o microcontrolador para outras tarefas tornando o programa mais eficiente.
Abaixo segue o programa exemplo da placa PK2Lab para uso com estes sensores.
/******************************************************************************
JL Audio Manutenção Eletrônica
Data: 01/2012
Autor: Jean Carlos
Projeto: Sensor de distância DYP-ME007
Microprocessador: PIC18F4550
Clock do processador: 8MHz
Estação de desenvolvimento: PK2Lab V 1.1
Compilador: MikroC PRO V 4.60.0.0
Versão atual:
Descrição:
Este projeto demonstra o uso do sensor de distancia DYP-DM007
Com a placa PK2Lab, o valor referente a distância entre o
objeto e o sensor é exibido no display LCD.
Trigger -> RC0
Echo -> RC2 -> Entrada do módulo CCP1
O resultado da captura é salvo em CCPR1H e CCPR1L
Para efetuar este projeto, iremos configurar o TMR1 como contador
sincrono,para ser incrementado pela fonte de clock externo que é
o cristal de 8MHz conectado a placa PK2Lab(Sem PLL).
8MHz -> (Fosc/4)2MHz -> Prescaler 2:1 -> 1MHz (1uS)
Para calcular a distancia em centimetros, usamos a formula abaixo:
*******************************************************************************/
// Configuração do LCD da placa PK2Lab V.1.1
sbit LCD_RS at RB2_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;
sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
//******************************************************************************
// Definições e Variáveis Globais
#define Trigger RC0_bit
char txt[4]; // Usado para conversão de dados em string
char Tempo_H, Tempo_L, Distancia_cm;
unsigned int Periodo; // Variável que armazena o período do Pulso ECHO
//******************************************************************************
// Funções Auxiliares
void interrupt()
{
if(CCP1IF_bit && CCP1CON.B0) // Captura por CCP1 e borda configurada como subida...
{
CCP1IF_bit = 0; // Limpa a flag para nova captura
CCP1IE_bit = 0; // Desabilita interrupção por periféricos(CCP1)
CCP1CON = 4; // Configura a borda de captura para DESCIDA. (ESTE EVENTO CAUSARIA INTERRUPÇÃO ERRÔNEA)
CCP1IE_bit = 1; // Habilita interrupção por periféricos(CCP1)
TMR1H = 0; // Zera registradores do TMR1 para contagem de tempo
TMR1L = 0;
TMR1ON_bit = 1; // Habilita contagem de tempo.
}
else if(CCP1IF_bit)
{
CCP1IF_bit = 0; // Limpa a flag para nova captura
TMR1ON_bit = 0; // Desabilita contagem de tempo.
CCP1IE_bit = 0; // Desabilita interrupção por periféricos(CCP1)
CCP1CON = 5; // Configura a borda de captura para SUBIDA. (ESTE EVENTO CAUSARIA INTERRUPÇÃO ERRÔNEA)
CCP1IE_bit = 1; // Habilita interrupção por periféricos(CCP1)
Tempo_H = CCPR1H; // Carrega valores de tempo capturado(Neste caso em us)
Tempo_L = CCPR1L;
}
}
Pulso() // Gera o Pulso de trigger para o sensor ultra som.
{
Trigger = 1;
Delay_us(10);
Trigger = 0;
}
//******************************************************************************
//Rotina Principal
void main()
{
TRISC = 0b00000100; // Entrada CCP1
PORTC = 0b00000000;
INTCON = 0b11000000; // Liga interruptores GIE e PEIE
TMR1IE_bit = 0; // Desabilita interrpções de TMR1
CCP1IE_Bit = 1; // Habilita interrupções por CAPTURA(CCP1)
CCP1CON = 5; // Configura módulo CCP1 para CAPTURA e borda de SUBIDA.
T1CKPS1_bit = 0; // Prescaller TMR1 2:1
T1CKPS0_bit = 1;
TMR1CS_bit = 0; // Clock selecionado -> OSC/4
TMR1ON_bit = 0; // Timer -> 1 = Habilita contagem
Lcd_Init();
Lcd_Cmd(_Lcd_Cursor_Off);
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,"*** PK2Lab ***");
Lcd_Out(2,1,"Distancia: cm");
Delay_ms(100);
while(1)
{
Pulso(); // Dispara leitura de distância.
Delay_ms(100); // Intervalo entre leituras.
Periodo = (Tempo_H<<8)+ Tempo_L; // Obtenção do período relativo ao ECHO
Distancia_cm = Periodo/58; // Conversão da distância informada para cm
//------------------------------------------------------------------------------------//
// Um Pulso de 58us corresponde a uma distância de 1cm //
//------------------------------------------------------------------------------------//
// Distância MINIMA 3cm e MAXIMA 3m
if((Distancia_cm < 3)||Distancia_cm >300) Lcd_Out(2,12,"---");
else
{
byteToStr(Distancia_cm, txt); // Converte texto para impressão
Lcd_Out(2,12,txt); // Imprime valores no display
}
}
}
Olá Jean, parabéns pelo projeto!, pergunta: quando entra na interrupção, não fica desativado outra interrupção? é necessário desativar a interrupção? vou olhar o código novamente para ver prioridade de interrupção, valeu! Paulo Roquetti
ResponderExcluirOlá Paulo, eu desativo as interrupções por periféricos para poder mudar a borda de sensibilidade da interrupção, o que ocorre é que sempre que se altera essa borda é gerado errôneamente pelo microcontrolador um evento de interrupção, por isto temos que desabilitar no momento que alteramos essa configuração e logo após podemos reabilitar as interrupções sem que este erro ocorra.
ExcluirExcelente post, Parabéns! Será muito útil.
ResponderExcluirOlá...
ResponderExcluirComo faço para realizar a leitura com um oscilador de 20mhz??
Obrigado desde já
Olá Bruno, você terá que trabalhar com os ajustes de prescaler para garantir 1MHz para o contador, isto pode ser feito inclusive utilizando o oscilador interno dos PICs, dependendo do modelo já temos inclusive 8MHz interno. Grande abraço!
ResponderExcluir