树莓派使用Python检测连续脉冲
树莓派使用Python检测连续脉冲
1、应用场景 使用树莓派作为智能小车主控制器时,需要对轮子进行测速,采用的是马达+霍尔传感器的形式,小车运动时霍尔传感器会输出连续脉冲信号,通过转换就可以得到小车的速度,前行的距离等等。本博文用于流量传感器检测连续脉冲场景,通过转换可以得到流量大小。
2、检测方式 使用到了树莓派GPIO的输入(Input)功能,可分为以下几种情况(需要先安装RPi.GPIO
)。
# Python 2.X
pip install RPi.GPIO
# Python 3.X
pip3 install RPi.GPIO
上拉/下拉电阻
当GPIO没有连接任何元件时,其状态是不可控的,为解决这一问题,需要使用到上拉和下拉电阻,用于设定输入的默认值。使用硬件方式,通常需要将一个 10K 的电阻连接在输入通道与 3.3V(上拉)或 0V(下拉)之间。而树莓派可以通过软件实现GPIO的上拉和下拉:
GPIO.setup(channel, GPIO.IN, pull_up_down``=``GPIO.PUD_UP)
或者
GPIO.setup(channel, GPIO.IN, pull_up_down``=``GPIO.PUD_DOWN)
轮询(Polling)
可在某一时刻获取GPIO输入值:
if GPIO.input(channel):
print('Input was HIGH')
else:
print('Input was LOW')
也可以循环判断:
while GPIO.input(channel) == GPIO.LOW:
time.sleep(0.01)# 为 CPU 留出 10 毫秒,供其处理其它事物
中断和边缘检测
可使用中断或者边缘检测监测GPIO状态,可用到以下两个函数:
- wait_for_edge() 函数
- event_detected() 函数
GPIO.wait_for_edge(channel, GPIO.RISING)
- GPIO.RISING:上升沿触发
- GPIO.FALLING:下降沿触发
- GPIO.BOTH:都触发
GPIO.add_event_detect(channel, GPIO.RISING) # 在通道上添加上升临界值检测
do_something()
if GPIO.event_detected(channel):
print('Button pressed')
触发方式也有三种,同上。
线程回调 RPi.GPIO 在第二条线程中执行回调函数。这意味着回调函数可以同您的主程序同时运行,并且可以立即对边缘进行响应。例如:
def my_callback(channel):
print('这是一个边缘事件回调函数!')
print('在通道 %s 上进行边缘检测'%channel)
print('该程序与您的主程序运行在不同的进程中')
GPIO.add_event_detect(channel, GPIO.RISING, callback=my_callback) # 在通道上添加上升临界值检测``... 其它程序代码 ...
如果您需要多个回调函数:
def my_callback_one(channel):
print('回调 1')
def my_callback_two(channel):
print('回调 2')
GPIO.add_event_callback(channel, my_callback_one)
GPIO.add_event_callback(channel, my_callback_two)
【注意】在该示例中,回调函数为顺序运行而不是同时运行。这是因为当前只有一个进程供回调使用,而回调的运行顺序是依据它们被定义的顺序。
开关防抖
按键按下时,回调操作调用不止一次,这种现象称为“开关抖动”,有两种方式可以解决:
- 将一个0.1uf电容连接到开关上
- 软件去抖
bouncetime
参数:# 在通道上添加上升临界值检测,忽略由于开关抖动引起的小于 200ms 的边缘操作
GPIO.add_event_detect(channel, GPIO.RISING, callback = my_callback, bouncetime = 200)
或者
GPIO.add_event_callback(channel, my_callback, bouncetime=200)
remove_event_detect()
由于某种原因,您不希望您的程序检测边缘事件,您可以将它停止:
GPIO.remove_event_detect(channel)
3、检测代码
#霍尔脉冲读取函数
GPIO.setup(18, GPIO.IN,pull_up_down=GPIO.PUD_UP)#通过18号引脚读取左轮脉冲数据
GPIO.setup(35, GPIO.IN,pull_up_down=GPIO.PUD_UP)#通过35号引脚读取右轮脉冲数据
counter=0#左轮脉冲初值
counter1=0#右轮脉冲初值
def my_callback(channel):#边缘检测回调函数,详情在参见链接中
global counter#设置为全局变量
if GPIO.event_detected(18):#检测到一个脉冲则脉冲数加1
counter=counter+1
#这里的channel和channel1无须赋确定值,不能不写。
def my_callback1(channel1):
global counter1
if GPIO.event_detected(35):
counter1=counter1+1
GPIO.add_event_detect(18,GPIO.RISING,callback=my_callback) #在引脚上添加上升临界值检测再回调
GPIO.add_event_detect(35,GPIO.RISING,callback=my_callback1)
参考连接
- 树莓派中用python检测连续脉冲
- 【树莓派使用Python检测连续脉冲】使用 RPi.GPIO 模块的输入(Input)功能
推荐阅读
- 由浅入深理解AOP
- 【译】20个更有效地使用谷歌搜索的技巧
- mybatisplus如何在xml的连表查询中使用queryWrapper
- MybatisPlus|MybatisPlus LambdaQueryWrapper使用int默认值的坑及解决
- MybatisPlus使用queryWrapper如何实现复杂查询
- iOS中的Block
- Linux下面如何查看tomcat已经使用多少线程
- 使用composer自动加载类文件
- android|android studio中ndk的使用
- 使用协程爬取网页,计算网页数据大小