基於IoT的多功能智能跑操系統

基于IoT的多功能智能跑操系统

基於IoT的多功能智能跑操系統

项目目标

  • 通过ESP32作为主控芯片实现打卡系统的基本逻辑功能
  • 利用RFID Unit 实现IC卡的信息识别、读取功能
  • 基于MQTT信息传输技术实现跑操信息的”线下-云平台“交互功能
  • 使用M5 StickV实现二维码识别技术

项目原理

  • MQTT

设置MQTT服务器有三个步骤:

  1. 设置MQTT服务器设置

    MQTT服务器的三大要素是:服务器ID,用户名和密码。其他要素,比如端口号是1883,一般都是用这个的,还有服务器是该平台的网址。

  2. 发布数据

    发布数据的两个要点是主题和数据格式。主题的格式不同的平台会有不同的要求,建议参考平台的API参数。第二是数据格式,一般都是用JSON格式。

  3. 订阅数据

订阅数据和发布数据基本相同,也是设置主题和数据。但发布和订阅的主题不同。因为MQTT是比较简单的通讯协议,所以安全性要由中间人来提供。订阅数据会返回Mid, Result两个值,可以透过这两个值检查数据有没有错误和有没 有上传成功,具体语句可以看PahoMQTT库。

我们用的是Ubidots这个IoT平台,详情可以参考这个网站。
Ubidots Docs
基於IoT的多功能智能跑操系統

  • M5StickV

    设置M5StickV识别二维码的步骤:

    1. 使用micropython自带的sensor和image库,分别设置摄影镜头和图像的参数。而LCD库为控制屏幕显示的参数。我们我镜头参数设定如下图像色彩格式:选择是RGB565色彩图。设置图像像素大小,sensor.QQVGA: 160x120。把img设为获取摄影机的图像。
    2. 使用img库的find_qrcode是检测图上是否有qrcode,如果有则会返回一系列的qrcode的参数,如解析的数据,规格等。
    3. 因为我们主要用的是解碼的代码,所以单独取译码结果来作下一步使用。
  • RFID

    RFID卡的结构有UID和BLOCKS。UID是每张卡的唯一标识符,只可读不可写。BLOCKS是可读可写的,因此我们把学生的数据放在BLOCKS里。值得注意的时要加入延时,否则如果进行可累加的操作,会因为射频处理识别的频率高而多次识别。

  • UART

    通用异步收发传输器(Universal Asynchronous Receiver/Transmitter,通常称作UART) 是一种串行异步收发协议,应用十分广泛。UART工作原理是将数据的二进制位一位一位的进行传输。在UART通讯协议中信号线上的状态位高电平代表’1’低电平代表’0’。当然两个设备使用UART串口通讯时,必须先约定好传输速率和一些数据位。在进行传输前必须要对硬件进行连接,连接方式如图所示:基於IoT的多功能智能跑操系統
    TX:发送数据端,要接对面设备的RX
    RX:接收数据端,要接对面设备的TX
    GND:保证两设备共地,有统一的参考平面
    我们先分析我们使用到的器件的接口,可以从硬件设计图中找到我们使用到的器件,M5Go Lite的TX和RX接口为GPIO17和GPIO16,而我们对M5StickV的GPIO35和GPIO34做端口映射成RX和TX,使M5GO和M5StickV的TX和RX相连,RX和TX相连。使用方法为调用Micropython带有的uart库,设置好相应平台。

概念图

基於IoT的多功能智能跑操系統

功能实现

以下功能在代码里都有注译,欢迎取用。

主要功能实现

  • M5GO LITE UI交互界面

  • M5GO LITE 实现 Wifi 连接功能

  • RFID读写IC卡信息

  • MQTT网络协议通讯实现云平台与开发板信息交互

  • M5StickV 识别读取二维码信息

  • 打卡系统以及其包含的信息查询、显示功能

次要功能實現

  • 单日不可重复打卡,不论任何方式
  • 扫瞄了非学生信息的二维码,不上传
  • 临时数据储存列表,以防上传失败

代码

M5GO LITE的代码

from m5stack import *
from m5ui import *
from uiflow import *
import wifiCfg
from m5mqtt import M5mqtt
import json
import time
import unit
import machine
from numbers import Number
def Wifi_reconnect():
  while (wifiCfg.wlan_sta.isconnected()) != 1:
    wifiCfg.reconnect()
  label0.setText('Wifi connected')

