Misura di Distanza con Ultrasuoni

sensore-di-distanzaSchema con Microcontrollore che Grazie a un Sensore di Distanza ad Ultrasuoni, Permette di Misurare e Visualizzare la Distanza su un Display LCD…

 
 

 
 




 

INTRO

In commercio esistono molti moduli che permettono di misurare grazie agli ultrasuoni la distanza del sensore da un oggetto. Il principio di funzionamento è molto semplice, vi è un altoparlante piezoelettrico che emette un segnale nell’ultrasuono, ovvero 40KHz, e vi è un microfono utile a ricevere il suono riflesso. Infatti il segnale emesso dall’altoparlante, non udibile da persone o animali, rimbalza contro l’oggetto e il suono ci mette un certo tempo a tornare indietro. Il tempo che ci mette a raggiungere il bersaglio e tornare al modulo sarà dato dal doppio della distanza diviso la velocità del suono (34300 cm al secondo) t=((distanza*2)/34300. I sensori di distanza ad ultrasuoni solitamente hanno 4 pin , due per l’alimentazione, uno detto trigger e l’altro detto echo; il primo serve a richiedere la misura, il secondo restituisce un segnale alto per un tempo proporzionale alla distanza. Quindi serve un codice per microcontrollore che effettui una misura di tempo, la converte in distanza e poi visualizza la distanza su LCD.

 




 

MODULO MISURATORE DISTANZA AD ULTRASUONI

Per questo progetto è stato usato il modulo US-015 disponibile su Ebay a pochi euro. L’alimentazione è a 5V con una corrente di 3mA, il modulo non crea un raggio dritto, ma ha un angolo di ricezione di 15°, il che vuol dire che il bersaglio può essere in un raggio di 15°. Ha un raggio di ricezione da 2Cm a 700cm nominali, anche se ci sono problemi da 15Cm in giù e per misure superiori a 4m. in questo range l’errore è 0.3Cm più 1% della distanza misurata ( 200cm misurati hanno un errore di 2.3cm). La temperatura di funzionamento è da 0°C a 70°C, il problema è però che la velocità del suono dipende dalla temperatura, quindi effettuando due misure alla stessa distanza, con temperature molto diverse si potrebbero avere misure di circa 1% diverse, anche meno. I segnali del modulo sono i seguenti:

segnali-us-015 DISTANZA ULTRASUONI

Quindi prima di tutto si invia un segnale alto per almeno 10us sul pin del trigger, internamente dopo questo impulso sul pin di trigger, il modulo genera un onda quadra a frequenza di 40KHz che viene trasmessa dall’altoparlante, il ricevitore riceve l’onda riflessa e in base alla distanza sul pin di echo viene generato un segnale alto dato da (distanza*58)us. Quindi per passare da tempo a distanza, basta misurare il tempo in microsecondi e poi dividere per 58.

 

CODICE

Il codice è il seguente:

#define Hi(param) ((char *)&param)[1]       //definizione funzione Hi
#define Lo(param) ((char *)&param)[0]       //definizione funzione Lo

sbit LCD_RS at RB7_bit;                     //Definizione libreria LCD
sbit LCD_EN at RB6_bit;
sbit LCD_D4 at RB5_bit;
sbit LCD_D5 at RB4_bit;
sbit LCD_D6 at RB3_bit;
sbit LCD_D7 at RB2_bit;                     //Fine definizione libreria LCD

sbit LCD_RS_Direction at TRISB7_bit;        //Configurazione I/O per LCD
sbit LCD_EN_Direction at TRISB6_bit;
sbit LCD_D4_Direction at TRISB5_bit;
sbit LCD_D5_Direction at TRISB4_bit;
sbit LCD_D6_Direction at TRISB3_bit;
sbit LCD_D7_Direction at TRISB2_bit;        //Fine configurazione I/O per LCD

unsigned int Distanza;                      //Variabile distanza
char TXT[7];                                //Testo distanza
unsigned short int trigger = 0;             //Variabile trigger

void EXT_INT() iv 0x0008 ics ICS_AUTO {     //Interrupt fronte di salita di echo
  TMR1L = 0;                                //Resetto timer
  TMR1H = 0;                                //Resetto timer
  PIR1.CCP1IF = 0;                          //Resetto flag modulo ccp1
  INTCON3.INT1IF = 0;                       //Resetto flag interrupt
}

void main() {                               //Programma principale

  CCP1CON = 0b00000100;                     //Capture ogni fronte di discesa

  TRISB = 0b00000010;                       //Portb uscite tranne int1
  TRISC.B1 = 0;                             //Uscita trigger
  TRISC.B2 = 1;                             //Ingresso modulo CCP1

  Lcd_init();                               //Inizializza lcd
  Lcd_cmd(_LCD_CLEAR);                      //Pulisci lcd
  Lcd_cmd(_LCD_CURSOR_OFF);                 //Disattiva cursore lcd

  T1CON = 0b10000001;                       //tmr1 on, clock int, prescaler 1

RCON.IPEN = 0;                              //disabilito la priorità degli interrupt
INTCON.GIE = 1;                             //attivo gli interrupt

INTCON2.INTEDG1 = 1;                        //interrupt sul fronte di salita
INTCON3.INT1IE = 1;                         //Abilita interrupt

Delay_ms(500);                              //Delay 0.5S

while(1){                                   //Ciclo infinito
 if(trigger == 0){                          //Se non si è gia inviato un trigger...
  PORTC.B1 = 1;                             //Impulso di trigger
  Delay_us(10);                             //Durata 10uS
  PORTC.B1 = 0;                             //Spegni impulso
  trigger = 1;                              //Segnala che si è inviato il trigger
  }

    if (PIR1.CCP1IF == 1){                  //Se fronte di discesa echo (capture)...
      Lo(Distanza) = ccpr1l;                //Unisci ccpr1l alla variabile
      Hi(Distanza) = ccpr1h;                //Unisci ccpr1h alla variabile
      Distanza = Distanza / 116;            //Converti in centrimetri
        
      IntToStr(Distanza, TxT);              //Converti in stringa la distanza
      Lcd_Cmd(_LCD_CLEAR);                  //Pulisci LCD
      Lcd_Out(1, 1, "Distanza [Cm]");        //Stringa prima riga
      Lcd_Out(2, 6, TxT);                   //Stringa distanza su seconda riga
        
      PIR1.CCP1IF = 0;                      //Resetta flag capture
      Delay_ms(500);                        //0.5S prima di una nuova misura
      trigger = 0;                          //Prepara nuovo invio trigger
    }
 }//fine ciclo infinito
}//fine

Nelle prime due righe si definisce la funzione di concatenazione di due numeri a 8 bit, poi si dichiara l’interfaccia dell’LCD e tre variabili, una per la distanza, una per il testo e l’altra per la conferma dell’invio del trigger.

Dopo di che viene inizializzata la subroutine di interrupt nella quale si resetta il timer counter e i flag, questa routine parte sul fronte di salita del segnale echo.

Nel programma principale, prima di tutto si inizializza il modulo capture e gli ingressi uscite; l’ingresso del modulo CCP1 è settato ingresso e anche quello per l’interrupt INT1 mentre il pin dove collegare il trigger è un uscita. Dopo di che si inizializza LCD e timer counter 1 con lunghezza a 16bit, prescaler 1:1 e si accende.

Dopo di che si attivano gli interrupt senza priorità e INT1 sul fronte di salita. Per quanto riguarda il timer counter, si è pensato di utilizzare un quarzo da 8MHz, quindi il counter conta ogni 0.5us visto che si ha un prescaler 1:1. Quindi se il timer counter conta 3000 vuol dire che sono trascorsi 1500us in realtà.

Nel programma principale si ha un ciclo infinito nel quale prima di tutto si va a controllare se si è inviato un impulso di trigger o no, se non si è inviato si invia ovvero si pone a 1 l’uscita, poi si aspettano 10us e poi si pone a 0 l’uscita e si informa che si è giaà inviato il trigger.

Dopo di che si avrà il fronte di salita del segnale di echo e il ciclo di interrupt resetta il timer counter, dopo un certo istante si avrà il fronte di discesa del segnale echo, quindi il modulo capture setta il flag CCPIF uguale a 1 e conserva il valore del timer counter. Questo valore è dato da due numeri a 8 bit che vengono uniti e una volta uniti si va a dividere per (58*2), 58 per convertire da tempo a distanza e il 2 perché il timer counter conta 2 ogni microsecondo.

Il valore di distanza viene convertito in stringa, viene pulito l’LCD e si scrive sulla prima riga una stringa e sulla seconda il valore della distanza. Dopo di che si aspetta mezzo secondo e si resettano i flag in modo tale che l’operazione di misura possa ricominciare.

 




 

SCHEMA

Lo schema è il seguente:

schema MISURATORE DISTANZA ULTRASUONI

Il cristallo X1 è un quarzo da 8MHz e con i due condensatori da 22pF formano il circuito di oscillazione. La resistenza R4 serve per evitare che il PIC18F252 si resetti, mentre ai pin 20 si hanno 5V e ai pin 19 e 8 la massa dell’alimentazione.

Il modulo US-015 è alimentato anch’esso a 5V e anche il display LCD, mentre si fornisce una tensione per regolare il contrasto dell’LCD grazie alla resistenza RV1.

Al pin 13 e al pin 22 è connesso il segnale di echo dal modulo mentre al pin 12 il trigger.

La configurazione dei fuses è la seguente:

fuses-sesore-distanza-ad-ultrasuoni

È tutto disabilitato tranne il brownout reset e l’oscillatore è in configurazione HS con quarzo a 8MHz.

Il circuito montato su breadboard ha la seguete configurazione:

misuratore-distanza-ultrasuoni-montato-su-breadboard

 

DOWNLOAD

È possibile scaricare la simulazione, il file .hex e il file .c al seguente LINK!!!




 

[Voti Totali: 0 Media Voti: 0]
Segui la Nostra Pagina Facebook: Facebook

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *