存档3月 2020

烟雾探测传感器实验

#实验目的:实验通过烟雾探测传感器+数模转换模块,通过检测空气情况,然后输出烟雾探测值。
#接线效果如图
接线示例
#实验代码
代码示例

#!/usr/bin/env python
#coding:utf-8

'''
from JiuJiang
树莓酱的操作实例
https:://www.suhmeijiang.com
'''

import time              ##引入time库
import smbus             ##引入控制总线

address = 0x48   ##传感器地址
A0 = 0x40        ##使用的端口地址
bus = smbus.SMBus(1)   ##开启总线

try:
    while True:
        bus.write_byte(address, A0)    ##设置获取传感器哪个端口数据
        value = bus.read_byte(address)   ##读取指定端口的数据
        print ("检测值:%1.3f " %(value)) ##范围为0~255
        ##print ("检测值:%1.3f " %(value*3.3/255))  ##转换为电压输出 如果是5V需要将3.3替换为5
        time.sleep(1)    ##探测频率

except KeyboardInterrupt:
    pass
#实验效果:
1、执行程序 Python jiujiang.py;
2、可见屏幕依次打印出数值,并相对稳定输出(数字越大 烟雾越大);
3、当用酒精(安全起见)靠近传感器时,可见数值逐渐增大;
4、当将酒精移开后,数值逐渐降低;
5、由于实验温度,实验规模受限因此无法实际模拟真实烟雾场景,仅做参考;
6、由于获取的是模拟信号,因此需要自己设定一个报警值,作为触发预警的阈值。
#视频效果如下:

人体红外传感器检测触发七彩LED灯闪烁实验

#实验目的:通过人体红外传感器检测是否有人经过,从而触发继电器通电,然后触发七彩LED灯(或其他预警)闪烁预警。
#接线效果如图:
接线示例
1、继电器接线具体可参考:http://www.shumeijiang.com/2019/11/23/继电器实验/
2、人体红外传感器接线具体可参考:http://www.shumeijiang.com/2019/12/28/人体红外传感器探测实验/
#实验关键代码:
代码示例

#!usr/bin/env python
#coding:utf-8

'''
from JiuJiang
树莓酱的操作实例
https:://www.suhmeijiang.com
'''

import RPi.GPIO as GPIO  ##引入GPIO模块
import time              ##引入time库

ledPin = 20  ##继电器控制
detectPin = 23  ##人体红外传感器检测

GPIO.setmode(GPIO.BCM)  ##此处采用的BCM编码 因为T型扩展板也是BCM编码 方便统一
GPIO.setup(ledPin, GPIO.OUT)  ##设置继电器为输出模式
GPIO.setup(detectPin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) ##设置人体红外传感器为输入模式 并初始化拉低电平

GPIO.output(ledPin, GPIO.LOW)  ##初始化继电器为低电平

##定义七彩LED灯预警闪烁方法
def startWarning():
    GPIO.output(ledPin, GPIO.HIGH)  ##高电平闪烁
    time.sleep(8)  ##闪烁8秒
    GPIO.output(ledPin, GPIO.LOW)  ##低电平熄灭


GPIO.add_event_detect(detectPin, GPIO.RISING)   ##添加一个边沿检测事件 检测电压升高
GPIO.add_event_callback(detectPin, startWarning)  ##同时添加一个回调动作

try:
    while True:
        if GPIO.event_detected(detectPin):  ##检测是否触发事件 电压升高触发
            print "触发预警"
        else:
            pass

        time.sleep(1)  ##检测频率为1秒/次  可自定义
except KeyboardInterrupt:
    pass

GPIO.cleanup()
#实验效果:
1、执行代码 Python jiujiang.py;
2、由于初始化为低电压,所以当人体红外传感器没有检测到人体时,不会触发预警;
3、当将手触放在人体红外传感器前,传感器会触发高电平,进而触发边沿事件,再而触发回调方法,触发LED闪烁。
4、由于回调方法有几秒延迟,因此可见LED等持续闪烁,直到时间到达,程序设置为低电平,LED灯熄灭;然后进入下一个检测周期。
#视频效果如下:

GPIO之初始化高电平或低电平

#实验背景:当我们做传感器实验时,经常会有个疑虑,当传感器被触发或者被获取之前,那么程序的电压状态是高电平还是低电平呢;这块其实程序处于一个float状态,也就是悬浮可变状态,它会很容易受到其他因素的干扰,从而导致出现获取到意外的数值。因此就需要在程序开始之时,初始化对应的针脚的电压状态。

【GPIO.IN】