data = Noneial

#rfid init
rfid0 = unit.get(unit.RFID, unit.PORTA)

uart = None
t1 = None 
t2 = None


student_checkag=[] #存人数的列表
#mqtt initial
m5mqtt = M5mqtt('random', 'industrial.api.ubidots.com', 1883, 'BBFF-HXOoqxfhftjZSub2lDqbK019M3KHFg', '', 300)

#Label and tile set 
setScreenColor(0x000000)
label0 = M5TextBox(69, 33, "Running System", lcd.FONT_Comic,0x89eee1, rotate=0)
label1 = M5TextBox(40, 86, "Name :", lcd.FONT_DejaVu18,0xff66d2, rotate=0)
label2 = M5TextBox(76, 124, "ID :", lcd.FONT_DejaVu18,0xff66d2, rotate=0)
label3 = M5TextBox(40, 165, "Count :", lcd.FONT_DejaVu18,0xff66d2, rotate=0)
label4 = M5TextBox(135, 86, "", lcd.FONT_DejaVu18,0xff66d2, rotate=0)
label5 = M5TextBox(135, 124, "", lcd.FONT_DejaVu18,0xff66d2, rotate=0)
label6 = M5TextBox(135, 165, "", lcd.FONT_DejaVu18,0xff66d2, rotate=0)
label7 = M5TextBox(30, 188, "", lcd.FONT_DejaVu18,0xffd400, rotate=0)
label10 = M5TextBox(20, 35, "123", lcd.FONT_Default,0xFFFFFF, rotate=0)
label10.hide()
title10 = M5Title(title="Today runner list:", x=3 , fgcolor=0xFFFFFF, bgcolor=0x0000FF)
title10.hide()

#uart initial
uart = machine.UART(2, tx=17, rx=16) 
uart.init(115200, bits=8, parity=None, stop=1)

#var set
wifistatus = None
Name = None
count = None
uid = None
A = None
uartmsg=None
A_J = None
qruid=None
qrName=None
qrcount=None

m5mqtt.start()

#label hide and show 
def showlist():
  title10.show()
  label10.show()

def hidelist():
  title10.hide()
  label10.hide()
  
def showmainui():
  label0.show()
  label1.show()
  label2.show()
  label3.show()
  label4.show()
  label5.show()
  label6.show()
  label7.show()
  label8.show()
  label9.show()
  
def hidemainui():
  label0.hide()
  label1.hide()
  label2.hide()
  label3.hide()
  label4.hide()
  label5.hide()
  label6.hide()
  label7.hide()
  label8.hide()
  label9.hide()
  
def buttonA_wasPressed():
  showlist()

  global list_run
  list_run = ''
  student_checkag.sort()
  for i in range(len(student_checkag)):
    if(i==0):
      list_run=str(i+1)+'. '+student_checkag[i]+' '
      
    elif(i%4==0):
      list_run=str(i+1)+'. '+student_checkag[i]+' '+'\n'
      
    else:
      list_run=str(i+1)+'. '+student_checkag[i]+' '
      
  label10.setText(str(list_run))
  
  hidemainui()
  pass
btnA.wasPressed(buttonA_wasPressed)




