Measure Distance Using Ultrasonic Sensor


 
URM37 V3.2 Ultrasonic Sensor uses an industrial level AVR processor as the main processing unit. It comes with a temperature correction which is very unique in its class.
Specification
 Power: +5V
Current: <20mA
Working temperature: -10℃~+70℃
Detecting range: 4cm-5m
Resolution: 1cm
Interface: RS232 (TTL), PWM
Servo control: One servo control output
Operating Mode: Serial (PWM) passive control mode; Autonomous Mode; On/OFF Mode
Temperature sensor: 12 bits reading from serial port
Size: 22mm × 51 mm
Weight: 30g


1: +VCC - +5V Power
2: GND - Ground
3: RST - Reset
4: PWM - PWM Output 0-25000US,Every 50US represent 1cm
5: MOTO - Servo control signal output
6: COMP/TRIG
COMP - On/OFF mode, when the detecting distance is smaller than a pre-set value, this pin pulls low.
TRIG - PWM or RS232 trigger pin
7: PWR_ON - Enable pin, enable the sensor when high
8: RXD - RS232,TTL communication
9: TXD - RS232,TTL communication



Circuit Diagram



/***********************************************************\                                                                              * Distance meter using ulrtasonicsensor                                 
*
*  Snesor: URM37 Vs 3.2                                    
*  Microcontroller: 16f877a | Oscillater: 20 Mhz            
*  Used modules: Capture Compare PWM 1 (CCP1)          
*  Display Method: 16x2 LCD                                          
\***********************************************************/

 // LCD module connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;

unsigned tOld, tNew;
char edge = 0;
char capture = 0;
unsigned tword;
unsigned distance;
int i;

//Functions
void interrupt();
char int_to_char(int key_n);

//main function
void main() {

  int no1,no2;
  char display[7];
  char display1[7];
  Lcd_Init();                        // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);               // Clear display
  Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off

  TRISC = 0;        // assign PORTC as output
  TRISC.B2 = 1;     // RC2 must be input
  T1CON = 0x1;      // Timer1 ON, internal clock Fosc/4
  INTCON.GIE = 1;   //Inable Global Interrupts
  INTCON.PEIE =1;   //Enable Peripheral Interrupts
  PIE1.CCP1IE = 1;  // enable interrupt capture
  TRISD=0;
  PORTD=0;
  CCP1CON = 0x04;   // Capture mode every falling edge

  Lcd_Out(1,1,"   Measure the    ");
  Lcd_Out(2,1," distance  using  ");
  Delay_ms(2000);
  Lcd_Out(1,1,"   Ultrasonic     ");
  Lcd_Out(2,1,"     Sensor       ");
  Delay_ms(2000);
  Lcd_Cmd(_LCD_CLEAR);
  Delay_ms(3000);

  Lcd_Out(1,1,"Distance is:");       //Display Charactors on the LCD

 while(1){       //Start never ending while loop

  if(capture){
  PIE1.CCP1IE = 0; // disable interrupt while processing
  capture = 0;     // clear flag

  // Calculate length of pulse from rising edge to rising edge
  tword = ~tOld + tNew+1;
  // tword contain length of pulse in micro second
  distance=tword /50;      // 50 us = 1cm
  distance=distance/5;


  /* Here IntToStr function has not used to convert intiger numbers to string (Only string can display on LCD). */
  /* Therefore user defined int_to_char function has used                                                       */

  no1=distance%10;
  no2=distance/10;

  for(i=2;i<=4;i++){
  display[i]=int_to_char(no1);
  no1=no2%10;
  no2=no2/10;
  }
  display[5]=int_to_char(no1);

  //Display distance on the LCD (This can be simply relaced by a forloop)
  Lcd_Chr(2,6,display[5]);
  Lcd_Chr(2,7,display[4]);
  Lcd_Chr(2,8,display[3]);
  Lcd_Chr(2,9,display[2]);

  Lcd_Chr(2,11,'c');
  Lcd_Chr(2,12,'m');


  PIR1.CCP1IF = 0; // clear CCP flag
  PIE1.CCP1IE = 1; // enable interrupt

 }

}// End of while

} // End of main

void interrupt() {

if(PIR1.CCP1IF==1){          //Check CCP1 enterrupt

if(!edge){
tOld = (256*CCPR1H)+CCPR1L; // keep starting value
edge = 1;
PIE1.CCP1IE = 0;            // disable interrupt for change
CCP1CON = 0x05;             // Capture mode every rising edge edge
PIE1.CCP1IE = 1;            // Enable interrupt capture

}else{
tNew = (256*CCPR1H)+CCPR1L; // Keep ending value
capture = 1;                // Complete capture, set a flag
edge = 0;
PIE1.CCP1IE = 0;           // disable interrupt for change
CCP1CON = 0x04;            // Capture mode every falling edge
PIE1.CCP1IE = 1;           // Enable interrupt capture

}

PIR1.CCP1IF = 0; //Clear CCP flag
}
}

 //Function to convert integer values to char
 char int_to_char(int key_n){

           char key_c_n[1];

           if(key_n==0){
           key_c_n[0]='0';
           } else if(key_n==1){
           key_c_n[0]='1';
           } else if(key_n==2){
           key_c_n[0]='2';
           } else if(key_n==3){
           key_c_n[0]='3';
           } else if(key_n==4){
           key_c_n[0]='4';
           } else if(key_n==5){
           key_c_n[0]='5';
           } else if(key_n==6){
           key_c_n[0]='6';
           } else if(key_n==7){
           key_c_n[0]='7';
           } else if(key_n==8){
           key_c_n[0]='8';
           } else if(key_n==9){
           key_c_n[0]='9';
           }
           return key_c_n[0];
           }  //End of the function

2 comments :

  1. can u told me how the simulator device u used in Proteus instead of the sensor

    thanks

    ReplyDelete
  2. How do I read the temperature exactly?

    Which pin should I read from? The NC pin?

    I cant get TX and RX to do anything, but PWM works well for distance.

    Please teach me how to use this thing for reading temperature

    ReplyDelete

Copyright © Rough Record. Designed by OddThemes