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_Initfunction initializes the sensor, Timer1 for Input Capture Mode, and global interrupts. -
The
Trigger_Ultrasonicfunction sends a trigger pulse to start a distance measurement. -
In the
mainfunction, 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_Ultrasonicfunction triggers the HC-SR04 sensor by setting the trigger pin high and then low. -
Measure_Distancefunction 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
distancevalue 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_Initinitializes 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_completeflag to become true, indicating that a pulse width measurement has been completed. Once complete, you can use thepulse_widthvalue 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.