设置示例
可见通过:
1、GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_UP) #拉高电压
2、GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)#拉低电压

        执行代码可见,当pull_up_down=GPIO.PUD_UP时,输出高电平1;当GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)时,输出低电平0。


#!/usr/bin/env python
#coding:utf-8

'''
from JiuJiang
树莓酱的操作实例
http:://www.suhmeijiang.com
'''

import RPi.GPIO as GPIO  ##引入GPIO模块
import time              ##引入time库

detectPin = 18

GPIO.setmode(GPIO.BCM)   ##此处采用的BCM编码 因为T型扩展板也是BCM编码 方便统一

#GPIO.setup(detectPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)  ##拉高电压
GPIO.setup(detectPin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) ##拉点电压

print GPIO.input(detectPin)

GPIO.cleanup()

【GPIO.OUT】


设置示例
可见通过:
1、GPIO.output(detectPin, GPIO.LOW) ##初始化低电平
2、GPIO.output(detectPin, GPIO.HIGH) ##初始化高电平

        执行代码可见,当GPIO.LOW时输出低电平0;当GPIO.HIGH时输出高电平1;


#!/usr/bin/env python
#coding:utf-8

'''
from JiuJiang
树莓酱的操作实例
http:://www.suhmeijiang.com
'''

import RPi.GPIO as GPIO  ##引入GPIO模块
import time              ##引入time库

detectPin = 18

GPIO.setmode(GPIO.BCM)   ##此处采用的BCM编码 因为T型扩展板也是BCM编码 方便统一
GPIO.setup(detectPin, GPIO.OUT) ##设置为输出模式

GPIO.output(detectPin, GPIO.LOW)  ##设置默认输出低电平
#GPIO.output(detectPin, GPIO.HIGH)  ##设置默认输出高电平

print GPIO.input(detectPin)

GPIO.cleanup()

循迹传感器实验

#实验目的:通过利用传感器发射红外线,遇到黑色线后被吸收而无法被反射被发现的原理,从而发现传感器循迹的原理和奥秘。
#传感器原理
传感器背面
  • 可见传感器背面有蓝色LED灯和黑色LED灯;
  • 蓝色LED灯负责发射红外线,黑色LED灯则负责接收发射后的红外线;
  • 当红外线被发射并照射到白色表面时,红外线被吸收和反射,此时黑色LED灯接收到反射的红外线,从而输出低电平;
  • 当遇到黑色表面时,由于红外线被吸收,黑色LED等无法接收到反射的红外线,从而输出高电平。
#接线效果如图:
接线示例
#实验代码
代码示例
#注:发现黑色线为高电压,没发现为低电平;

#!/usr/bin/env python
#coding:utf-8

'''
from JiuJiang
树莓酱的操作实例
https:://www.suhmeijiang.com
'''

import RPi.GPIO as GPIO  ##引入GPIO模块
import time              ##引入time库

detectPin = 18

GPIO.setmode(GPIO.BCM)   ##此处采用的BCM编码 因为T型扩展板也是BCM编码 方便统一
GPIO.setup(detectPin, GPIO.IN) ##设置18口为输入口

try:
    while True:
        status = GPIO.input(detectPin)
        if status == GPIO.HIGH:   ##高电平触发 发现黑色线
            print '发现黑色线,继续前进'
            time.sleep(1)        ##检测到预警提示持续时间
        else:
            print '路径丢失,重新规划路线'

        time.sleep(0.5)    ##检测频率

except KeyboardInterrupt:
    pass

GPIO.cleanup()
#视频效果如下:

GPIO之event_detected()系列函数

#函数列表

函数参数含义函数含义
add_event_detect( channel, status, bouncetime=300)传感器引脚,要检测的状态注册一个事件用于检测status是否发现
event_detected( channel)要检测的引脚检测引脚是否检测到status状态
add_event_callback( channel, callback)传感器引脚,回调函数发现指定status然后回调执行自定义方法
remove_event_detect( channel)要检测的引脚停止边缘检测
#注:status可选值 GPIO.RISING(电压升高), GPIO.FALLING(电压变低), GPIO.BOTH(电压升高或降低);bouncetime为抖动时间用于软件防抖,单位毫秒。
其中防抖时间可以理解为设置的单位时间内检测一次事件,从而实现单位时间内是否有一次事件触发的效果。
#实验参考:http://www.shumeijiang.com/2020/03/15/gpio之边沿检测/
#实验代码:
实验代码
#实验效果
  • 执行程序可见屏幕输出“开始检测”;
  • 因为设置挂起时间为4秒,如果在4秒内手指放在传感器触摸板上,可见回调自定义函数并输出“获取到响应1”;
  • 然后伴随挂起4秒结束,屏幕会输出“接下来的动作”;
  • 然后输出“检测到事件”

