• 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 - PING

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

    This topic has probably been discussed extensively, but every now and then you still see questions about how to use ultrasound distance sensors. So why the post; it's been a while since my last post and I recently order a batch of HC-SR04, so I needed to get ready to play with those.

    The HC-SR04 is a cheap copy of the PING sensor. I've used the PING in numerous occasions, and I've built my own as well. But no matter how much more I tried to lower the cost of the one I built, I could never approach the cost of this HC-SR04. So I decided to order a few and try them out.

    First of: how do these work. These sensors work on the SONAR principle. A sound-wave is transmitted; if the wave hits something it will return back (think a tennis ball hitting a wall). The longer (time) it takes the sound-wave to come back, the longer distance it had to travel. That is the concept in a nutshell. There are lots more to consider (e.g. type of material the sound-wave reflects back from, how much distance can the sound-wave cover and still return enough energy to be detected, and many others); but for this post we'll keep it simple.

    Both the PING and the HC-SR04 operate very similar to each other. You provide a 10usec (more or less) positive pulse to their input; a short time later they send 8-40kHz pulses; they then listens for those pulses to return; and finally they put out a positive pulse on their output which width (i.e. time between rising edge and falling edge) is proportional to the distance the sound-wave traveled before returning back. The PING happens to use the same pin for input and output; the HC-SR04 uses the individual pins (one for input, one for output). Other than this they are pretty close to each other (HC-SR04 claims a bit more range as well).

    To test this system I created the code below using a PIC12F683 and a PING. I also created similar code for the HC-SR04 which I will test as soon as those arrive. The hookup is pretty simple. Connect one I/O from the PIC to the PING I/O; or two I/Os from the PIC to the HC-SR04. Then write the code to (1) provide a 10us pulse, (2) allow for some "dead/wait" time, (3) measure the pulse width of the return pulse, and (4) convert this pulse width into distance.

    It would now be good to note that both PING and HC-SR04 only work at +5V (i.e. they do not work at +3.3V - I've confirmed this on the PING, still to confirm on the HC-SR04). That was the reason for building my own a while back.

    How to convert from time to distance? Well, sound travels approximately at 340m/s (at standard altitude and temperature). The time reported by either sensor will be the time it took for the sound-wave to hit the target and return to the sensor, the sound-wave essentially traveled twice the distance (i.e. round-trip). Since we're interested in the distance to the target; this reported time must be divided in half. This means that we can represent distance as one of two ways:

    1) D (inches) = 0.5 * Time (round-trip in usec) * 74_in/us
    2) D (centimeters) = 0.5 * Time (round-trip usec) * 29_cm/us

    Note the 0.5 term in from of the round-trip time, effectively measuring only the one-way trip (i.e. distance-to-target, not the distance-to-target-and-back).

    Below is tested code used for the PING sensor. The PC was used to read the returns.

    '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 -> IO_SONAR
    'GP5 -> N/A

    'Usage Information:
    'RS232 Baud Rate: 9600bps
    'Comments: PING only works with +5V.
    'To use lower voltage, recommend using step-up regulator (e.g NCP1402)
    'The SONAR principle determines the distance to an object based on the
    'speed of sound(1_inch = 73.746_usec).If a pulse is sent, its distance (in inches)
    'to target will be; d_in = (t_usec / 73.746)
    'SONAR measures the return pulse, time pulse travels to target and back to the SONAR
    'Or d_in = (t_usec / 147.492)

    'General Configuration
    Define CONF_WORD = 0x33c4
    'Oscillator/Clock Configuration for internal 8MHz osc
    Define CLOCK_FREQUENCY = 8
    OSCCON = 0x71
    'Variable Declarations
    Symbol io_rs232_tx = GP0 'rs-232 output
    Symbol io_sonar = GP4 'ping/hc-sr04 sensor
    Const _trisio = %11111110
    Dim flag_valid_dist As Bit
    Dim _true As Bit
    Dim _false As Bit
    _true = True
    _false = False

    'Main Program
    Dim distance_in As Word 'distance in inches
    Call init()
    WaitMs 1000
    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
    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
    Config io_sonar = Output
    High io_sonar
    WaitUs 10
    Low io_sonar
    '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, PING recommends 750us
    'wait for rising edge of echo pulse
    Config io_sonar = Input
    While io_sonar = 0
    'turn-on timer1
    T1CON.TMR1ON = True
    'wait for falling edge of echo pulse or timeout
    While io_sonar = 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

    Davoid, February 26, 2018
    Beaucoup! Merci!

EE World Online Articles