树莓派基础实验11:U型光电传感器实验
一、介绍
U型光电传感器是一种对射式光电传感器,它有一个发射端和接收端组成。它的工作原理是通过对红外发射光的阻断和导通,在红外接收管感应出的电流变化来实现开和关的判断。适用于物体通过传感器使光线被挡住的情况,因此,U型光电传感器广泛用于速度测量。
二、组件
★Raspberry Pi主板*1
★树莓派电源*1
★40P软排线*1
★U型光电传感器模块*1
★双色LED模块*1
★面包板*1
★跳线若干
三、实验原理
U型光电传感器由两部分组成:发射器和接收器。发射器发光,然后光线进入接收器,如果发射器和接收器之间的光速被障碍物挡住,接收器即使在一瞬间也将检测不到入射光,并且输出电平将会改变,光线隔断是高电平,没有挡住时是低电平。在这个实验中,我们将通过使用此更改来打开或关闭LED灯。
四、实验步骤
第1步:连接电路,该实验与实验6(轻触开关按键实验)相同。这里要注意光电传感器使用3.3V电源,而不是5V。
树莓派 | T型转接板 | U型光电传感器 |
---|---|---|
GPIO 0(序号11) | GPIO 17 | SIG(OUT) |
3.3V | 3.3V | VCC |
GND | GND | GND |
树莓派 | T型转接板 | 双色LED |
---|---|---|
GPIO 1(序号12) | GPIO 18 | R(红色端口) |
GND | GND | GND |
GPIO 2(序号13) | GPIO 27 | G(绿色端口) |
第2步:这次编程有两个函数要注意,是关于输入的高级应用。
有多种方式将GPIO的输入导入到程序中,polling( 轮询 )式 和 interrupt( 中断 )式( edge detection 边缘检测 ),“轮询”式如果程序在错误的时间读取值,可能会错过输入。我们这里采用中断式。
如果您没有将输入引脚连接到任何东西,它将“浮动”。换句话说,读取的值是未定义的,因为它没有连接到任何东西,直到你按下按钮或开关。它可能会由于接收电源干扰而改变很大的值。
为了解决这个问题,我们使用一个向上拉或向下拉电阻器。这样,就可以设置输入的默认值。可以使用硬件或者软件实现上下拉电阻。在硬件方式中,常常在输入通道与3.3V(上拉)或0V(下拉)之间使用10K电阻。GPIO模块允许您在编程中这样配置:
GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_UP)# or
GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
我们很多时候并不关心电平值, 而关心电平从低到高,或从高到低的变化(如编码器测速/按键按下弹开等), 为避免主程序忙于其它事情错过引脚的电平改变, 有两种方式:
wait_for_edge() 函数
event_detected() 函数
wait_for_edge()函数是为了阻止程序的执行,直到检测到边缘为止。换句话说,等待按钮按下的示例可以改写成:
GPIO.wait_for_edge(channel, GPIO.RISING)
注意检测的边缘参数有 GPIO.RISING, GPIO.FALLING , GPIO.BOTH (上升沿, 下降沿 或 升降沿), 这样用几乎不占用CPU,如果你只希望在确定的时间段内查询,可以使用 timeout 参数:
# wait for up to 5 seconds for a rising edge (timeout is in milliseconds)
channel = GPIO.wait_for_edge(channel, GPIO_RISING, timeout=5000)
if channel is None:print('Timeout occurred')
else:print('Edge detected on channel', channel)
event_detected()函数被设计用来与其他事物一起在循环中使用, 不同于polling轮询, 它不会在CPU忙于处理其他事物时错过输入状态的变化。 这使得使用Pygame 或 PyQt 时非常有用,因为其中有一个主循环监听和及时响应GUI事件的基础。
只要检测到指定参数的边缘事件(上升沿, 下降沿 或 升降沿)发生时,调用GPIO.event_detected(channel)的值就为"ture"(真)。
#Note that you can detect events for GPIO.RISING, GPIO.FALLING or GPIO.BOTH.
GPIO.add_event_detect(channel, GPIO.RISING) # add rising edge detection on a channel
do_something()
if GPIO.event_detected(channel):print('Button pressed')
不过需要自己新建一个线程去循环检测event_detected()的值,还算是比较麻烦的。
可采用另一种办法轻松检测状态,这种方式是直接传入一个回调函数:GPIO通过在add_event_detect()函数中添加callback参数,RPI.GPIO为回调函数运行第二个线程。这意味着回调函数可以与主程序同时运行,以立即响应边缘。
For example:
def my_callback(channel):print('This is a edge event callback function!')print('Edge detected on channel %s'%channel)print('This is run in a different thread to your main program')
GPIO.add_event_detect(channel, GPIO.RISING, callback=my_callback) # 这里添加了回调函数callback这个参数,就不需要GPIO.event_detected(channel)函数了
如果你想要不止一个回调函数:
def my_callback_one(channel):print('Callback one')
def my_callback_two(channel):print('Callback two')
GPIO.add_event_detect(channel, GPIO.RISING)
GPIO.add_event_callback(channel, my_callback_one)
GPIO.add_event_callback(channel, my_callback_two)
请注意,在这种情况下,回调函数是按顺序运行的,而不是并发的。这是因为只有一个线程用于回调,其中每个回调都按照它们被定义的顺序运行。
由于存在开关抖动(用示波器可以看到),每次按下开关会调用多次回调函数,这不是我们希望的,有两种方式处理开关抖动:
①在开关两个引脚之间添加一个0.1uF的电容
②软件消抖
③二者结合使用
使用软件消抖时, 给回调函数添加一个弹跳时间的参数( bouncetime= ), 弹跳时间(参照单片机可以为10~20ms)在ms级别, 下面的程序用200ms来消抖:
# add rising edge detection on a channel, ignoring further edges for 200ms for switch bounce handling
GPIO.add_event_detect(channel, GPIO.RISING, callback=my_callback, bouncetime=200)
由于某些原因, 你的程序可能不希望用边缘检测了,可以停止它们:
GPIO.remove_event_detect(channel)
第3步:正式编程。 定义针脚参数和初始化设置函数setup(),其中就用到了上面讲解的GPIO输入高级应用,添加边缘事件检测函数GPIO.add_event_detect()。
#!/usr/bin/env python
import RPi.GPIO as GPIOPIPin = 11
Rpin = 12
Gpin = 13def setup():GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical locationGPIO.setup(Gpin, GPIO.OUT) # Set Green Led Pin mode to outputGPIO.setup(Rpin, GPIO.OUT) # Set Red Led Pin mode to outputGPIO.setup(PIPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Set BtnPin's mode is input, and pull up to high level(3.3V)GPIO.add_event_detect(PIPin, GPIO.BOTH, callback=detect, bouncetime=200)
第4步: 定义Led(x)函数,控制双色LED灯闪烁。定义Print(x),打印光线被遮挡的提示消息。没有遮挡光线,电路联通,传感器输出低电平,红灯亮;光线被遮挡,电路断开,传感器输出高电平,绿灯亮。
def Led(x): #控制双色LED灯闪烁的函数if x == 0: #没有遮挡光线,电路联通,传感器输出低电平,红灯亮GPIO.output(Rpin, 1)GPIO.output(Gpin, 0)if x == 1 #光线被遮挡,电路断开,传感器输出高电平,绿灯亮GPIO.output(Rpin, 0)GPIO.output(Gpin, 1)def Print(x): #打印光线被遮挡提示消息if x == 1:print ' *************************'print ' * Light was blocked *'print ' *************************'
第5步: 检测到光线被遮挡时(或者没有被遮挡时),边缘事件检测函数都会回调detect(chn)函数。
def detect(chn):Led(GPIO.input(PIPin)) #控制双色LED灯闪烁的函数Print(GPIO.input(PIPin)) #打印光线被遮挡提示消息def loop():while True:pass #pass语句就是空语句
很多程序都提供了“空语句”支持,Python 也不例外,Python 的 pass 语句就是空语句。有时候程序需要占一个位、放一条语句,但又不希望这条语句做任何事情,此时就可通过 pass 语句来实现。通过使用 pass 语句,还可以让程序更完整,因为如果定义一个空函数程序会报错,当你没有想好函数的内容时可以用 pass 填充,使程序可以正常运行。
第6步: 创建destroy()函数,清除LED状态。创建程序入口,并包含异常处理。
def destroy():GPIO.output(Gpin, GPIO.LOW) # Green led offGPIO.output(Rpin, GPIO.LOW) # Red led offGPIO.cleanup() # Release resourceif __name__ == '__main__': # Program start from heresetup()try:loop()except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child program destroy() will be executed.destroy()
树莓派基础实验11:U型光电传感器实验相关推荐
- 计算机病毒引导实验,东华大学计算机病毒实验一引导型病毒实验报告
东华大学计算机病毒实验一引导型病毒实验报告 (30页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 11.90 积分 实验一 引导型病毒实验1. 实验目的 ...
- 操作系统实验11:内存管理实验(DAY 62)
文章目录 1:实验要求: 2:代码实现 3:实验分析: 4:结果分析 1:出现两个进程 2:设置内存空间为256 3:再重复一次上一步操作 4:输入5,展示内存空间 5:输入4,杀死2号进程. 1:实 ...
- 计算机病毒引导实验,东华大学计算机病毒实验一引导型病毒实验报告.doc
东华大学计算机病毒实验一引导型病毒实验报告 实验一 引导型病毒实验 1. 实验目的 通过实验,了解引导区病毒的感染对象和感染特征,重点学习引导病毒的感染机制和恢复感染染毒文件的方法,提高汇编语言的使用 ...
- cmi码型变换matlab程序_实验四 码型变换实验.doc
实验四 码型变换实验 一.实验要求 1.了解几种常见的数字基带信号. 2.掌握常用数字基带传输码型的编码规则. 3.掌握用FPGA实现码型变换的方法. 二.实验内容 1.观察NRZ码.RZ码.BRZ码 ...
- 实验十二:U型光电传感器实验
OK,今天睡不着,好几天也没有更新blog了 上周只更新了1篇 本周第1篇就是这个 因为周一周二课最多,上完课就想休息一下 而且晚上有时候会接单,也比较忙,在壹心理做倾听师 程序猿和倾听师,调剂下,左 ...
- c语言实验11答案,c语言实验9-11参考答案
c语言实验9-11参考答案 (4页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 9.90 积分 数组 上机题9.编写程序:从键盘输入一串整数保存到数组中, ...
- cmi编码实验_CMI码型变换实验
CMI 码型变换实验 一.实验原理和电路说明 在实际的基带传输系统中, 并不是所有码字都能在信道中传输. 例如, 含有丰富直流和 低频成分的基带信号就不适宜在信道中传输, 因为它有可能造成信号严重畸变 ...
- linux磁盘配额实验11,Linux磁盘配额实验
1.实现磁盘限额的条件 *需要Linux内核支持 *安装quota软件包 2.Linux磁盘限额的特点 作用范围:针对指定 文件系统(分区) 限制对象:普通用户帐号.组帐号 限制类型:磁盘容量(默认单 ...
- 华北水利水电C 语言实验11,华北水利水电大学C语言实验11.doc
华北水利水电大学C语言实验11 C语言程序设计实验报告 实验11.结构体程序设计 班级 2013156 学号 201315613 姓名 吴浩 [实验目的] (1)掌握结构体类型的概念.定义和使用: ( ...
最新文章
- linux下date -d,linux date -d的一些用法
- python爬虫分析大学排名_Python爬虫获得国内高校排名,python,获取,大学排名
- iOS中SQLite3数据库修改字段名
- go mod require + replace解决本地包依赖问题
- Windows 平台的 Markdown 编辑器 : Typora
- 5G的场景、需求、通信速率
- C++学习之路 | PTA乙级—— 1068 万绿丛中一点红 (20 分)(精简)
- VS系列IDE(2005、2008等)下使用cppunit的方法及使用示例
- python实例属性与类属性_Python 面向对象编程:类的创建与初始化、实例属性与方法、类属性与方法...
- .NET+Oracle 9i时产生的未在本地计算机上注册“OraOLEDB.Oracle.1”提供程序
- 什么是Dropthings
- python计算机入门_Python零基础入门(1)-------计算机基础
- ftp上传乱码_ftp同步图片到本地文件夹,ftp同步图片到本地文件夹的实现步骤
- 图解TCPIP(第5版)
- RS-485通信协议(ModBus版)
- MyBatis拦截器实现原理
- win10屏幕文字模糊不清
- 动漫设计系统(基于ASP.NET的动态网站)
- 机房收费系统(一)可行性研究报告
- java生成二维码到文件,java生成二维码转成BASE64