• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Playing with ultrasound distance sensors - sr04

    Blog entry posted in 'Electronics and Other Ramblings...', March 27, 2013.

    Continuing on this topic; last time I included simple code for the PING sensor. Here I present equally simple code for the HC-SR04.
    The hookup is pretty simple. Connect two I/Os from the PIC to the HC-SR04 I/Os. The code provides the following: (1) a 10us pulse output to the TRIG input of the sensor, (2) allows for "dead/wait" time, (3) measures the pulse width of the return pulse from the ECHO output of the sensor, and (4) converts this pulse width into distance.
    I can confirm that the HC-SR4 (similar to the PING) does not operate at +3.3V; not a big issue, just something to keep in mind when working with these sensors.

    Below is tested code used (using PIC12F683) for the PING sensor. The PC was used to read the returns. One observation about this sensor; the HC-SR04 appears (on first look) to provide a some first order filtering to the results (or otherwise be a little more directional) as compared to the PING. This is based on initial results which appear to show the results do not move around as much. Still, some simple software filter (e.g. mean filter) is recommended.

    Hopes these examples help someone :)

    Code :

    'Author: languer (©2013)
    'Pin Allocation:
    'PIN# Main_Fn Secondary_Fn
    'GP0 -> OUT_RS232 ICSP-DAT
    'GP1 -> N/A ICSP-CLK
    'GP2 -> N/A
    'GP3 -> N/A MCLR
    'GP4 -> OUT_SONAR
    'GP5 -> IN_SONAR

    'General Configuration
    Define CONF_WORD = 0x33c4
    Define CLOCK_FREQUENCY = 8
    OSCCON = 0x71
    'Variable Declarations
    Symbol io_rs232_tx = GP0 'rs-232 output
    Symbol io_sonar_out = GP4 'hc-sr04/ping sensor
    Symbol io_sonar_in = GP5 'hc-sr04/ping sensor

    Const _trisio = %11101110
    Dim flag_valid_dist As Bit
    Dim _true As Bit
    Dim _false As Bit
    _true = True
    _false = False
    Dim cnt As Word

    'Main Program
    Dim distance_in As Word 'distance in inches
    WaitMs 2500
    Call init()
    Serout io_rs232_tx, 9600, CrLf, "Main..."
    While _true
    flag_valid_dist = False
    distance_in = get_distance()
    If flag_valid_dist = _true Then
    Serout io_rs232_tx, 9600, CrLf, "Distance=", #distance_in, "_in"
    Serout io_rs232_tx, 9600, CrLf, "Invalid Measurement"
    flag_valid_dist = False
    WaitMs 1000

    Proc init()
    TRISIO = _trisio
    'set TMR1 prescaler to 1:2 -> with 8MHz clock
    'this results in tmr1 resolution of 1uS, with maximum of 65.53ms
    'or 0.007in resolution, with maximum of 442inches
    T1CON.T1CKPS1 = 0
    T1CON.T1CKPS0 = 1
    'clear global variables
    flag_valid_dist = False
    Low io_rs232_tx
    Low io_sonar_out
    Serout io_rs232_tx, 9600, CrLf, "Power-up..."
    End Proc

    'get distance procedure
    Function get_distance() As Word
    Dim echo_time As Word
    'transmit pulse
    High io_sonar_out
    WaitUs 10
    Low io_sonar_out
    'receive echo time
    'zero-out timer1
    TMR1L = 0
    TMR1H = 0
    PIR1.T1IF = 0
    'allow for some holdoff time
    WaitUs 200 '8-cycles of 40kHz is 200us
    'wait for rising edge of echo pulse
    While io_sonar_in = 0
    'turn-on timer1
    T1CON.TMR1ON = True
    'wait for falling edge of echo pulse or timeout
    While io_sonar_in = 1 And PIR1.T1IF = 0
    T1CON.TMR1ON = False
    If PIR1.T1IF Then
    echo_time = 0
    echo_time.HB = TMR1H
    echo_time.LB = TMR1L
    flag_valid_dist = True 'flag a valid distance was measured
    'zero-out timer1
    TMR1L = 0
    TMR1H = 0
    PIR1.T1IF = 0
    'return value
    get_distance = echo_time / 148
    End Function


EE World Online Articles