Skip to main content

Ultrasonic Sensor HC-SR04 With PIC Microcontroller

How ultrasonic sensor SR-HC04 works.
How Ultrasonic Sensor Works

An ultrasonic sensor is a very useful sensor that measures distances with sounds. We used the PIC16F628A microcontroller for this project. This microcontroller has TMR1 which we are going to use. We need 2 I/O pins for TRIG and ECHO pins. For showing distance, we used an LCD. For more information about the LCD library and usage click the button below.

HC-SR04 Ultrasonic Sensor

This sensor sends out ultrasonic sound waves and receives them back. After calculating the traveling time it can measure the distance between the sensor and the object. This is the power of sound. But the measurement speed of the ultrasonic sensor is low compared to the infrared proximity sensor.

HC-SR04 ultrasonic sensor module.
HC-SR04 Ultrasonic Sensor

The sensor module we are going to use is like the picture above. This module has an ultrasonic transmitter, ultrasonic receiver, and control circuit. With this module, you can measure distances from 2cm to 400cm. The module has 4 pins:

  • VCC: 5V power input pin
  • Trig: Trigger pin
  • Echo: Echo pin
  • GND: Ground pin

Trig and Echo pins are used to communicate with the microcontroller.

Calculating Measurement

Ultrasonic sensor distande calculation.
Ultrasonic Sensor Distance

In the picture above, you can see two-length d and x. The d is the distance from the object to the sensor. The x is the distance from the object to the sensor module. If you want to measure distances under 15cm precisely you must use x distance.

You can see how to calculate the d and x lengths in the picture below. For this formula, we choose FOSC = 4 MHz and Prescaler = 1:1.

Ultrasonic sensor distance calculation.
Ultrasonic Sensor Distance Calculation

To show how much error will be if not use x length, you can see examples below.

Ultrasonic sensor error examples.
Error Examples

Timer1 Module

TIMER1 block diagram.
TIMER1 Block Diagram

The Timer1 module is a 16-bit timer/counter consisting of two 8-bit registers (TMR1H and TMR1L) which are readable and writable. The TMR1 register pair (TMR1H:TMR1L) increments from 0000h to FFFFh and rolls over to 0000h. (PIC16F628A Datasheet) We will use the Timer1 module to measure time. In the T1CON register, we will use T1CKPS bits to adjust prescale value, TMR1CS bits for clock selection and TMR1ON bits to start/stop the timer. For read and write timer values we will use TMR1H and TMR1L registers.

TIMER1 Control Register
T1CON Register

Ultrasonic Sensor Circuit

Ultrasonic sensor schematic with PIC16F628A microcontroller.
Ultrasonic Sensor Schematic

MPLAB XC8 Code

PIC16F628A microcontroller has a 2Kb program memory. For this reason, we can not calculate the x value and show an “Out of Range” message. If you have a microcontroller that has more than 2Kb program spaces you can use it and calculate the x value.

main.c File

/*
 * File:   main.c
 * Author: radon
 *
 * Created on March 23, 2020, 12:51 PM
 */


#include "config.h"

void main(void) {
    // Turn comparator off and enable pins for digital I/O functions
    CMCONbits.CM = 0b111;
    
    // Ultrasonic sensor pins
    TRISAbits.TRISA0 = 0;  // TRIG pin
    TRISAbits.TRISA1 = 1;  // ECHO pin
    
    // TIMER1 Configuration
    // Prescaler = 1:1
    T1CONbits.T1CKPS = 0b00;
    // Select internal clock (FOSC/4)
    T1CONbits.TMR1CS = 0;
    
    // LCD initialize
    LCDInitialize();
    
    uint8_t str[13];
    uint16_t timer;
    
    while(1) {
        // Reset TIMER1 values
        TMR1H = 0;
        TMR1L = 0;
        
        // Sen 10us pulse to TRIG pin
        PORTAbits.RA0 = 1;
        __delay_us(10);
        PORTAbits.RA0 = 0;
        
        // Wait for ECHO pin goes to HIGH
        while(!PORTAbits.RA1);
        T1CONbits.TMR1ON = 1;   // Enable TIMER1 module
        // Wait for ECHO pin goes to LOW
        while(PORTAbits.RA1);
        T1CONbits.TMR1ON = 1;   // Disable TIMER1 module
        
        // Read TIMER1 values
        timer = (TMR1H << 8) | TMR1L;
        // Calculate distance
        timer = timer/58.8235 + 1;
        // Using round function
        //timer = round(timer/58.8235);
        // For presice calculation
        //timer = round(sqrt(((timer*timer)/3460.2041)-6.25));
        
        if(timer >=2 && timer <=400) {
            LCDClearDisplay();
            LCDPrintString("Trion Projects", 1, 0);
            sprintf(str, "Dist = %dcm", timer);
            LCDPrintString(str, 2, 0);
        } else {
            LCDPrintString("Out of Range!", 2, 0);
        }
    }
}

config.h File

/* 
 * File:   
 * Author: 
 * Comments:
 * Revision history: 
 */

// This is a guard condition so that contents of this file are not included
// more than once.  
#ifndef CONFIG
#define    CONFIG

// PIC16F628A Configuration Bit Settings

// 'C' source line config statements

// CONFIG
#pragma config FOSC = INTOSCCLK // Oscillator Selection bits (INTOSC oscillator: CLKOUT function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON       // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is MCLR)
#pragma config BOREN = OFF      // Brown-out Detect Enable bit (BOD disabled)
#pragma config LVP = OFF        // Low-Voltage Programming Enable bit (RB4/PGM pin has digital I/O function, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EE Memory Code Protection bit (Data memory code protection off)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

#define _XTAL_FREQ 4000000

#include <xc.h> // include processor files - each processor file is guarded.  
#include <stdint.h>
#include <stdio.h>
#include <math.h>
#include "lcd.h"


#endif    /* CONFIG */
lcd.c and lcd.h Files

We use our LCD library which you can find in the link below.

Video

Comments

Popular posts from this blog

How to Make Blink LED with PIC16F628A

How to Make Blink LED With PIC16F628A In this project tutorial, we are going to make blink-led projects with a pic microcontroller. After you read this tutorial you can build a PIC microcontroller project with XC8 on MPLAB IDE. We are going to make 3 different blinking projects. These projects are basic. Just learn how to make a basic project with a PIC microcontroller. You can see below which projects we are going to make; Blinking LED with 1s delay, LED with button, Blinking LED with a button.

DC Motor Speed Control With PIC16F628A

DC Motor Speed Control Simulation In this project, we will control the speed and direction of a DC motor using the PIC16F628A microcontroller. We will write the software in MPLAB IDE with the XC8 language that will send a PWM signal to L293D to control the motor. Finally, we will simulate it through the Proteus software. PWM (Pulse Width Modulation) You can get more information about the PWM signal from the link above. Now let’s examine the L293D motor driver.