树莓派开发(一)——HC-SR04传感器

环境:
树莓派3b
2020-02-13-raspbian-buster-full

前期准备

烧录系统

利用Win32DiskImager.exe工具,选择好镜像文件和TF卡,点write等待,就完成了。

远程连接

由于贫穷的限制,我没有专门的显示器连接树莓派。所以只能通过远程连接。

很奇怪我尝试用WIFI连接的时候,并没有连上。所以我插了根网线直连。192.168.1.1查到树莓派的ip,新建ssh文件总是被删,所以建了个ssh文件夹,通过putty连接。

初始账号密码:

1
2
pi
raspberry

连接后再

1
sudo raspi-config

进入设置页面更改分辨率,打开VNC,并且以防万一再次打开ssh。

1
Advanced Options -> Resolution -> DMT Mode 82 1920×1080 60Hz 16:9

1
2
Interfacing Options -> SSH
Interfacing Options -> VNC

然后可以通过VNC打开图形化界面了。

WiringPi安装

我这里的WiringPi原本就是安装好的,所以不需要再次安装。
网上有很多安装教程,就不过多赘述了。

1
2
gpio -v
gpio readall

查看板子型号和引脚信息。

HC-SR04

这个传感器的作用是超声波测距。

HC-SR04模块一共有4个引脚,分别是Vcc(高电平),GND(低电平),Trig(触发测距)以及Echo(返回测距结果)。


下图是 HC-SR04的时序图。

这个图表明,只需为Trig引脚提供一个10uS以上的高电平脉冲触发信号,模块会自动将Echo脚设置为高电平。该模块内部将发出8个40kHz周期电平,即输出超声波,并检测回波。

一旦检测到有回波信号则输出回响信号。接收到之后Echo脚会自动变成低电平,从而完成一次测距。

回响信号的脉冲宽度与所测的距离成正比。

由此通过发射信号到收到的回响信号时间间隔可以计算得到距离。只需要测量Echo脚为高电平的时间,然后乘上声速/2就可以了。

HC-SR04引脚 树莓派引脚 说明
Vcc 2 5V电压
Trig 38 GPIO.20
Echo 40 GPIO.21
Gnd 39 Gnd

python代码:

1
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
# -*-coding:utf-8 -*-
import RPi.GPIO as GPIO
import time

Trig_Pin = 20
Echo_Pin = 21

GPIO.setmode(GPIO.BCM)
GPIO.setup(Trig_Pin, GPIO.OUT, initial = GPIO.LOW)
GPIO.setup(Echo_Pin, GPIO.IN)

time.sleep(2)

def checkdist():
GPIO.output(Trig_Pin,GPIO.HIGH)
    time.sleep(0.00015)
    GPIO.output(Trig_Pin,GPIO.LOW)
    while not GPIO.input(Echo_Pin):
        pass
    t1 = time.time()
    while GPIO.input(Echo_Pin):
        pass
    t2 = time.time()
    return (t2-t1)*340*100/2

try:
    while True:
        print 'Distance:%0.2f cm' % checkdist()
        time.sleep(1)
except KeyboardInterrupt:
    GPIO.cleanup()

注:
1.第8行:在RPi.GPIO中,同时支持树莓派上的两种GPIO引脚编号。

第一种编号是BOARD编号,这和树莓派电路板上的物理引脚编号相对应。使用这种编号的好处是,你的硬件将是一直可以使用的,不用担心树莓派的版本问题。因此,在电路板升级后,你不需要重写连接器或代码。

第二种编号是BCM规则,是更底层的工作方式,它和Broadcom的片上系统中信道编号相对应。在使用一个引脚时,你需要查找信道号和物理引脚编号之间的对应规则。对于不同的树莓派版本,编写的脚本文件也可能是无法通用的。

你可以使用下列代码(强制的)指定一种编号规则:

1
2
3
GPIO.setmode(GPIO.BOARD)

GPIO.setmode(GPIO.BCM)

2.第9~10行:引脚设置
在使用一个引脚前,你需要设置这些引脚作为输入还是输出。配置一个引脚的代码如下:

1
2
3
4
5
6
7
8
# 将引脚设置为输入模式
GPIO.setup(channel, GPIO.IN)

# 将引脚设置为输出模式
GPIO.setup(channel, GPIO.OUT)

# 为输出的引脚设置默认值
GPIO.setup(channel, GPIO.OUT, initial=GPIO.HIGH)

将Trig设置为输出,并为其设置初始值为高电平。
将Echo设置为输入。

3.第15~17行:设置引脚的输出状态

1
GPIO.output(channel, state)

其中通道是基于指定的编号系统(BOARD或BCM)的通道编号。

状态可以是0 / GPIO.LOW / False1 / GPIO.HIGH / True

设置输出高电平:

1
2
3
4
5
GPIO.output(12, GPIO.HIGH)

GPIO.output(12, 1)

GPIO.output(12, True)

设置输出低电平:

1
2
3
4
5
GPIO.output(12, GPIO.LOW)

GPIO.output(12, 0)

GPIO.output(12, False)

先给Trig引脚一个高电平脉冲,sleep 15Us(大于10uS即可)。

4.第18~19行:读取GPIO引脚的值

1
GPIO.input(channel)

其中通道是基于指定的编号系统(BOARD或BCM)的通道编号。
这将返回0 / GPIO.LOW / False1 / GPIO.HIGH / True

如果没有读取到Echo引脚的值就pass。

5.第20行:开始计时

6.第21行:读取到了Echo引脚的值,pass。

7.第23行:计时结束。

8.第24行:计算距离。

效果:

这个程序还有很多不完善的地方,比如Echo引脚电平设置出错等没有防护措施等。还可以继续优化。