HC-SR04 Ultrasonic Sensor code for Distance Measurement

The code written below is for the HC-SR04 Ultrasonic Sensor using the PIC16F877A microcontroller. To start measurement, Trig of SR04 must receive a pulse of high (5V) for at least 10us, this will initiate the sensor will transmit out 8 cycle of ultrasonic burst at 40kHz and wait for the reflected ultrasonic burst. When the sensor detected ultrasonic from receiver, it will set the Echo pin to high (5V) and delay for a period (width) which proportion to distance. To obtain the distance, measure the width (Ton) of Echo pin.

Time = Width of Echo pulse, in uS (micro second)
● Distance in centimeters = Time / 58
● Distance in inches = Time / 148
● Or you can utilize the speed of sound, which is 340m/s



Project Schematic




PROJECT CODE


For the below code, the measured distance will be displayed in binary on an LED array on PORTC of the microcontroller. Eg. 5cm will = 00000101

You should be able to copy paste it.

/********************************************************************************************
Interfacing HC-SR04 Ultrasonic Sensor with PIC16F877A Microcontroller
Basic Steps :

1. Provide TRIGGER to ultrasonic module
2. Listen for Echo
3. Start Timer when ECHO HIGH is received
4. Stop Timer when ECHO goes LOW
5. Read Timer Value
6. Convert it to Distance
7. Display it
*/

#include<pic.h>
#include<htc.h>

#define _XTAL_FREQ 20000000
#define trig RB0
#define echo RB4
#define test RD5

unsigned int timer,value; 
unsigned int distance_cm, duration_us;

__CONFIG(0x3F3A);
void main(void)
{
//Initialize Timer1 module
TMR1CS=0; //internal clock=0 fosc/4
T1OSCEN=0; //oscillator shutoff
T1CKPS1=1; //set prescale bits (prescal 1:4 if T1CKPS1:T1CKPS0 = 10)
T1CKPS0=0; //set ''  ''
TMR1IE=0;

//Initialize Interrupts
INTCONbits.GIE = 0; //En/disable all unmasked interrupts
INTCONbits.PEIE = 0; //En/disable all unmasked periphiral interrupts
INTCONbits.RBIE = 0; //En/disable RB port change interrupt
INTCONbits.RBIF = 0; //Clears RB port change interrupt flag bit

//Setup IO pins
TRISB0=0; //RB0 set as output TRIGGER
TRISB4=1; //RB4 set as input for ECHO

//Only four pins on portB RB7:RB4 have interrupt on change feature
TRISC=0x00; //portC output for 8bit led array

PORTB=0; //clear port B
PORTC=1; //initial value on port C
PORTD=0;

while(1)
{
RBIF=0;
TMR1=0;
TMR1L=0; //Clear the Timer
TMR1H=0; //

while(!echo) // if echo signal low
{
trig=0; //TRIGGER LOW
__delay_us(2);
trig=1; //TRIGGER high
__delay_us(10); //delay needed for 10us pulse
trig=0; //TRIGGER low
}

while(!echo); //Wait for echo to go high
{
TMR1ON=1; //start timer
while(echo); //Wait for echo to go low
TMR1ON=0; //stop timer

timer=((TMR1H<<8)+TMR1L);//combine 2 counter bytes to single integer

/*   Convert the Pulse Width into time (us) by using calculations 
We are using 20M OSC in this project.

Duration(us)Timer * Clockspd per ins(Fosc/4) * timer pre-scale(1:4)
1) Timer * 5M * 4 //fosc/4 = 20M/4 = 5M
2) Timer * 0.2 * 4 //convert freq (1/5Mhz = 0.2us)
3) Timer * 2/10  * 4 //0.2 = 2/10
4) (Timer/10) * 2 * 4 //rearrange formula
5) (Timer/10) * 8 //Duration = Timer * 0.2us(Clock speed) * 4 (Timer Prescale)
*/
duration_us=(timer/10)*8;
distance_cm=duration_us/58; //convert to distance in cm (taken from datasheet)

PORTC=distance_cm; //display binary output distance in cm on portC

}//end while

RBIF=0;
__delay_ms(400); //delay

}//end main while
}
//******************************************************************

Comments

Popular posts from this blog

Gesture Controlled Robot Arm Using PIC16F877A