项目十三 智能保险箱 - 任务二_第1页
项目十三 智能保险箱 - 任务二_第2页
项目十三 智能保险箱 - 任务二_第3页
项目十三 智能保险箱 - 任务二_第4页
项目十三 智能保险箱 - 任务二_第5页
已阅读5页,还剩50页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

《传感器应用》主讲教师:XXX

项目十三智能保险箱PART13※智能保险箱接近报警功能※智能保险箱密码开锁功能13※实现智能保险箱功能项目概述贵重物品的安全,是人身财产安全的重要一环。随着科技水平的提高,各种盗取财物的手段不断升级。因此,人们对安全稳定性好、操作便捷的智能保险柜的需求也在不断提高。某公司要设计一个智能保险箱,要求保险箱具有有人接近时报警功能、使用数字式转盘作为解锁方式,语言播报产品作为特色。小林是公司的产品研发工程师需要将其设计出来,使用树莓派开发套件编写程序调试实现上述功能,便于后续产品的研发。掌握编写智能保险箱接近报警功能方法01掌握编写智能保险箱密码开锁功能方法02学习目标objective技能目标objective掌握编写智能保险箱功能方法01掌握实现编写综合程序方法02TASKTWO任务二智能保险箱密码开锁功能4任务概述储备知识任务实施任务目标231本次任务:在理解完旋转编码器的工作原理后,编写一个智能保险箱的密码开锁功能,要求使用旋转编码器作为输入密码介质,每输入一个密码并在液晶屏上显示,输入正确密码时提示用户输入正确。任务概述4任务概述储备知识任务实施任务目标231TASKTWO任务二智能保险箱密码开锁功能01.认识旋转编码器的工作原理02.掌握旋转编码器的编程方法任务目标4任务概述储备知识任务实施任务目标231TASKTWO任务二智能保险箱密码开锁功能01.认识旋转编码器储备知识01.认识旋转编码器(一种机电装置)旋转编码器可将轴或轴的角位置或运动,转换为模拟或数字代码。旋转编码器通常放置在垂直于轴的一侧。旋转编码器用作检测自动化领域中的角度,速度,长度,位置和加速度的传感器。其电路原理图如图所示。图:旋转编码器原理图旋转编码器可通过旋转,计数正方向和反方向转动过程中,输出脉冲的次数。旋转计数不像电位计,这种转动计数是没有限制的。配合旋转编码器上的按键,可以复位到初始状态,即从0开始计数。图:旋转编码器工作原理增量编码器是一种将旋转位移,转换成周期性的电信号,再把这个电信号转变成计数脉冲,用脉冲的个数表示位移的大小的旋转式传感器。径向分度盘(码盘)的旋转为依据,同时被一个红外光源垂直照射。在增量编码器中角位移的转换采用了光电扫描原理。读数系统的构成交替的透光窗口不透光窗口光把码盘的图像投射到接收器表面上,接收器覆盖着一层衍射光栅,它具有和码盘相同的窗口宽度。接收器的工作感受光盘转动所产生的变化。将光变化转换成相应的电变化。使低电平信号上升到较高电平,并产生没有任何干扰的方形脉冲,这就必须用电子电路来处理。即将两个波形一样但相位差为180°的不同信号进行比较,以便提高输出信号的质量和稳定性。读数是在两个信号的差别基础上形成的,从而消除了干扰。读数系统通常采用——差分方式图:光电编码器工作原理图及输出波形其中一个通道给出与转速相关的信息,与此同时,通过两个通道信号进行顺序对比,得到旋转方向的信息。还有一个特殊信号称为Z或零通道,该通道给出编码器的绝对零位(恢复按钮),此信号是一个方波与A通道方波的中心线重合。90°增量编码器给出两相方波,它们的相位差90°。通常称——A通道B通道图:旋转编码器工作原理增量型编码器精度取决于两种因素光栅分度误差01光盘偏心02轴承偏心03电子读数装置引入的误差04光学部分的不精确性05◎机械◎电气这些因素有——确定编码器精度的测量单位是电气上的度数。电气360=机械360°/n°脉冲/转可以用下列公式来计算:多少机械角度相当于电气上的360度?以下用360°电气度数来表示机械轴的转动,而轴的转动必须是一个完整的周期。编码器精度编码器产生的脉冲分度决定了4任务概述储备知识任务实施任务目标231TASKTWO任务二智能保险箱密码开锁功能02.Python程序实现旋转编码器任务实施03.Python程序密码开锁功能02.Python程序实现旋转编码器任务所需软件如下所示:环境准备任务所需硬件如下所示:Python3PyCharm树莓派4B旋转编码器2.1.根据引脚说明和连线图连接设备步骤1:根据连线图连接线路(1)设备对应接口如下表说明树莓派T型转接板旋转编码器-G21SCL-G22DT-G23SW5V5VVCCGNDGNDGND(2)如图所示,使用杜邦线将树莓派连接面包板后的GPIO与旋转传感器模块连接起来,由板载的5V为模块供电。图:树莓派连接模块图2.2.Python程序实现旋转编码器步骤1:打开“MobaXterm”软件连接SFTP服务(1)开启树莓派电源->打开Pycharm软件->打开工程名称为“SmartStrongbox”,等待树莓派启动成功。(2)在工程中新建一个文件名称为ro_encode.py的文件,如图所示。图:新建一个Python文件(1)在ro_encode.py文件中输入代码,实现旋转编码器基础旋转反馈功能,当旋转编码器正时针旋转时计数器加1,逆时钟旋转时计数器减1。步骤2:编写旋转编码器代码#coding="utf-8"importRPi.GPIOas

