5.8 综合案例2.0-智能刷卡门禁系统(仅支持2.2以上版本)

最新案例教程点击下方链接跳转,CSDN已停止更新

点击跳转HaaS506官方最新案例







简介

使用MFRC522 RFID传感器与舵机制作的刷卡门禁系统。使用阿里云平台场景联动功能,只识别设定的卡号,简单实现多卡识别。满足小区使用场景。

准备

本案例需要的硬件

器材数量
HaaS506开发板1
MFRC522 RFID传感器1
SG90舵机1
喇叭1
SIM卡1
RFID卡片若干
杜邦线若干

硬件连接图

在这里插入图片描述

代码流程

1、连接阿里云平台
2、上报门禁状态
3、读RFID卡号,上传阿里云平台
4、云平台判断卡号,控制门禁
5,开门后等待时间,关闭门禁,上传门禁状态

功能实现

1、物联网平台开发

第一次使用物联网平台的读者,需要开通实例后使用物联网平台功能。也可以使用免费的公共实例进行开发,在阿里云物联网平台中,左上角选择‘华东2-上海’,点击‘公共实例’,即可开通。

1、平台产品创建可参考haas506 2.0开发教程-aliyunIoT
2、创建产品属性(添加物模型)
选择产品功能定义编辑草稿
在这里插入图片描述
1、添加自定义功能
2、按照图2显示添加标识符数据类型(标识符要与代码一致)
3、点击发布上线
在这里插入图片描述

  • 点击确定
    在这里插入图片描述

2、设备端开发

# 获取设备的IMEI 作为deviceName 进行动态注册
deviceName = modem.getDevImei()
...

改为

# 获取设备的IMEI 作为deviceName 进行动态注册
deviceName = modem.info.getDevImei()
...

注意:代码中mp3文件需要自行添加

main.py

# coding=utf-8
from driver import PWM
import network
import ujson
import utime as time
import modem
from  aliyunIoT import Device
import kv
import mfrc522
import audio 

 
#当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')

#当iot云端下发属性设置时,触发'props'事件
def on_props(request):
    global servo_data
    params=request['params']
    params=eval(params)
    servo=params["open_door"]
    servo_data={}
    if servo ==1:
        param2 = {'freq':50, 'duty': 12 }
        pwm_lpg.setOption(param2) 
        print('open zhe door')    
        servo_data["open_door"]= 1
        servo_data_str=ujson.dumps(servo_data)
        data={
            'params':servo_data_str
            }       
        device.postProps(data)
        aud.play('/data/pyamp/welcome.mp3')   
        time.sleep(3)  
        param2 = {'freq':50, 'duty': 5 }
        pwm_lpg.setOption(param2) 
        time.sleep(1)
        servo_data["open_door"]= 0
        servo_data_str=ujson.dumps(servo_data)
        data={
            'params':servo_data_str
            }       
        device.postProps(data)
    else:
        pass

#当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)
    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)   

def upload_uid():
    global uid_data
    uid_data["rfid"]= uid
    uid_data_str=ujson.dumps(uid_data)
    data={
        'params':uid_data_str
        }      
    device.postProps(data)


def do_read():
    global uid,uid_data
    rdr=mfrc522.MFRC522()
    uid = ''
    try:
        while True:
            (stat, tag_type) = rdr.request(rdr.REQIDL)
            if stat == rdr.OK:
                (stat, raw_uid) = rdr.anticoll()
                if stat == rdr.OK:	
                    uid=hex(raw_uid[0])[2:]+hex(raw_uid[1])[2:]+hex(raw_uid[2])[2:]+hex(raw_uid[3])[2:]		
                    print(' - uid	 : ',uid)
                    aud.play('/data/pyamp/ding.mp3') 
                    time.sleep(1)
                    upload_uid()
                else:
                    print('read error')
            time.sleep(1)			
    except KeyboardInterrupt:
        print("Bye")


