Challenge

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

C Code for HC-SR04 with ATmega328p using Input Capture Mode

#include <avr/io.h>

#include <util/delay.h>

#include <avr/interrupt.h>

#define F_CPU 16000000UL

#define TRIG_PIN PB1

#define SOUND_SPEED 34300 // cm/s

volatile uint16_t start_time, end_time;

volatile uint8_t capture_flag = 0;

void Timer1_ICU_Init() {

TCCR1A = 0; // Normal mode

TCCR1B = (1 << ICES1) | (1 << CS11); // Rising edge, prescaler = 8

TIMSK1 = (1 << ICIE1); // Enable input capture interrupt

sei(); // Enable global interrupts

}

void Trigger_Ultrasonic() {

PORTB |= (1 << TRIG_PIN);

_delay_us(10);

PORTB &= ~(1 << TRIG_PIN);

}

ISR(TIMER1_CAPT_vect) {

if (capture_flag == 0) {

start_time = ICR1; // Capture start time

TCCR1B &= ~(1 << ICES1); // Switch to falling edge detection

capture_flag = 1;

} else {

end_time = ICR1; // Capture end time

TCCR1B |= (1 << ICES1); // Switch back to rising edge detection

capture_flag = 2;

}

}

uint16_t Measure_Distance() {

capture_flag = 0;

Trigger_Ultrasonic();

while (capture_flag < 2); // Wait for both rising and falling edges

uint16_t pulse_width = end_time - start_time; // Timer ticks

uint16_t distance = (pulse_width * SOUND_SPEED) / (2 * F_CPU / 8); // Distance in cm

return distance;

}

int main() {

DDRB |= (1 << TRIG_PIN); // Set TRIG_PIN as output

DDRB &= ~(1 << PB0); // Set Echo pin (PB0) as input

Timer1_ICU_Init();

while (1) {

uint16_t distance = Measure_Distance();

_delay_ms(500);

}

}

---

Explanation:

1. Timer1 Input Capture Mode:

Captures pulse width using ICR1 register.

Measures rising and falling edges to calculate time duration.

2. Ultrasonic Sensor Working:

Trigger pin (PB1) sends a 10μs pulse.

Echo pin (PB0) receives the reflected pulse.

Distance = (Pulse Width × Sound Speed) / 2.

3. Interrupt Service Routine (ISR(TIMER1_CAPT_vect)):

Captures start and end times of the pulse.

Switches detection edge dynamically.

4. Distance Measurement (Measure_Distance):

Converts timer ticks to distance in cm.

---

Expected Output:

The calculated distance can

be displayed via UART or LCD.

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.