#!/usr/bin/env python
#coding:utf-8

'''
from JiuJiang
树莓酱的操作实例
http:://www.shumeijiang.com
'''

import RPi.GPIO as GPIO  ##引入GPIO模块
import time              ##引入time库

touchPin = 18

GPIO.setmode(GPIO.BCM)
GPIO.setup(touchPin, GPIO.IN)


def getRespose(self):
    print "获取到响应1"


GPIO.add_event_detect(touchPin, GPIO.RISING)  ##注册一个检测电压由低变高事件
GPIO.add_event_callback(touchPin, getRespose)  ##检测到事件触发回调getRespose 函数

print '开始检测'

while True:
    if GPIO.event_detected(touchPin):
        print "检测到事件"

    time.sleep(4)  ##进行挂起4秒
    print "接下来的动作"
#官方函数定义见如下截图:
#具体应用见文章:
1、https://www.shumeijiang.com/2021/09/02/四路红外避障传感器实验/
2、https://www.shumeijiang.com/2021/07/25/步进电机定位问题解决尝试

GPIO之wait_for_edge()函数

#函数:wait_for_edge(channel, status) 
#参数说明:
参数说明可选项
channel传感器引脚
status要检测的状态GPIO.RISING, GPIO.FALLING, GPIO.BOTH
其中GPIO.RISING表示电压由低变高;GPIO.FALLING表示电压由高变低;GPIO.BOTH表示两者都检测。
#实验案例参考:http://www.shumeijiang.com/2020/03/15/gpio之边沿检测/
#实验代码:
实验代码
执行代码可见效果:
1、代码执行可见屏幕输出“准备开始接收”,然后主线程进入阻塞状态,由于没有其他线程所以进程进入阻塞状态;
2、当用手指放置在传感器触摸板上,并持续放置时,可见屏幕输出“发现低电压变化高电压”,即检测到触摸动作;
3、当手指从传感器触摸板离开时,可见屏幕输出“发现高电压变化低电压”,即传感器感知到触摸结束。
#结论
  • 函数是阻塞形式;
  • 函数不需while循环检测,检测到即可触发进程继续进行;
  • 函数可检测电压由低变高,可检测电压由高变低,也可检测发现变压变化即触发。

!/usr/bin/env python
coding:utf-8
'''
from JiuJiang
树莓酱的操作实例
http:://www.shumeijiang.com
'''

import RPi.GPIO as GPIO  ##引入GPIO模块
import time              ##引入time库
touchPin = 18

GPIO.setmode(GPIO.BCM)
GPIO.setup(touchPin, GPIO.IN)
print '准备开始接收'

GPIO.wait_for_edge(touchPin, GPIO.RISING)
print '发现低电压变化高电压'

GPIO.wait_for_edge(touchPin, GPIO.FALLING)
print '发现高电压变化低电压'
#官方函数定义见如下截图:

GPIO之边缘检测

实验目的:应用一种新的电压检测方式,更精准更灵活的检测到传感器电压变化,从而获得传感器被触发或者被释放的状态。
边缘检测也是一种传感器状态检测的方式,不同的是通过内置的函数进行;比如wait_for_edge()或者event_detected(),它们和平常我们用的while循环有相同之处,都是用来检测传感器状态,不同的地方在与前者更精准,不会由于while内的time.sleep时无法获得CPU而导致状态获取失败,具体可见如下实验。
#接线效果如图
触摸开关传感器(默认低电压,触摸触发高电压)
#传统while获取方式(以触摸开关传感器为例):
while方式检测
while方式检测
#传统while检测会存在丢失现象,如果time.sleep(2)的时候主线程阻塞从而导致进程挂起,此时正好触发传感器,由于没有其他线程所以导致进程检测不到,出现结果丢失现象。
#wait_for_edge()函数,会在检测到指定的升高或者降低或者两者的状态时阻塞进程,直到检测到状态。

具体可见文章:http://www.shumeijiang.com/2020/03/15/gpio之wait_for_edge函数/
#event_detected()函数,不会阻塞进程,在while循环中检测到状态变化,不会影响主线程继续执行,而是通过其他线程同步检测到的状态,同时还能触发回调多个函数,同步触发其他任务。

具体可见文章:http://www.shumeijiang.com/2020/03/15/gpio之event_detected系列函数/