if __name__ == '__main__':
    ICCID=None
    g_connect_status = False
    net = None
    device = None
    deviceSecret = None
    deviceName = None
    productKey = "your productKey "
    productSecret = "your productSecret "
    device_dyn_resigter_succed = False

    # 连接网络
    connect_network()
     # 获取设备的IMEI 作为deviceName 进行动态注册
    deviceName = modem.info.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)

    #上报信息
    servo_data={}
    pwm_lpg = PWM()
    pwm_lpg.open("pwm_lpg")
    param2 = {'freq':50, 'duty': 5 }
    pwm_lpg.setOption(param2) 
    time.sleep(1)
    servo_data["open_door"]= 0
    servo_data_str=ujson.dumps(servo_data)
    data={
        'params':servo_data_str
        }       
    device.postProps(data)



    #音频实例化
    aud=audio.Audio()
    aud.set_pa()        #开启使能
    aud.setVolume(10)    #设置音量

    print('witing read ------ ')
    uid_data={}
    do_read()




mfrc522.py


from driver import SPI
from driver import GPIO


class MFRC522:

	OK = 0
	NOTAGERR = 1
	ERR = 2

	REQIDL = 0x26
	REQALL = 0x52
	AUTHENT1A = 0x60   #验证A密钥
	AUTHENT1B = 0x61   #验证B密钥


	def __init__(self):
		self.spi=SPI()
		self.spi.open('SPI0')
		self.rst=GPIO()
		self.rst.open('rst')
		self.rst.write(0)	
		self.rst.write(1)
		self.init()

	def _wreg(self, reg, val):
		writeBuf=bytearray([int(0xff & ((reg << 1) & 0x7e)),int(0xff & val)])
		self.spi.write(writeBuf,2)

	def _rreg(self, reg):
		readBuf=bytearray(1)
		writeBuf=bytearray([int(0xff & (((reg << 1) & 0x7e) | 0x80))])
		self.spi.write(writeBuf,1)
		self.spi.read(readBuf,1)
		return readBuf[0]

	def _sflags(self, reg, mask):
		self._wreg(reg, self._rreg(reg) | mask)

	def _cflags(self, reg, mask):
		self._wreg(reg, self._rreg(reg) & (~mask))

	def _tocard(self, cmd, send):

		recv = []
		bits = irq_en = wait_irq = n = 0
		stat = self.ERR

		if cmd == 0x0E:
			irq_en = 0x12
			wait_irq = 0x10
		elif cmd == 0x0C:
			irq_en = 0x77
			wait_irq = 0x30

		self._wreg(0x02, irq_en | 0x80)
		self._cflags(0x04, 0x80)
		self._sflags(0x0A, 0x80)
		self._wreg(0x01, 0x00)

		for c in send:
			self._wreg(0x09, c)
		self._wreg(0x01, cmd)

		if cmd == 0x0C:
			self._sflags(0x0D, 0x80)

		i = 2000
		while True:
			n = self._rreg(0x04)
			i -= 1
			if ~((i != 0) and ~(n & 0x01) and ~(n & wait_irq)):
				break

		self._cflags(0x0D, 0x80)

		if i:
			if (self._rreg(0x06) & 0x1B) == 0x00:
				stat = self.OK

				if n & irq_en & 0x01:
					stat = self.NOTAGERR
				elif cmd == 0x0C:
					n = self._rreg(0x0A)
					lbits = self._rreg(0x0C) & 0x07
					if lbits != 0:
						bits = (n - 1) * 8 + lbits
					else:
						bits = n * 8

					if n == 0:
						n = 1
					elif n > 16:
						n = 16

					for _ in range(n):
						recv.append(self._rreg(0x09))
			else:
				stat = self.ERR

		return stat, recv, bits

	def _crc(self, data):
		self._cflags(0x05, 0x04)
		self._sflags(0x0A, 0x80)

		for c in data:
			self._wreg(0x09, c)

		self._wreg(0x01, 0x03)

		i = 0xFF
		while True:
			n = self._rreg(0x05)
			i -= 1
			if not ((i != 0) and not (n & 0x04)):
				break

		return [self._rreg(0x22), self._rreg(0x21)]

	def init(self):
		self.reset()
		self._wreg(0x2A, 0x8D)
		self._wreg(0x2B, 0x3E)
		self._wreg(0x2D, 30)
		self._wreg(0x2C, 0)
		self._wreg(0x15, 0x40)
		self._wreg(0x11, 0x3D)
		self.antenna_on()

	def reset(self):
		self._wreg(0x01, 0x0F)

	def antenna_on(self, on=True):
		if on and ~(self._rreg(0x14) & 0x03):
			self._sflags(0x14, 0x03)
		else:
			self._cflags(0x14, 0x03)

	def request(self, mode):
		self._wreg(0x0D, 0x07)
		(stat, recv, bits) = self._tocard(0x0C, [mode])
		if (stat != self.OK) | (bits != 0x10):
			stat = self.ERR

		return stat, bits

	def anticoll(self):
		ser_chk = 0
		ser = [0x93, 0x20]
		self._wreg(0x0D, 0x00)
		(stat, recv, bits) = self._tocard(0x0C, ser)
		if stat == self.OK:
			if len(recv) == 5:
				for i in range(4):
					ser_chk = ser_chk ^ recv[i]
				if ser_chk != recv[4]:
					stat = self.ERR
			else:
				stat = self.ERR
		return stat, recv

	def select_tag(self, ser):
		buf = [0x93, 0x70] + ser[:5]
		buf += self._crc(buf)
		(stat, recv, bits) = self._tocard(0x0C, buf)
		return self.OK if (stat == self.OK) and (bits == 0x18) else self.ERR

	def auth(self, mode, addr, sect, ser):
		return self._tocard(0x0E, [mode, addr] + sect + ser[:4])[0]

	def stop_crypto1(self):
		self._cflags(0x08, 0x08)

	def read(self, addr):      #读块数据

		data = [0x30, addr]
		data += self._crc(data)
		(stat, recv, _) = self._tocard(0x0C, data)
		return recv if stat == self.OK else None

	def write(self, addr, data):
		buf = [0xA0, addr]
		buf += self._crc(buf)
		(stat, recv, bits) = self._tocard(0x0C, buf)
		if not (stat == self.OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A):
			stat = self.ERR
		else:
			buf = []
			for i in range(16):
				buf.append(data[i])
			buf += self._crc(buf)
			(stat, recv, bits) = self._tocard(0x0C, buf)
			if not (stat == self.OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A):
				stat = self.ERR

		return stat


