Project 2 - Measuring distance of an object using ultrasonic sensor (HC-SR04)
In this project, the implementation of code for “Measuring distance of an object using ultrasonic distance sensor (HC-SR04)
Measuring the distance of an object using ultrasonic distance Sensor (HC-SR04)
Measuring the distance of an object using an ultrasonic distance sensor, such as the HC-SR04, involves sending ultrasonic pulses and measuring the time it takes for the pulses to bounce back after hitting an object. Here's a step-by-step guide on how to connect and use the HC-SR04 with a microcontroller, like Arduino, to measure distances:
Components Needed:
1. HC-SR04 Ultrasonic Sensor
2. Arduino Board (e.g., Arduino Uno)
3. Breadboard and jumper wires
4. Power source for Arduino (USB cable or battery)
Wiring:
Connect the HC-SR04 to the Arduino as follows:
VCC to 5V on Arduino
Trig to a digital pin (e.g., D2)
Echo to a digital pin (e.g., D3)
GND to GND on Arduino
Arduino Code:
Here's a simple Arduino code example to measure distance using the HC-SR04 sensor:
// Define pins
const int trigPin = 2;
const int echoPin = 3;
// Variables
long duration;
int distance;
void setup() {
Serial.begin(9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop() {
// Trigger pulse
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
Measure the duration of the pulse
duration = pulseIn(echoPin, HIGH);
Calculate the distance in centimeters
distance = duration * 0.034 * 2;
Print the distance to the Serial Monitor
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" cm");
Wait before taking the next measurement
delay(1000);
}
How It Works:
1. The Arduino sends a 10μs pulse to the Trig pin of the HC-SR04.
2. The HC-SR04 emits ultrasonic waves.
3. When the waves hit an object, they bounce back to the sensor.
4. The echo pin of the HC-SR04 receives the echo, and the Arduino measures the time it took for the signal to return.
5. The distance is then calculated using the speed of sound in the air (approximately 0.034 cm/s).
Note:
Ensure the power supply is sufficient for both the Arduino and the HC-SR04.
The HC-SR04 may have a minimum and maximum effective range; consult its datasheet for details.
Adjust the `trigPin` and `echoPin` values in the code if you connect the sensor to different digital pins.
Upload the code to your Arduino, open the serial monitor, and you should see the measured distance in centimeters.
Usage of Input Capture Mode
Input Capture Mode is a feature available in some microcontrollers, particularly those with timer peripherals. It is often used to accurately measure the time between specific events, such as pulse width, pulse period, or time intervals. Input Capture Mode can be useful in applications like pulse width modulation (PWM), frequency measurement, or capturing the time between external events.
Here's a generic overview of how input capture mode is commonly used:
1. Configure Timer and pins:
Choose a timer module on your microcontroller.
Configure the timer for input capture mode.
Assign specific pins to be used as input capture pins.
2. **Initialize Timer:**
Set up the timer with appropriate prescaler values to determine its resolution and range.
Configure the timer mode to operate in input capture mode.
3. Configure Input Capture Pins:
Configure the selected pins for input capture functionality.
4. **Interrupt Setup:**
Set up interrupts for the input capture event.
Define an interrupt service routine (ISR) to handle the captured events.
5. Capture Events:
When a specific event occurs (e.g., a rising or falling edge on the input pin), the timer captures the current timer value.
The captured value is stored in a register.
6. **Calculate Time or Frequency:**
In the interrupt service routine, calculate the time between consecutive events by subtracting the previous captured value from the current one.
Convert the time to the desired units (e.g., seconds).
7. Application-Specific Logic:
Use the captured time information for your specific application, such as adjusting the PWM duty cycle, measuring frequency, or determining the time between external events.
Example (Arduino with Timer 1):
Here's a simplified example using Arduino's Timer1 and Input Capture Mode to measure the period of an external signal:
volatile, unsigned, long startTime;
volatile, unsigned, long endTime;
void setup() {
Serial.begin(9600);
// Configure Timer1 for Input Capture Mode
TCCR1A = 0; // Normal mode
TCCR1B = _BV(ICNC1) | _BV(ICES1); // Input capture with noise canceling, rising edge trigger
TIMSK1 |= _BV(ICIE1); // Enable Input Capture Interrupt
sei(); // Enable global interrupts
}
void loop() {
Your main loop code is here
}
ISR(TIMER1_CAPT_vect) {
An Input capture event occurred
if (TCCR1B & _BV(ICES1)) {
// Rising edge captured
startTime = ICR1;
} else {
// Falling edge captured
endTime = ICR1;
// Calculate period in microseconds
unsigned long period = endTime minus startTime;
Serial.print("Period: ");
Serial.print(period);
Serial.println(" microseconds");
// Toggle edge for the next capture
TCCR1B ^= _BV(ICES1);
}
}
This example captures the rising and falling edges of an external signal on Timer1 and calculates the period between these edges. Adjust the code according to your specific requirements and the capabilities of your microcontroller's timer peripherals.
Measuring the distance travelled by the wave to the object and getting bounced back from the object to the sensor.
Measuring pulse width using input capture mode.
To measure the distance traveled by an ultrasonic wave using the pulse width measurement technique with input capture mode, you can modify the previous example by using the timer's input capture mode to measure the width of the pulse generated by the ultrasonic sensor.
Here's an example Arduino code using Timer1 and Input Capture Mode to measure the pulse width of the signal returned by the HC-SR04 ultrasonic sensor:
volatile, unsigned, long startTime;
volatile, unsigned, long endTime;
volatile bool captureComplete = false;
const int trigPin = 2;
const int echoPin = 3;
void setup() {
Serial.begin(9600);
// Configure Timer1 for Input Capture Mode
TCCR1A = 0; // Normal mode
TCCR1B = _BV(ICNC1) | _BV(ICES1) | _BV(CS11); // Input capture with noise canceling, rising edge trigger, prescaler 8
TIMSK1 |= _BV(ICIE1); // Enable Input Capture Interrupt
Configure ultrasonic sensor pins
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
sei(); // Enable global interrupts
}
void loop() {
trigger an ultrasonic pulse
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Wait for capture to complete
while (!captureComplete) {
You can perform other tasks here if needed
}
Calculate the pulse width in microseconds
unsigned long pulseWidth = endTime minus startTime;
Calculate the distance in centimeters
unsigned long distance = pulse width / 58;
Print the distance to the Serial Monitor
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" cm");
// Reset flag for the next capture
captureComplete = false;
Wait before taking the next measurement
delay(1000);
}
ISR(TIMER1_CAPT_vect) {
An Input capture event occurred
if (TCCR1B & _BV(ICES1)) {
// Rising edge captured
startTime = ICR1;
} else {
// Falling edge captured
endTime = ICR1;
captureComplete = true;
// Toggle edge for the next capture
TCCR1B ^= _BV(ICES1);
}
}
This example triggers an ultrasonic pulse using the HC-SR04, and the input capture mode is used to measure the pulse width, which is then converted into a distance measurement. Note that the specific pulse width to distance conversion factor (58 in this case) may vary based on your sensor and environmental conditions, so you might need to adjust it accordingly.
Always refer to the datasheet of your ultrasonic sensor for accurate information about its characteristics and timing. Additionally, you may need to adjust the prescaler value in the timer configuration based on the desired resolution and range of your measurements.
The distance travelled by a wave to the object for which we want to measure the distance using the Ultrasonic Distance Sensor (HC-SR04).
Measuring Pulse width using the input Mode of Timer 1
I understand now. To measure the distance traveled by the ultrasonic wave to an object and back using the pulse width measurement technique with Input Capture Mode on Timer 1, you can use the following example Arduino code:
volatile, unsigned, long startTime;
volatile, unsigned, long endTime;
volatile bool captureComplete = false;
const int trigPin = 2;
const int echoPin = 3;
void setup() {
Serial.begin(9600);
// Configure Timer1 for Input Capture Mode
TCCR1A = 0; // Normal mode
TCCR1B = _BV(ICNC1) | _BV(ICES1) | _BV(CS11); // Input capture with noise canceling, rising edge trigger, prescaler 8
TIMSK1 |= _BV(ICIE1); // Enable Input Capture Interrupt
Configure ultrasonic sensor pins
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
sei(); // Enable global interrupts
}
void loop() {
trigger an ultrasonic pulse
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Wait for capture to complete
while (!captureComplete) {
You can perform other tasks here if needed
}
Calculate the pulse width in microseconds
unsigned long pulseWidth = endTime minus startTime;
Calculate the distance in centimeters
unsigned long distance = pulse width / 58;
Print the distance to the Serial Monitor
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" cm");
// Reset flag for the next capture
captureComplete = false;
Wait before taking the next measurement
delay(1000);
}
ISR(TIMER1_CAPT_vect) {
An Input capture event occurred
if (TCCR1B & _BV(ICES1)) {
// Rising edge captured
startTime = ICR1;
} else {
// Falling edge captured
endTime = ICR1;
captureComplete = true;
// Toggle edge for the next capture
TCCR1B ^= _BV(ICES1);
}
}
This code utilizes Timer1 in Input Capture Mode to measure the pulse width of the signal returned by the HC-SR04 ultrasonic sensor. The calculated pulse width is then converted into a distance measurement. The specific pulse width-to-distance conversion factor (58 in this case) may vary based on your sensor and environmental conditions, so you might need to adjust it accordingly.
Please refer to the datasheet of your ultrasonic sensor for accurate information about its characteristics and timing. Additionally, adjust the prescaler value in the timer configuration based on the desired resolution and range of your measurements.
The students will gain knowledge on the ultrasonic sensor (HC-SR04) to measure the distance travelled by wave to the object, the hardware connection between the Atmega328p and HC-SR04 and how to use input capture mode of Timer1
Certainly! Here's a guide that covers the knowledge of the ultrasonic sensor (HC-SR04), the hardware connection of the ATmega328P with the HC-SR04, and how to use the input capture mode of Timer1 for distance measurement:
Ultrasonic Sensor (HC-SR04):
Overview:
- The HC-SR04 is an ultrasonic distance sensor that uses sonar to measure distances.
- It works by sending out an ultrasonic pulse and measuring the time it takes for the pulse to bounce back after hitting an object.
Key Specifications:
- Operating Voltage: 5V DC
- Detection Range: 2cm to 400cm
- Accuracy: 3mm
- Working Frequency: 40kHz
Pin Configuration:
1. **VCC:** Connect to +5V power supply.
2. **Trig (Trigger):** Input for sending ultrasonic pulses. Connect to a digital output pin on the microcontroller.
3. **Echo:** Output for receiving the echo. Connect to a digital input pin on the microcontroller.
4. **GND:** Connect to the ground of the power supply.
Hardware Connection (ATmega328P and HC-SR04):
ATmega328P Connections:
- **VCC:** Connect to +5V on ATmega328P.
- **Trig (Trigger):** Connect to a digital output pin (e.g., D2) on ATmega328P.
- **Echo:** Connect to a digital input pin (e.g., D3) on ATmega328P.
- **GND:** Connect to GND on ATmega328P.
Wiring Diagram:
+5V ---------- VCC (HC-SR04)
D2 ----------- Trig (HC-SR04)
D3 ----------- Echo (HC-SR04)
GND ---------- GND (HC-SR04)
Using Input Capture Mode of Timer1 (Arduino Code):
volatile unsigned long startTime;
volatile unsigned long endTime;
volatile bool captureComplete = false;
const int trigPin = 2;
const int echoPin = 3;
void setup() {
Serial.begin(9600);
// Configure Timer1 for Input Capture Mode
TCCR1A = 0; // Normal mode
TCCR1B = _BV(ICNC1) | _BV(ICES1) | _BV(CS11); // Input capture with noise canceling, rising edge trigger, prescaler 8
TIMSK1 |= _BV(ICIE1); // Enable Input Capture Interrupt
// Configure ultrasonic sensor pins
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
sei(); // Enable global interrupts
}
void loop() {
// Trigger ultrasonic pulse
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Wait for capture to complete
while (!captureComplete) {
// You can perform other tasks here if needed
}
// Calculate pulse width in microseconds
unsigned long pulseWidth = endTime - startTime;
// Calculate distance in centimeters
unsigned long distance = pulseWidth / 58;
// Print the distance to the Serial Monitor
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" cm");
// Reset flag for the next capture
captureComplete = false;
// Wait before taking the next measurement
delay(1000);
}
ISR(TIMER1_CAPT_vect) {
// Input capture event occurred
if (TCCR1B & _BV(ICES1)) {
// Rising edge captured
startTime = ICR1;
} else {
// Falling edge captured
endTime = ICR1;
captureComplete = true;
// Toggle edge for the next capture
TCCR1B ^= _BV(ICES1);
}
}
This Arduino code uses Timer1 in Input Capture Mode to measure the pulse width of the signal returned by the HC-SR04 ultrasonic sensor. The pulse width is then converted into a distance measurement. Adjust the prescaler value based on your desired resolution and range of measurements.
Ensure the connections are correct, and upload the code to your ATmega328P-based Arduino board. Open the Serial Monitor to view the distance measurements in centimeters.