7 Ultrasonic sensor Distance Measurement - HC-SR04
7.1 Objective
By the end of this exercise, students will - Interface an HC-SR04 ultrasonic sensor with the STM32 Nucleo-144 F767ZI using STM32Duino. - Take multiple distance measurements and calculate the average. - Display the averaged distance using the serial monitor. - Control and LED with the measured distance.
7.2 Materials
- STM Nucleo-144 F767ZI development board.
- Ultrasonic Sensor (HC-SR04).
- Jumper wires for connections.
- STM32Duino environment set up in Arduino IDE (with STM32 core installed).
7.3 HC-SR04 Sensor
- VCC: 5V power.
- GND: Ground.
- Trig: Trigger pin (to send out the ultrasonic pulse).
- Echo: Echo pin (to receive the reflected pulse).
7.4 Wiring Connections
- VCC -> 5V pin on STM32.
- GND -> GND pin on STM32.
- Trig -> D12 or any available digital GPIO pin (using in the Arduino Compatible zio connector)
- Echo -> D13 or any available digital GPIO pin.
Tip
While using Stm32duino with Arduino in Arduino compatible board, the Arduino pin conventions can also be used in the program. Eg. A0
for anolog pin, 12
for digital pin.
7.5 Explanation of Key Functions
digitalWrite(pin, HIGH/LOW)
: Sends a HIGH or LOW signal to the pin to activate or deactivate the trigger pin.pulseIn(pin, HIGH)
: Measures the time for the echo pin to go HIGH, which is proportional to the distance.- Serial communication functions: To print the results on the Serial Monitor.
Serial.begin(baud_rate)
- Should be initialized in thesetup
to start the serial communication. The baud rate can be typically set to 9600 or 115200.Serial.print
- Prints a value in the serial monitor.Serial.println
- Same as print but also prints a newline character at the end.
7.6 Tasks and Sample IO Behavior
Task 1: Interface HC-SR04 with STM32 and Measure Distance
- Objective: Write code to interface the HC-SR04 with the STM32 Nucleo-144 F767ZI, measure the distance, and print the result on the Serial Monitor.
Example Code
#define TRIG_PIN 12 // Trigger pin
#define ECHO_PIN 13 // Echo pin
void setup() {
.begin(9600); // Initialize serial communication
Serial(TRIG_PIN, OUTPUT); // Set the trigger pin as an output
pinMode(ECHO_PIN, INPUT); // Set the echo pin as an input
pinMode}
void loop() {
float distance = measureDistance();
// Print the average distance to the Serial Monitor
.print("Distance: ");
Serial.print(distance);
Serial.println(" cm");
Serial
(1000); // Delay before taking another set of measurements
delay}
float measureDistance() {
long duration;
float distance;
// Clear the trigger pin
(TRIG_PIN, LOW);
digitalWrite(2);
delayMicroseconds
// Send a 10µs pulse to trigger the sensor
(TRIG_PIN, HIGH);
digitalWrite(10);
delayMicroseconds(TRIG_PIN, LOW);
digitalWrite
// Measure the time of the echo pulse
= pulseIn(ECHO_PIN, HIGH);
duration
// Calculate the distance (speed of sound is 34300 cm/s)
= (duration * 0.0343) / 2;
distance return distance;
}
Sample Output on Serial Monitor
Distance: 25.34 cm
Distance: 26.21 cm
Distance: 25.78 cm
Task 2: Take Multiple Measurements and Calculate the Average
- Objective: Modify the program to take 10 distance measurements and calculate the average to improve accuracy. Display the averaged distance on the Serial Monitor.
Example Code(modify the code from above task)
/* pin configurations*/
/* setup goes here*/
void loop() {
// Print the average distance to the Serial Monitor
.print("Distance: ");
Serial.print(measureDistanceSmooth(10)); // Averaging 10 measurements
Serial.println(" cm");
Serial
(1000); // Delay before taking another set of measurements
delay}
/* Measure Distance Function */
float measureDistanceSmooth(int numMeasurements) {
float totalDistance = 0.0;
// Take multiple measurements
for (int i = 0; i < numMeasurements; i++) {
// Add to the total distance for averaging
+= measureDistance();
totalDistance (5); // Small delay between measurements
delay}
// return the average distance
return totalDistance / numMeasurements;
}
Sample Output on Serial Monitor
Distance: 25.34 cm
Distance: 25.35 cm
Distance: 25.33 cm
Task 3: Calibrate Ultrasonic Sensor and Fade LED with Sensor Measurement
Objective
- Calibrate the HC-SR04 sensor by recording minimum and maximum distance readings.
- Perform calibration until a button press is detected using an interrupt.
- Control the brightness of the built-in LED on PA0 (using PWM to fade) based on the measured distance.
Steps
- Calibration Phase:
- Start taking distance readings and continuously update the minimum and maximum values.
- The calibration phase continues until the button is pressed, triggering an interrupt.
- LED Brightness Control:
- After calibration, the measured distance is used to control the brightness of the LED on PA0 using PWM.
- The brightness will vary proportionally between the minimum and maximum measured distances.
Code Example (Include measuring functions from the above task.)
#define TRIG_PIN 12 // Trigger pin
#define ECHO_PIN 13 // Echo pin
#define LED_PIN PB0 // Inbuilt-LED Pin
#define BUTTON_PIN PC13 // Inbuilt Button pin
volatile bool calibrationComplete = false;
float minDistance = 1000; // Large initial value for calibration
float maxDistance = 0; // Small initial value for calibration
void setup() {
.begin(9600);
Serial(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(LED_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT);
pinMode
// Attach interrupt for the button press
(digitalPinToInterrupt(BUTTON_PIN), completeCalibration, FALLING);
attachInterrupt
// Set up PWM for LED pin
(8); // 8-bit resolution (0-255)
analogWriteResolution}
void loop() {
if (!calibrationComplete) {
float distance = measureDistance();
// Update min/max distances for calibration
if (distance < minDistance) minDistance = distance;
if (distance > maxDistance) maxDistance = distance;
.print("Calibrating... Min: ");
Serial.print(minDistance);
Serial.print(" cm, Max: ");
Serial.println(maxDistance);
Serial
(500); // Slow down calibration readings
delay} else {
// After calibration, use distance to control LED brightness
float currentDistance = measureDistanceSmooth(10);
int brightness = map(currentDistance, minDistance, maxDistance, 0, 255); // Map distance to brightness
= constrain(brightness, 0, 255); // Ensure the value stays within 0-255 range
brightness
(LED_PIN, brightness); // Set LED brightness
analogWrite
.print("Distance(cm):");
Serial.print(currentDistance);
Serial.print(",LED Brightness:");
Serial.println(brightness);
Serial
(200); // Slow down the readings
delay}
}
/* Measuring functions*/
// Button interrupt handler to stop calibration
void completeCalibration() {
= true;
calibrationComplete .println("Calibration complete.");
Serial}
Sample Output on Serial Monitor
Calibrating... Min: 10.34 cm, Max: 58.21 cm
Calibrating... Min: 9.67 cm, Max: 61.52 cm
Calibration complete.
Distance(cm):35.42 cm,LED Brightness:128
Distance(cm):20.30 cm,LED Brightness:64
Tip
You can use serial plotter to view graphs of the serial output. You can use serial plotter in two ways. 1. Just printing comma seperated values in the serial monitor. 2. Using the format {label 1}:{value 1}, {label 2}:{value 2} which will show the labels in the serial plotter.
Conclusion
- Interfacing an Ultrasonic Sensor: The HC-SR04 ultrasonic sensor was interfaced with the STM32 Nucleo-144 F767ZI using the STM32Duino platform.
- Serial Communication: The measured results were displayed on the Serial Monitor using the
Serial.print()
function, emphasizing the role of serial communication in embedded systems. - Timing and Control: Concepts such as trigger pulses and delay functions were applied to manage sensor timing and ensure reliable operation.
- Button Interrupts: This task demonstrated how to use button interrupts to stop a calibration phase.
- PWM Control: The PWM output on PA0 was used to control LED brightness based on the distance measured by the ultrasonic sensor.