board.json

{
    "name": "haas506",
    "version": "2.0.0",
    "io": {
      "pwm_lpg": {
        "type": "PWM",
        "port": 3
        },
      "KEY1": {
        "type": "GPIO",
        "port": 44,
        "dir": "irq",
        "pull": "pullup",
        "intMode": "rising"
      },      
      "led1": {
        "type": "GPIO",
        "port": 7,
        "dir": "output",
        "pull": "pulldown"
      },
      "led_g": {
        "type": "GPIO",
        "port": 32,
        "dir": "output",
        "pull": "pulldown"
      },
      "cs": {
        "type": "GPIO",
        "port": 15,
        "dir": "output",
        "pull": "pullup"
      },
      "rst":{
        "type":"GPIO",
        "port": 31,
        "dir": "output",
        "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
  }
调试

1、阿里云平台,打开实时刷新,刷卡后卡片号码会即时上报在这里插入图片描述

3、场景联动设定

点击规则引擎场景联动,点击创建规则
在这里插入图片描述
进行规则设定,如下图所示,云端识别到卡号,就发送一条开门命令。
在这里插入图片描述
点击保存
在这里插入图片描述
启动场景联动
在这里插入图片描述

刷卡测试

使用预设卡片刷卡时,舵机会转动,将门打开,其他卡片不行

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值