GPIOimport

timeRot_CLK_Pin=21

#旋转编码器CLK管脚Rot_DT_Pin=22

#旋转编码器DT管脚Rot_SW_Pin=23

#旋转编码器SW管脚Rot_flag=0

#是否发生旋转标志位Last_Rot_Status=0

#DT状态Current_Rot_Status=0

#CLK状态globalCounter=0

#当前旋转编码器计数器GPIO.setmode(GPIO.BCM)GPIO.setup(Rot_CLK_Pin,GPIO.IN)#旋转编码器CLK管脚,设置为输入模式GPIO.setup(Rot_DT_Pin,GPIO.IN)

#旋转编码器DT管脚,设置为输入模式#获取数据while(True):

Last_Rot_Status=GPIO.input(Rot_DT_Pin)

while(not

GPIO.input(Rot_CLK_Pin)):

#判断CLK管脚的电平变化来区分方向

Current_Rot_Status=GPIO.input(Rot_DT_Pin)

Rot_flag=1

#发生旋转标记

if

Rot_flag==1:#标记位为1发生了旋转

Rot_flag=0

#复位标记位

if(Last_Rot_Status==0)and(Current_Rot_Status==1):

globalCounter=globalCounter-1

#逆时针方向,负

if(globalCounter<0):globalCounter=0

print(globalCounter)

if(Last_Rot_Status==1)and(Current_Rot_Status==0):

globalCounter=globalCounter+1

#顺时针方向,正

if(globalCounter>9):globalCounter=9

print(globalCounter)代码详解代码判断是否有IO电平变化。while(not

GPIO.input(Rot_CLK_Pin))案例中如果编码器发生旋转则CLK脚将产生IO翻转。在产生变化前先记录变化前的DT口的IO电平状态,判断之前的状态与之后的状态的区别。正时针旋转。如果从1变0逆时钟旋转。如果从0变1旋转代码如下所示,需要注意的是当减到0时让变量保持为0。if(Last_Rot_Status==0)and(Current_Rot_Status==1):globalCounter=globalCounter-1

#逆时针方向,负

if(globalCounter<0):globalCounter=0

print(globalCounter)(1)在理解旋转编码器的代码后,将其分装成对应库函数方便后续调用代码,并在代码中加入SW_pin按钮接口的使用函数,如下所示。步骤3:封装旋转编码器代码#!/usr/bin/envpython3#coding='utf-8'importRPi.GPIOas

GPIOimport

timeRot_CLK_Pin=21

#旋转编码器CLK管脚Rot_DT_Pin=22

#旋转编码器DT管脚Rot_SW_Pin=23

#旋转编码器SW管脚Rot_flag=0

#是否发生旋转标志位Last_Rot_Status=0

#DT状态Current_Rot_Status=0

#CLK状态globalCounter=0

#当前旋转编码器计数器def

init():

GPIO.setmode(GPIO.BCM)

GPIO.setup(Rot_CLK_Pin,GPIO.IN)#旋转编码器CLK管脚,设置为输入模式

GPIO.setup(Rot_DT_Pin,GPIO.IN)#旋转编码器DT管脚,设置为输入模式

GPIO.setup(Rot_SW_Pin,GPIO.IN,pull_up_down=GPIO.PUD_UP)#设置Rot_SW_Pin管脚为输入模式,上拉至高电平(3.3V)def

Rot_Deal():

global

Rot_flag

global

Last_Rot_Status

global

Current_Rot_Status

global

globalCounter

Last_Rot_Status=GPIO.input(Rot_DT_Pin)

while(not

GPIO.input(Rot_CLK_Pin)):#判断CLK管脚的电平变化来区分方向

