HC-SR04 ultrasonic rangefinder example code for dsPIC30F4011

The following example program for a dsPIC30F40011 microcontroller takes a reading from a HC-SR04 ultrasonic rangefinder once every 200ms.

  • The dsPIC 30F4011 is running at 30 MIPS (using the internal fast RC oscillator with 16x PLL multiplier).
  • RC13 is a digital output and is connected to the “trigger” pin on the HC-SR04.
  • RC14 is a digital input and is connected to the “echo” pin on the HC-SR04.
  • The HC-SR04 requires trigger pulses of 10 us duration (or longer). In this example, the trigger pulses are 20 us in duration.
  • Timer 1 is used to measure the duration of the echo pulses. Its prescaler is set to 1:8, so that each timer tick is equal to 8 instruction cycles (266.66 ns).
  • The UART is configured at 38400 baud to print the measured distance (in metres).
//
// dsPIC30F4011 Ultrasonic rangefinder example
// Written by Ted Burke
// Last updated 25-10-2017
//
// RC13 is the trigger pin (digital output)
// RC14 is the echo pin (digital input)
//
  
#include <xc.h>
#include <stdio.h>
#include <libpic30.h>
  
// Configuration settings
_FOSC(CSW_FSCM_OFF & FRC_PLL16); // Fosc=16x7.5MHz, Fcy=30MHz
_FWDT(WDT_OFF);                  // Watchdog timer off
_FBORPOR(MCLR_DIS);              // Disable reset pin
  
void main()
{
    // Configure RC13 as a digital output to send the trigger pulse
    _TRISC13 = 0;
    
    // Setup UART
    U1BRG = 48;            // 38400 baud @ 30 MIPS
    U1MODEbits.UARTEN = 1; // Enable UART
  
    // We'll use Timer 1 to measure the duration of the echo pulse
    // We set the Timer 1 prescaler to 1:8, which means that each tick
    // of the timer is equal to 8 instruction cycles - i.e. 266.66 ns
    PR1 = 65535;          // Set the Timer 1 period (max 65535)
    T1CONbits.TCKPS = 1;  // Prescaler (0=1:1, 1=1:8, 2=1:64, 3=1:256)
    
    double distance;
    
    while(1)
    {
        // Send trigger pulse
        _LATC13 = 1;                        // begin trigger pulse
        __delay32(600);                     // 20 us
        _LATC13 = 0;                        // end trigger pulse
        
        // Measure duration of echo pulse
        while (_RC14 == 0);                 // wait for beginning of echo pulse
        TMR1 = 0;                           // reset Timer 1 counter
        T1CONbits.TON = 1;                  // start Timer 1
        while (_RC14 == 1 && TMR1 < 50000); // wait for end of echo pulse (timeout after 13.33 ms)
        T1CONbits.TON = 0;                  // stop Timer 1
        
        // Calculate the distance from duration of echo pulse
        distance = TMR1 * 4.5333e-5;
        printf("Distance: %f metres\r\n", distance);
        
        // Delay (200 ms) before next reading
        __delay32(6000000);
    }
}
Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s