综合案例2.0-自动感应门
最新案例教程点击下方链接跳转,CSDN已停止更新
点
击
跳
转
简介
很多公共场所采用自动感应门,当有人靠近时门会自动打开,远离时自动关门;有时候需要将门常开比如搬运货物,不方便将门关闭;或者场所夜晚关门时需要常关,不允许他人进入。
本案例模拟相应场景,设计一款可以使用手机APP来控制自动感应门的系统。
红外避障传感器
-
红外避障是避障传感器的一种,具有一对红外线发射与接收管,发射管发射出一定频率的红外线,当检测方向遇到障碍物(信号输出接口输出低电平信号,可通过电位器旋钮调节检测距离)。
-
规格参数:
1.工作电压:DC 3.3V-5V
2.工作电流:≥20mA
3.工作温度:-10℃—+50℃
4.检测距离:2-30cm
5.输出信号:有障碍物或反射到地面输出低电平,无障碍物高电平
6.调节方式:多圈电阻式调节
7.有效角度:35°
准备
本案例需要的硬件
器材 | 数量 |
---|---|
HaaS506开发板 | 1 |
红外避障传感器 | 1 |
SG90舵机 | 1 |
SIM卡 | 1 |
杜邦线 | 若干 |
硬件连接图
代码流程
1、连接阿里云平台
2、启用两个线程,避障传感器每秒将检测状态上传阿里云;舵机根据条件判断是否开门。
3、创建‘移动应用’功能,控制门禁正常、常闭、常开模式,并实时检测累计人流量。
4、将门禁状态上传阿里云平台。
功能实现
1、物联网平台开发
第一次使用物联网平台的读者,需要开通实例后使用物联网平台功能。也可以使用免费的公共实例进行开发,在阿里云物联网平台中,左上角选择‘华东2-上海’,点击‘公共实例’,即可开通。
1、平台产品创建可参考haas506 2.0开发教程-aliyunIoT
2、创建产品属性(添加物模型)
选择产品功能定义–编辑草稿
1、添加自定义功能
2、按照图2显示添加标识符与数据类型(标识符要与代码一致)
3、点击发布上线
- 点击确定
2、设备端开发
-
第一次使用开发板的读者可以按照haas5062.0开发教程-导学篇搭建开发环境。
-
搭建完后复制以下代码到Visual Studio Code,复制产品证书到代码相应位置。
-
舵机使用案例参考
-
2.2版本获取IMEI号接口有更新,需要更改以下内容(Ctrl+F 查找modem)
# 获取设备的IMEI 作为deviceName 进行动态注册
deviceName = modem.info.getDevImei()
...
main.py
# coding=utf-8
from driver import GPIO
from driver import PWM
import network
import ujson
import utime as time
import modem
from aliyunIoT import Device
import kv
import _thread
#当iot设备连接到物联网平台的时候触发'connect' 事件
def on_connect(data):
global module_name,default_ver,productKey,deviceName,deviceSecret,on_trigger,on_download,on_verify,on_upgrade
print('***** connect lp succeed****')
data_handle = {}
data_handle['device_handle'] = device.getDeviceHandle()
#当连接断开时,触发'disconnect'事件
def on_disconnect():
print('linkkit is disconnected')
servo_data={}
#当iot云端下发属性设置时,触发'props'事件
def on_props(request):
global servo_data,door_status
params=request['params']
params=eval(params)
door_status=params["door_status"]
servo_data["door_status"]= door_status
servo_data_str=ujson.dumps(servo_data)
data={
'params':servo_data_str
}
device.postProps(data)
#当iot云端调用设备service时,触发'service'事件
def on_service(id,request):
print('clound req id is {} , req is {}'.format(id,request))
#当设备跟iot平台通信过程中遇到错误时,触发'error'事件
def on_error(err):
print('err msg is {} '.format(err))
#网络连接的回调函数
def on_4g_cb(args):
global g_connect_status
pdp = args[0]
netwk_sta = args[1]
if netwk_sta == 1:
g_connect_status = True
else:
g_connect_status = False
#网络连接
def connect_network():
global net,on_4g_cb,g_connect_status
#NetWorkClient该类是一个单例类,实现网络管理相关的功能,包括初始化,联网,状态信息等.
net = network.NetWorkClient()
g_register_network = False
if net._stagecode is not None and net._stagecode == 3 and net._subcode == 1:
g_register_network = True
else:
g_register_network = False
if g_register_network:
#注册网络连接的回调函数on(self,id,func); 1代表连接,func 回调函数 ;return 0 成功
net.on(1,on_4g_cb)
net.connect(None)
else:
print('网络注册失败')
while True:
if g_connect_status:
print('网络连接成功')
break
time.sleep_ms(20)
#动态注册回调函数
def on_dynreg_cb(data):
global deviceSecret,device_dyn_resigter_succed
deviceSecret = data
device_dyn_resigter_succed = True
# 连接物联网平台
def dyn_register_device(productKey,productSecret,deviceName):
global on_dynreg_cb,device,deviceSecret,device_dyn_resigter_succed
key = '_amp_customer_devicesecret'
deviceSecretdict = kv.get(key)
print("deviceSecretdict:",deviceSecretdict)
if isinstance(deviceSecretdict,str):
deviceSecret = deviceSecretdict
if deviceSecretdict is None or deviceSecret is None:
key_info = {
'productKey': productKey ,
'productSecret': productSecret ,
'deviceName': deviceName
}
# 动态注册一个设备,获取设备的deviceSecret
#下面的if防止多次注册,当前若是注册过一次了,重启设备再次注册就会卡住,
if not device_dyn_resigter_succed:
device.register(key_info,on_dynreg_cb)
count_data = {}
def upload_count():
global count_data
count_data["person_count"]= count
count_data_str=ujson.dumps(count_data)
data1={
'params':count_data_str
}
device.postProps(data1)
def setOptionSero(duty_cycle):
global servo
param2 = {'freq':50, 'duty': duty_cycle }
servo.setOption(param2)
def operatorDoor():
global detected, closed,door_status
closed = True
# 开门后判断是否还有人
while True:
time.sleep_ms(50)
if door_status == 1:
openDoor()
elif door_status == -1:
closeDoor()
else:
if detected == True:
openDoor()
else:
closeDoor()
def openDoor():
global closed,servo
if closed == True:
print("open the door")
setOptionSero(12)
# TODO 开门操作
closed = False
def closeDoor():
global closed,servo
if closed == False:
time.sleep_ms(200)
print("close the door")
# 操作关门
setOptionSero(5)
closed = True
def infrared_status():
global detected, count, door_status
while True: # 无限循环
time.sleep_ms(50)
status = infrared.read()
# 检测到物体
if status == 0:
detected = True
# 非常闭状态的才上报
if door_status != -1:
count = count + 1
print("object detected, count = " + str(count))
upload_count()
# 检测到人后停5秒再检测,相当于模拟行人通过的时间
time.sleep(5)
# 没有检测到
elif status == 1:
detected = False
print('no object detected')
# 没检测到人,则间隔500ms检测一次
time.sleep_ms(500)
if __name__ == '__main__':
ICCID=None
g_connect_status = False
net = None
device = None
deviceSecret = None
deviceName = None
#替换以下产品信息
##################################
productKey = "a1JuD7ay6Pj"
productSecret = "yV68ScGy5DgEczVx"
##################################
device_dyn_resigter_succed = False
# 连接网络
connect_network()
# 获取设备的IMEI 作为deviceName 进行动态注册
#2.2版本改为
#deviceName = modem.info.getDevImei()
deviceName = modem.getDevImei()
#获取设备的ICCID
ICCID=modem.sim.getIccid()
#初始化物联网平台Device类,获取device实例
device = Device()
if deviceName is not None and len(deviceName) > 0 :
#动态注册一个设备
dyn_register_device(productKey,productSecret,deviceName)
else:
print("获取设备IMEI失败,无法进行动态注册")
while deviceSecret is None:
time.sleep(0.2)
print('动态注册成功:' + deviceSecret)
key_info = {
'region' : 'cn-shanghai' ,
'productKey': productKey ,
'deviceName': deviceName ,
'deviceSecret': deviceSecret ,
'keepaliveSec': 60,
}
#打印设备信息
print(key_info)
#device.ON_CONNECT 是事件,on_connect是事件处理函数/回调函数
device.on(device.ON_CONNECT,on_connect)
device.on(device.ON_DISCONNECT,on_disconnect)
device.on(device.ON_PROPS,on_props)
device.on(device.ON_SERVICE,on_service)
device.on(device.ON_ERROR,on_error)
device.connect(key_info)
# 初始化红外
infrared = GPIO()
print(infrared,'---------------------------')
infrared.open("infrared")
# 初始化舵机
servo = PWM()
servo.open("pwm_lpg")
#初始化数据
count = 0
detected = False
door_status = 0
upload_count()
time.sleep(2)
try:
# 启动红外检测
_thread.start_new_thread(infrared_status, ())
# 启动舵机模拟开门/关门操作线程
_thread.start_new_thread(operatorDoor, ())
except Exception as e:
print(e)
print("Error: unable to start thread")
while True:
time.sleep_ms(1000)
board.json
{
"name": "haas506",
"version": "2.0.0",
"io": {
"pwm_lpg": {
"type": "PWM",
"port": 3
},
"infrared":{
"type":"GPIO",
"port": 20,
"dir": "input",
"pull":"pullup"
},
"SPI0": {
"type": "SPI",
"port": 0,
"mode": "master",
"freq": 2000000
},
"serial1": {
"type": "UART",
"port": 0,
"dataWidth": 8,
"baudRate": 115200,
"stopBits": 1,
"flowControl": "disable",
"parity": "none",
"timeout": 1000
},
"serial2": {
"type": "UART",
"port": 1,
"dataWidth": 8,
"baudRate": 9600,
"stopBits": 1,
"flowControl": "disable",
"parity": "none",
"timeout": 1000
},
"serial3": {
"type": "UART",
"port": 2,
"dataWidth": 8,
"baudRate": 115200,
"stopBits": 1,
"flowControl": "disable",
"parity": "none",
"timeout": 1000
}
},
"debugLevel": "ERROR",
"repl": "enable",
"replPort": 0
}
3、调试
1、串口调试工具log,网络连接成功–动态注册成功–每秒打印红外避障传感器的状态,当有人进入打印‘open the door’,控制舵机开门,并显示上传云端当前人数;当没人进入打印‘no object detected’。
2、阿里云平台,打开实时刷新,会显示当前 进入人数。
4、创建移动应用
创建‘普通项目’
创建完自动跳转主页,关联相应产品
返回主页,新建移动应用
自动跳转应用编辑界面,选择组件→基础组件→图表→实时曲线,或者直接搜索。
添加完成后,配置组件信息。
添加‘单选’组件,并配置组件信息。
配置交互信息。
配置完成后保存,点击预览可以查看设置好的移动应用。
手机扫描二维码,可以在手机上选择自动门模式,并且实时查看人流量。