Current_Rot_Status=GPIO.input(Rot_DT_Pin)

Rot_flag=1

#发生旋转标记

if

Rot_flag==1:#标记位为1发生了旋转

Rot_flag=0

#复位标记位

if(Last_Rot_Status==0)and(Current_Rot_Status==1):

globalCounter=globalCounter-1

#逆时针方向,负

if(globalCounter<0):globalCounter=0

return

globalCounter

if(Last_Rot_Status==1)and(Current_Rot_Status==0):

globalCounter=globalCounter+1

#顺时针方向,正

if(globalCounter>9):globalCounter=9

return

globalCounterdef

Rot_SW():

if(GPIO.input(Rot_SW_Pin)==0):

time.sleep(0.1)

if(GPIO.input(Rot_SW_Pin)==0):

return

True

return

Falseif__name__=="__main__":

init()

while(True):

if(Rot_SW()):print("True")

print(Rot_Deal())代码详解调用函数时则返回当前旋转次数。案例中封装了旋转编码器的旋转次数函数Rot_Deal()案例中封装了旋转编码器的按钮函数Rot_SW()返回True。当中键被按下时返回False。当中键未按下时技能拓展(1)修改代码实现顺时针旋转次数大于100次后恢复到0代码编写。(2)在任务中加入LCD1602显示模块,在屏幕中显示当前数字功能,显示位置可自行设置。03.Python程序密码开锁功能任务所需软件如下所示:环境准备任务所需硬件如下所示:Python3PyCharm树莓派4BLCD1602模块旋转编码器3.1.根据引脚说明和连线图连接设备步骤1:根据连线图连接线路(1)设备对应接口如下表说明树莓派T型转接板旋转编码器-G21SCL-G22DT-G23SW5V5VVCCGNDGNDGND树莓派T型转接板LCD1602SDASDASDASCLSCLSCLGNDGNDGNDVCC5VVCC(2)如图所示,使用杜邦线将树莓派连接面包板后的GPIO与旋转传感器、LCD1602模块连接起来,由板载的5V为模块供电。图:树莓派连接模块图3.2.Python程序密码开锁功能步骤1:打开“Pycharm”软件(1)开启树莓派电源->打开Pycharm软件->打开工程名称为“SmartStrongbox”,等待树莓派启动成功。(2)在工程中新建一个文件名称为lcd1602.py的文件。(1)在lcd1602.py文件中输入代码,完成在液晶显示屏中第一行显示inputpassword:字符串。步骤2:编写LCD1602代码并执行代码import

timeimportsmbusBUS=smbus.SMBus(1)#IICLCD1602液晶模块写入字def

write_word(addr,data):

global

BLEN

temp=data

if

BLEN==1:

temp|=0x08

else:

temp&=0xF7

BUS.write_byte(addr,temp)#设置IICLCD1602液晶模块地址#IICLCD1602发送命令def

send_command(comm):

#首先发送bit7-4位

lcd_buf=comm&0xF0

lcd_buf|=0x04

#RS=0,RW=0,EN=1

write_word(LCD_ADDR,lcd_buf)

time.sleep(0.002)

lcd_buf&=0xFB

#MakeEN=0

write_word(LCD_ADDR,lcd_buf)

#其次发送bit3-0位

lcd_buf=(comm&0x0F)<<4

lcd_buf|=0x04

#RS=0,RW=0,EN=1

write_word(LCD_ADDR,lcd_buf)

time.sleep(0.002)

lcd_buf&=0xFB

#MakeEN=0

write_word(LCD_ADDR,lcd_buf)#IICLCD1602发送数据def

send_data(data):

#首先发送bit7-4位

lcd_buf=data&0xF0

lcd_buf|=0x05

#RS=1,RW=0,EN=1

write_word(LCD_ADDR,lcd_buf)

time.sleep(0.002)

lcd_buf&=0xFB

#MakeEN=0

write_word(LCD_ADDR,lcd_buf)

#其次发送bit3-0位

lcd_buf=(data&0x0F)<<4

lcd_buf|=0x05

#RS=1,RW=0,EN=1

write_word(LCD_ADDR,lcd_buf)

time.sleep(0.002)lcd_buf&=0xFB

#MakeEN=0

write_word(LCD_ADDR,lcd_buf)#IICLCD1602初始化def

init(addr,bl):

global

LCD_ADDR

global

BLEN

LCD_ADDR=addr

BLEN=bl

try:

send_command(0x33)

#必须先初始化到8线模式

time.sleep(0.005)

send_command(0x32)#然后初始化为4行模式

time.sleep(0.005)

send_command(0x28)

#2行&5*7点位

time.sleep(0.005)

send_command(0x0C)