def mainproamg():
  while True:
    while wifistatus == 0: #wifi set
      wifiCfg.auto_connect()
      Wifi_reconnect()
    try :
      if rfid0.isCardOn(): #如有卡片接触
        rgb.setColorAll(0xff0000)
        #rfid0.writeBlock(1,'213173444')
        #rfid0.writeBlock(2,'yangmi')
        
        uid = rfid0.readBlockStr(1)   #读UID
        if(str(uid) not in student_checkag):#该人本日是否有跑操记录
          Name = rfid0.readBlockStr(2) #读Name
          count = int((rfid0.readBlockStr(4))) #读跑操次數
          count = count + 1
          rfid0.writeBlock(4,str(count)) #刷新跑操次數 写入卡
          A = {"Student":{"value":count, "context":{"CardID":uid, "name" :Name }}}
          A_J = json.dumps(A) #生成JSON包
          label5.setText(str(uid))
          label4.setText(str(Name))
          label6.setText(str(count))
          m5mqtt.publish(str('/v1.6/devices/esp32'),str(A_J)) #publish mqtt
  
          student_checkag.append(str(uid)) #跑操者 寫入 列表
          speaker.sing(392, 1)  #铃声
          speaker.sing(349, 1)
          speaker.sing(330, 1)
          speaker.sing(294, 1)  
          wait_ms(1000)
          label7.setText(str(""))
        else: 
          #提示本日已經有拍卡
          label7.setText(str("Please do not scan again!"))
          wait_ms(2000)
          label7.setText(str(""))
    	
      elif(uart.any()): #如uart有资料
        #label5.setText(str("enter qr"))
        uartmsg = str((uart.read()).decode())#qrcode msg
        #label5.setText(str(uartmsg))
        save_d =eval(uartmsg)
        #label5.setText(str(uartmsg))
        qruid=save_d.get('Student').get('context').get('CardID')
        label5.setText(str(qruid))
        if(str(qruid) not in student_checkag): #该人本日是否有跑操记录
          qrcount=save_d.get('Student').get('value')#解释dict 取其中的关键值
          qrName=save_d.get('Student').get('context').get('name')
          qrcount=int(qrcount+1)
          label5.setText(str(qruid))
          label4.setText(str(qrName)) 
          label6.setText(str(qrcount))
          
          B = {"Student":{"value":qrcount, "context":{"CardID":qruid, "name" :qrName }}}
          B_J = json.dumps(B)
          m5mqtt.publish(str('/v1.6/devices/esp32'),str(B_J)) 
          student_checkag.append(str(qruid))
          wait_ms(2)
        else:
          label7.setText(str("Please do not scan again!"))
          wait_ms(2000)
          label7.setText(str(""))
        pass
    
    except:
      wait(1)
    wait_ms(2)
    
def buttonB_wasPressed():
  hidelist()
  showmainui()
  mainproamg()
  pass
btnB.wasPressed(buttonB_wasPressed)


mainproamg()

M5STICKV的代码

import sensor, image ,time #forcam
import lcd #for lcd屏
from machine import I2C,UART
from fpioa_manager import fm #导入maipy的fm(fpioa manager)这个内置的对象,用于后续注册工作。


#uart initial
fm.register(35, fm.fpioa.UART2_RX, force=True)
fm.register(34, fm.fpioa.UART2_TX, force=True)
uart_Port = UART(UART.UART2, 115200,8,0,0, timeout=1000, read_buf_len= 4096)

clock = time.clock()
lcd.init() #lcd initial
#set camera

sensor.reset()
sensor.set_pixformat(sensor.RGB565) #RGB565 
sensor.set_framesize(sensor.QQVGA) # can be QVGA on M7...
sensor.set_vflip(1) 
sensor.set_hmirror(1) 
sensor.skip_frames(20)
sensor.run(1)
sensor.set_auto_gain(False) #自动增益off
while(True):
    img = sensor.snapshot()
    fps =clock.fps() #
    check =img.find_qrcodes()#scan img find qrcode
    if(len(check)>0):
        try:
            tuplexboxa =check[0].rect()
            data0=check[0].payload()
            img.draw_string(15,20,"Scan Successfully!",(236,36,36),scale=1.0)
            img.draw_rectangle(tuplexboxa,(236,36,36))
            lcd.display(img)#在Lcd 屏中顯示鏡頭取得的圖片
            data=eval(data0)
            data2=data.get('Student')
            data3=data2.get("context")
            check1=('Student' in data)
            check2=('value' in data2)
            check3=('context' in data2)
            check4=('CardID' in data3)
            check5=('name' in data3)
            if(check1==True & check2==True & check3==True & check4==True & check5==True):
                 uart_Port.write(str(data))#uart发送解码资料
                 time.sleep(2)
        except:
            print("Invalid QR code") #如二维码格式不符
            strerror="Invalid QR code"#
            lcd.display(strerror)#


实际操作视频

查询跑操是否记录在列
wifi连接+单日打卡限制功能
RFID实现不同人连续打卡功能
StickV实现二维码读取功能

上一篇:RT-Thread应用实战-TI温湿度HDC1000软件包设计与制作


下一篇:【MaixPy教程】用maixHub训练模型进行开源硬件识别