SR04 Ultrasonic Ranging Sensor
Module Source
Purchase link: https://item.taobao.com/item.htm?spm=a1z10.3-c-s.w4002-19589090137.10.33c336b4KtAN1t&id=608943401463 Materials download link: https://pan.baidu.com/s/1sSah9PvLBrmbA7So-6YcSw Materials extraction code: qq35
Specifications
Operating voltage: 3-5.5V Operating current: 5.3MA Sensing angle: less than 15 degrees Detection distance: 2CM-600CM Detection precision: 0.1CM+1% Output method: GPIO Number of pins: 4 Pin
Principle Analysis
You only need to input a high level of more than 10US on the Trig pin (trigger signal), and the system will send out 8 40KHZ ultrasonic pulses, then detect the echo signal. When the echo signal is detected, it is output through the Echo pin. The distance value can be calculated from the duration of the high level output by the Echo pin. That is, the distance value is: (high level time * 340m/s) / 2. When the measurement distance exceeds the measurement range of HC-SR04, a high level signal will still be output through the Echo pin, and the width of the high level is about 66ms. As shown in Figure 6:
Measurement cycle: After receiving the high level pulse output by the HC-SR04 through the Echo pin, the next measurement can be performed, so the measurement cycle depends on the measurement distance. When the distance to the measured object is very close, the pulse width returned by Echo is narrow and the measurement cycle is very short; when the distance to the measured object is far, the pulse width returned by Echo is wide and the measurement cycle is correspondingly longer. In the worst case, the measured object exceeds the measurement range of the ultrasonic module, and the returned pulse width is the longest, about 66ms, so the measurement cycle in the worst case should be slightly greater than 66ms (70ms is sufficient).
Porting Process
Pin Selection
Port to Project
Our goal is to port the example to the ESP32-S3 dev board. Complete driver code has been provided for you. Follow the steps below to complete the porting. For detailed instructions on creating folders and new .c and .h files, refer to section 1.4.2 in the [DHT11 Temperature and Humidity Sensor] chapter; we will not repeat it here. However, here we change the file names bsp_dht11.c and bsp_dht11.h to bsp_ultrasonic.c and bsp_ultrasonic.h, and change the folder name to SR04.
Write Code
Write the following in the bsp_ultrasonic.c file:
#include "bsp_ultrasonic.h"
// Timer handle
esp_timer_handle_t ceju = 0;
static bool timer_initialized = false;
int64_t star = 0;
int64_t endTime = 0;
float distance = 0;
void delay_ms(unsigned int ms)
{
vTaskDelay(ms / portTICK_PERIOD_MS);
}
void delay_us(unsigned int us)
{
ets_delay_us(us);
}
// Timer callback function, used as timeout handling
void timer_once(void *arg)
{
int64_t tick=esp_timer_get_time();
esp_timer_delete(ceju);
}
/******************************************************************
* Function Name: bsp_ultrasonic
* Function Description: Ultrasonic initialization
* Function Parameters: None
* Function Return: None
* Author: LC
* Notes: The TRIG pin is responsible for sending the ultrasonic pulse train
******************************************************************/
void Ultrasonic_Init(void)
{
gpio_config_t trig_config = {
.pin_bit_mask = (1ULL<<SR04_TRIG), // Configure pin
.mode =GPIO_MODE_OUTPUT,
.pull_up_en = GPIO_PULLUP_ENABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE, // Disable pull-down
.intr_type = GPIO_INTR_DISABLE // Disable pin interrupt
};
gpio_config(&trig_config);
gpio_config_t echo_config = {
.pin_bit_mask = (1ULL<<SR04_ECHO), // Configure pin
.mode =GPIO_MODE_INPUT,
.pull_up_en = GPIO_PULLUP_DISABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE, // Disable pull-down
.intr_type = GPIO_INTR_DISABLE // Disable pin interrupt
};
gpio_config(&echo_config);
}
/******************************************************************
* Function Name: Hcsr04GetLength
* Function Description: Get the measured distance
* Function Parameters: None
* Function Return: Measured distance
* Author: LC
* Notes: None
******************************************************************/
float Hcsr04GetLength(void)
{
/* Measure 5 times and calculate the average once */
float length = 0;
float t = 0;
float sum = 0;
unsigned int i = 5;
esp_timer_create_args_t once_test={ // Timer structure initialization
.callback= &timer_once,
.arg=NULL,
.name="HC_SR04Timer"
};
if (!timer_initialized)
{
esp_timer_init(); // Initialize timer
timer_initialized = true;
}
esp_timer_create(&once_test,&ceju); // Create timer
while(i--)
{
gpio_set_level(SR04_TRIG, 1);// Pull TRIG high, output high level
delay_us(20);// Duration greater than 10us
gpio_set_level(SR04_TRIG, 0);// Pull TRIG low, output low level
/* Echo sends signal, wait for echo signal */
/* After the square wave is input, the module will automatically emit 8 40KHz sound waves,
and at the same time the level of the echo pin will change from 0 to 1;
(at this time the timer should start timing); when the ultrasonic wave returns and is
received by the module, the level of the echo pin will change from 1 to 0;
(at this time the timer should stop counting), the time recorded by the timer is
the total time from ultrasonic emission to return; */
while(gpio_get_level(SR04_ECHO) == 0);// Echo waits for response
// After the Echo low level ends, the timer starts a single cycle of work,
// and calls back the function when it reaches 1740us
esp_timer_start_once(ceju,1740);
delay_us(1);
// Get the current time Record the current time star as the start time when the Echo pin goes high
star = esp_timer_get_time();
while(gpio_get_level(SR04_ECHO)==1)
{
endTime = esp_timer_get_time(); // Record the end time when the Echo pin goes low
// Note: the code for the end time must be placed inside the loop;
// if placed outside the loop, ranging may not work properly
}
// Calculate the duration of the Echo pin high level
endTime = endTime-star;
// Calculate distance, time unit is us
float cm=((float)endTime/58.0);
sum += cm;
}
distance = sum / 5;// Average of five times
return distance;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
Write the following in the bsp_ultrasonic.h file:
#ifndef _BSP_ULTRASONIC_H_
#define _BSP_ULTRASONIC_H_
#include "driver/gptimer.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "freertos/queue.h"
#include <inttypes.h>
#include "sdkconfig.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "rom/ets_sys.h"
#include "esp_system.h"
#include "driver/gptimer.h"
#include "esp_timer.h"
#define SR04_TRIG 1
#define SR04_ECHO 2
void delay_us(unsigned int us);
void delay_ms(unsigned int ms);
void timer_once(void *arg); // Callback function
void Ultrasonic_Init(void);// Ultrasonic initialization
float Hcsr04GetLength(void );// Get the ultrasonic ranging distance
#endif2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Porting Verification
Enter the following code in main.c:
#include <stdio.h>
#include "bsp_ultrasonic.h"
void app_main(void)
{
Ultrasonic_Init();
printf("SR04 Start....\r\n");
while(1)
{
printf("distance: %0.2f\n",Hcsr04GetLength());
delay_ms(1000);
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
Power-on effect (place an obstacle at a distance of 20cm):
Driver code:
File Download
📌 Materials Download Center (click to jump)
📌 In the Materials Download Center -> Module Porting Materials Download, inside the compressed package of this chapter.