Challenge

Project 2 - Measuring distance of an object using ultrasonic sensor (HC-SR04)

Overview of the Project:  with an example :

with a code outline for measuring the distance of an object using an Ultrasonic Distance Sensor (HC-SR04) and an Atmega328P microcontroller. Please note that the code outline provided here serves as a general guide. You may need to adapt it to your specific microcontroller platform and programming environment.

#include
#include
#include

// Define HC-SR04 sensor pins
#define TRIGGER_PIN     // Define the trigger pin
#define ECHO_PIN        // Define the echo pin

volatile uint16_t pulse_width = 0;
volatile uint8_t measurement_complete = 0;

// Initialize Ultrasonic Sensor
void Ultrasonic_Init() {
    // Configure trigger pin as an output
    DDRD |= (1 << TRIGGER>    
    // Configure echo pin as an input
    DDRD &= ~(1 << ECHO>    
    // Initialize Timer1 for Input Capture Mode
    TCCR1B |= (1 << ICES1>    TIMSK1 |= (1 << ICIE1>    
    // Enable global interrupts
    sei();
}

// Send a trigger pulse to start measurement
void Trigger_Ultrasonic() {
    PORTD |= (1 << TRIGGER>    _delay_us(10);  // Pulse width of 10us
    PORTD &= ~(1 << TRIGGER>}

int main() {
    // Initialize Ultrasonic Sensor
    Ultrasonic_Init();
    
    while (1) {
        // Trigger the Ultrasonic Sensor
        Trigger_Ultrasonic();
        
        // Wait for measurement to complete
        while (!measurement_complete) {
            // Wait for the Input Capture interrupt
        }
        
        // Calculate the distance from the pulse width (in cm or inches)
        // You'll need to write the calculation logic here
        
        // Reset the measurement flag
        measurement_complete = 0;
        
        // Add a delay before the next measurement
        _delay_ms(1000);  // Adjust as needed
    }
    
    return 0;
}

// Input Capture interrupt handler
ISR(TIMER1_CAPT_vect) {
    static uint16_t start_time = 0;
    static uint16_t end_time = 0;
    
    if (TCCR1B & (1 << ICES1>        // Rising edge captured
        start_time = ICR1;
        TCCR1B &= ~(1 << ICES1>    } else {
        // Falling edge captured
        end_time = ICR1;
        pulse_width = end_time - start_time;
        measurement_complete = 1;
        TCCR1B |= (1 << ICES1>    }
}

In this code outline:

  • The HC-SR04 sensor's trigger and echo pins need to be defined appropriately.

  • The Ultrasonic_Init function initializes the sensor, Timer1 for Input Capture Mode, and global interrupts.

  • The Trigger_Ultrasonic function sends a trigger pulse to start a distance measurement.

  • In the main function, the code triggers the sensor, waits for the measurement to complete using a flag (measurement_complete), and calculates the distance based on the pulse width. You'll need to write the distance calculation logic according to the HC-SR04 datasheet.

  • The Input Capture interrupt (TIMER1_CAPT_vect) is used to capture the rising and falling edges of the echo pulse, allowing measurement of the pulse width.

Measuring the pulse width using the Input Capture Mode of Timer1 in an ATmega328P microcontroller involves capturing the time between the rising and falling edges of a digital signal, such as the echo signal from an HC-SR04 ultrasonic sensor. Here's how you can measure pulse width using Timer1's Input Capture Mode:

  • The distance travelled by a wave to the object for which we want to measure the distance using Ultrasonic Distance Sensor (HC-SR04).

#include
#include

#define TRIGGER_PIN   // Define the trigger pin
#define ECHO_PIN      // Define the echo pin

// Function to trigger the HC-SR04 sensor
void Trigger_Ultrasonic() {
    // Set the trigger pin HIGH for at least 10 microseconds
    // Then set it LOW to trigger the sensor
}

// Function to measure the pulse width and calculate distance
float Measure_Distance() {
    uint32_t pulse_width;
    
    // Trigger the sensor to send an ultrasonic pulse
    Trigger_Ultrasonic();
    
    // Wait for the echo pin to go HIGH (start of pulse)
    while (!(PIND & (1 << ECHO>    
    // Measure the time until the echo pin goes LOW (end of pulse)
    while (PIND & (1 << ECHO>        pulse_width++;
        _delay_us(1);  // Delay 1 microsecond
    }
    
    // Calculate the distance in meters
    float distance = (float)(pulse_width * 1e-6 * 343) / 2.0;
    
    return distance;
}

int main() {
    // Initialize sensor pins and other settings
    
    while (1) {
        float distance = Measure_Distance();
        // Use the 'distance' value as needed (e.g., display or process)
        
        // Add a delay between measurements
        _delay_ms(1000);  // Adjust as needed
    }
    
    return 0;
}

  • Trigger_Ultrasonic function triggers the HC-SR04 sensor by setting the trigger pin high and then low.

  • Measure_Distance function measures the pulse width (time) it takes for the echo pin to go from high to low and calculates the distance based on the formula.

  • The main loop continuously measures the distance and can use the distance value as needed

  • Measuring Pulse width using Input Capture Mode of Timer 1

Note: Make sure you have configured the hardware connections and initialized Timer1 properly, as shown in previous responses. The following code assumes that Timer1 is correctly set up.

#include
#include

#define ECHO_PIN    // Define the echo pin for the HC-SR04 sensor

volatile uint16_t pulse_width = 0;
volatile uint8_t measurement_complete = 0;

// Initialize Timer1 for Input Capture Mode
void Timer1_Init() {
    // Configure Timer1 for Input Capture Mode
    TCCR1B |= (1 << ICES1>    TIMSK1 |= (1 << ICIE1>}

// Input Capture interrupt handler
ISR(TIMER1_CAPT_vect) {
    static uint16_t start_time = 0;
    static uint16_t end_time = 0;
    
    if (TCCR1B & (1 << ICES1>        // Rising edge captured
        start_time = ICR1;
        TCCR1B &= ~(1 << ICES1>    } else {
        // Falling edge captured
        end_time = ICR1;
        pulse_width = end_time - start_time;
        measurement_complete = 1;
        TCCR1B |= (1 << ICES1>    }
}

int main() {
    // Initialize Timer1
    Timer1_Init();
    
    // Set ECHO_PIN as an input
    
    // Enable global interrupts
    sei();
    
    while (1) {
        // Wait for measurement to complete
        if (measurement_complete) {
            // The 'pulse_width' variable now contains the pulse width in timer counts
            // You can convert it to time or distance based on your application
            // Reset the measurement flag
            measurement_complete = 0;
        }
    }
    
    return 0;
}

  • Timer1_Init initializes Timer1 for Input Capture Mode. It sets up the timer to capture both rising and falling edges of the input signal.

  • The Input Capture interrupt handler (TIMER1_CAPT_vect) captures the timer value at the rising and falling edges of the input signal. It calculates the pulse width by subtracting the start time from the end time.

  • In the main loop, the code waits for the measurement_complete flag to become true, indicating that a pulse width measurement has been completed. Once complete, you can use the pulse_width value as needed for your application.

Make sure to connect the echo pin from your HC-SR04 sensor to the appropriate microcontroller pin (ECHO_PIN) and configure the hardware accordingly. You should also adapt the code to handle your specific measurement requirements or unit conversions.

Your portfolio, next

Ship work like this
in your own course.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.