#启用无光标显示

time.sleep(0.005)

send_command(0x01)#清除显示

BUS.write_byte(LCD_ADDR,0x08)

except:

return

False

else:

return

True#IICLCD1602初始化def

init():

global

LCD_ADDR

global

BLEN

LCD_ADDR=0x27

BLEN=1

try:

send_command(0x33)#必须先初始化到8线模式

time.sleep(0.005)

send_command(0x32)#然后初始化为4行模式

time.sleep(0.005)

send_command(0x28)#2行&5*7点位

time.sleep(0.005)

send_command(0x0C)

#启用无光标显示

time.sleep(0.005)

send_command(0x01)#清除显示

BUS.write_byte(LCD_ADDR,0x08)

except:

return

False

else:

return

True#LCD1602清空显示函数def

clear():

send_command(0x01)

#清除显示#LCD1602使能背光显示def

openlight():

BUS.write_byte(0x27,0x08)

#使能背光显示命令

BUS.close()#关闭总线#LCD1602显示函数def

write(lcd_x,lcd_y,lcd_str):

#选择行与列

if

lcd_x<0:

lcd_x=0

if

lcd_x>15:

lcd_x=15

if

lcd_y<0:

lcd_y=0

if

lcd_y>1:

lcd_y=1

#移动光标

lcd_addr=0x80+0x40*lcd_y+lcd_x

send_command(lcd_addr)

#发送地址for

chr

in

lcd_str:#获取字符串长度

send_data(ord(chr))#发送显示

#程序入口if__name__=='__main__':

init()#初始化显示屏

write(0,0,'Inputpassword:')

#在第一行显示Hello(2)执行代码,观察LCD液晶显示屏是否显示“Inputpassword”字符串,如图所示。图:显示字符串(1)打开在main.py主程序文件,编写开锁功能代码,用户可以旋转编码器,当旋转编码器旋转到对应数字时按下编码器中间按钮则选定当前数字作为密码,液晶显示屏的密码显示位数右移一位,当输入的密码为00000000时提示密码输入正确程序停止。步骤3:编写主函数代码并执行代码#!/usr/bin/envpython3#-*-coding:utf-8-*-importRPi.GPIOas

GPIOimport

timeimport

ro_encodeimport

LCD1602InPwd_list=[0]#当前密码password_list=[0,0,0,0,0,0,0,0]globalCounter=0count=0if__name__=="__main__":

ro_encode.init()#初始化旋转模块IO

LCD1602.init()#初始化LCD1602IO

LCD1602.write(0,0,"InputPassword:")

while

True:

#获取旋转模块数据

tmp=ro_encode.Rot_Deal()

#旋转编码方向位判断函数

if

tmp!=globalCounter:

#判断状态值发生改变

globalCounter=tmp

InPwd_list[count]=globalCounter

LCD_DISP2=''.join(str(x)for

x

in

InPwd_list)#组合密码字符串

LCD1602.write(0,1,LCD_DISP2)

#在第二行显示world!

#确定按钮判断

if

ro_encode.Rot_SW():

InPwd_list.append(globalCounter)

LCD_DISP2=''.join(str(x)for

x

in

InPwd_list)#旋转编码方向位判断函数

if

tmp!=globalCounter:

#判断状态值发生改变globalCounter=tmp

InPwd_list[count]=globalCounter

LCD_DISP2=''.join(str(x)for

x

in

InPwd_list)#组合密码字符串

LCD1602.write(0,1,LCD_DISP2)#在第二行显示world!

#确定按钮判断

if

ro_encode.Rot_SW():

InPwd_list.append(globalCounter)

LCD_DISP2=''.join(str(x)for

x

in

InPwd_list)

LCD1602.write(0,1,LCD_DISP2)

count=count+1

if

count==(len(password_list)-1):

if

InPwd_list==password_list:

print('密码正确,已为您打开保险柜!')

LCD_DISP1='PASSWORDOK'

LCD1602.write(0,0,LCD_DISP1)

break

else:

print('密码错误,请重新输入!')

count=0

globalCounter=0

InPwd_list=[0]

LCD1602.write(0,1,"")代码详解案例中调用旋转编码器库Rot_Deal()函数从而获取当前的旋转到的数字并赋值给变量tmp,如果当前的显示的数字与函数获取到的数字不一致则判断用户旋转了编码器,则将显示的数字在液晶屏上显示。tmp=ro_encode.Rot_Deal()#旋转编码方向位判断函数

if

tmp!=globalCounter:#判断状态值发生改变

globalCounter=tmp#换成当前最新的数值

InPwd_list[count]=globalCounter #密码列表转换为字符串

LCD_DISP2=''.join(

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论