Raspberry Pi Development-Ultrasonic Ranging

1. Module introduction:

HC-SR04 Ultrasonic Module:
Insert picture description here
Insert picture description here
VCC: Positive
Trig: Trigger
Echo: Response
GND: Negative (ground)

2. Raspberry Pi interface:

gpio readall   // 输入指令查看树莓派 io 口

 +-----+-----+---------+------+---+---Pi 3B--+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 |     |     |    3.3v |      |   |  1 || 2  |   |      | 5v      |     |     |
 |   2 |   8 |   SDA.1 |   IN | 1 |  3 || 4  |   |      | 5v      |     |     |
 |   3 |   9 |   SCL.1 |   IN | 1 |  5 || 6  |   |      | 0v      |     |     |
 |   4 |   7 | GPIO. 7 |   IN | 1 |  7 || 8  | 1 | ALT0 | TxD     | 15  | 14  |
 |     |     |      0v |      |   |  9 || 10 | 1 | ALT0 | RxD     | 16  | 15  |
 |  17 |   0 | GPIO. 0 |   IN | 0 | 11 || 12 | 0 | IN   | GPIO. 1 | 1   | 18  |
 |  27 |   2 | GPIO. 2 |   IN | 0 | 13 || 14 |   |      | 0v      |     |     |
 |  22 |   3 | GPIO. 3 |   IN | 0 | 15 || 16 | 0 | IN   | GPIO. 4 | 4   | 23  |
 |     |     |    3.3v |      |   | 17 || 18 | 0 | IN   | GPIO. 5 | 5   | 24  |
 |  10 |  12 |    MOSI |   IN | 0 | 19 || 20 |   |      | 0v      |     |     |
 |   9 |  13 |    MISO |   IN | 0 | 21 || 22 | 0 | IN   | GPIO. 6 | 6   | 25  |
 |  11 |  14 |    SCLK |   IN | 0 | 23 || 24 | 1 | IN   | CE0     | 10  | 8   |
 |     |     |      0v |      |   | 25 || 26 | 1 | IN   | CE1     | 11  | 7   |
 |   0 |  30 |   SDA.0 |   IN | 1 | 27 || 28 | 1 | IN   | SCL.0   | 31  | 1   |
 |   5 |  21 | GPIO.21 |   IN | 1 | 29 || 30 |   |      | 0v      |     |     |
 |   6 |  22 | GPIO.22 |   IN | 1 | 31 || 32 | 0 | IN   | GPIO.26 | 26  | 12  |
 |  13 |  23 | GPIO.23 |   IN | 0 | 33 || 34 |   |      | 0v      |     |     |
 |  19 |  24 | GPIO.24 |   IN | 0 | 35 || 36 | 0 | IN   | GPIO.27 | 27  | 16  |
 |  26 |  25 | GPIO.25 |   IN | 0 | 37 || 38 | 0 | IN   | GPIO.28 | 28  | 20  |
 |     |     |      0v |      |   | 39 || 40 | 0 | IN   | GPIO.29 | 29  | 21  |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+---Pi 3B--+---+------+---------+-----+-----+

3. Wiring:

Vcc: Ultrasonic module power supply pin, connected to 5V power supply

Trig: Receive the control signal from the Raspberry Pi and connect to the GPIO port

Echo: Send the ranging result to the Raspberry Pi, connect to the GPIO port

(It is worth noting that: Echo returns a 5v signal, and the Raspberry Pi's GPIO may be burned if it receives a signal exceeding 3.3v, so a voltage divider circuit can be added)

Gnd: ground, connect to 0v

4. Working principle:

1. The Raspberry Pi sends a pulse signal lasting 10us (microseconds) to Trig

2. HC-SR04 receives the 10us pulse signal sent by the Raspberry Pi, sends 8 40khz square waves, sets Echo to high level, and prepares to receive the returned ultrasonic wave

3. When HC-SR04 receives the returned ultrasonic wave, set Echo to low level

4. The duration of the high level output of the Echo is the time from emission to return of the ultrasonic wave

5. Record the time between sending and receiving (high level duration) to calculate the distance

5. Code implementation:

#include <stdio.h>
#include <wiringPi.h>
#include <sys/time.h>

#define Trig 4
#define Echo 5

float getDistance()
{
    
    
		float dis;
		long start;
		long end;
		struct timeval tv1;
		struct timeval tv2;
/*      struct timeval {
               time_t      tv_sec;     // 秒
               suseconds_t tv_usec;    // 微秒  
         };
*/
		digitalWrite(Trig, LOW);   // 先通入低电平,避免后续误差过大
        delayMicroseconds(2);

		digitalWrite(Trig, HIGH);
		delayMicroseconds(10);   // 树莓派发送 10us 脉冲信号
		digitalWrite(Trig, LOW);

		while(digitalRead(Echo) != HIGH);   // HIGH(1),检测到高电平时跳出循环
		gettimeofday(&tv1, NULL);   // 获取时间(此为高电平开始时间)
		
		while(digitalRead(Echo) != LOW);   // LOW(0),检测到低电平跳出循环
		gettimeofday(&tv2, NULL);   // 获取时间(此为低电平开始时间,即为高电平结束时间)

		start = tv1.tv_sec * 1000000 + tv1.tv_usec;   // 单位(微秒)
		end = tv2.tv_sec * 1000000 + tv2.tv_usec;   // 单位(微秒)
		
		dis = (float)(end - start) / 1000000 * 34000 / 2;   // 距离计算(高电平时间 * 音速 / 2)
		
		return dis;
}

int main()
{
    
    
		float dis;
		
		if(wiringPiSetup() == -1){
    
       // 硬件初始化
				printf("硬件初始化失败!\n");
				return -1;
		}
		
		pinMode(Trig, OUTPUT);   // 配置端口为输出模式
		pinMode(Echo, INPUT);   // 配置端口为输入模式
		pullUpDnControl(Echo, PUD_UP);   // 对一个设置 IO 模式为 INPUT 的输入引脚设置拉电阻模式
										 // PUD_UP 启用上拉电阻,引脚电平拉到 3.3v

		while(1){
    
    
				dis = getDistance();
				printf("distance = %0.2fcm\n",dis);
				delay(1000);
		}
		return 0;
}

6. Function analysis:

#include <sys/time.h>
int gettimeofday(struct timeval *tv, struct timezone *tz);

// 获取自 1970-01-01 00:00:00 到调用 gettimeofday() 函数所经历的秒数,存放在 tv 中,精确到微秒
// 获取时区信息,存放到 tz 中,不关心时传入 NULL 即可

struct timeval {
    
    
		time_t      tv_sec;     /* seconds(秒)*/
		suseconds_t tv_usec;    /* microseconds(微秒)*/
};

struct timezone {
    
    
		int tz_minuteswest;     /* minutes west of Greenwich(格林威治时间往西方的时差)*/
		int tz_dsttime;         /* type of DST correction(DST 时间的修正方式)*/
};

Guess you like

Origin blog.csdn.net/lcx1837/article/details/108137893