物联网实验四 RFID-2.4G有源实验

 

校名


校徽


《物联网实验》

实验报告



题  目 实验4 RFID-2.4G有源实验
姓  名 高星杰
学  号 2021307220712
专  业 计算机科学与技术
上课时间 2024春
授课教师 朱容波


2024 年 6月 25 日

[TOC]

实验4 RFID-2.4G有源实验

实验目的

  • 加深RFID-2.4G技术的理解
  • 掌握使用RFID的数据读取的方式
  • 了解2.4G有源卡的读取
  • 更好地理解物联网中的RFID标签的设计原理;
  • 进一步熟练实验,提高自己的实践动手能力;

实验要求

  • 通信协议:2.4G有源RFID

  • 实验内容:2.4G有源RFID数据读取

  • 参考视频:2.4G有源RFID数据读取实验.mp4

  • 通过Python编写界面程序实现RFID端口数据读取

实验设备

  • 硬件:2.4G 有缘 RFID 节点,串口线,物联网实验开发箱;
  • 软件:Keli4 For ARM 开发软件,串口调试工具;
  • 参考资料:协议栈 API 接口说明文档,LoRa 源码,STM32 工程源码

实验原理

在进行实验之前,要先对实验理论进行了解。

首先我们要对RFID-2.4G技术进行了解,对此我们将以问答的形式给出。

什么是有源RFID-2.4G?

RFID-2.4G 是工作在2.4GHz频段的射频识别系统(RFID),这是一种利用无线电波进行非接触式数据传输的技术,广泛应用于资产跟踪、人员定位、供应链管理等领域。2.4GHz频段属于微波频段的一部分,具体范围通常在2.4GHz至2.5GHz之间。由于这一频段与Wi-Fi、蓝牙等常见设备共用,具有较好的兼容性和全球应用前景。

RFID-2.4G系统通常为有源RFID系统,这意味着标签内置有电池,可以主动发送信号,而不是像无源RFID那样依赖读卡器提供能量。有源标签具备较长的读取距离,通常可达数十米甚至几百米;较大的数据存储容量,可以存储大量数据如传感器数据、时间戳等;多功能性,可以实现环境监测、实时定位等高级功能。

这种系统广泛应用于需要远距离数据传输和监控的场景,如仓库和工厂中高价值物品的资产追踪、安全管理中的人员定位(例如医院病人监控、监狱囚犯管理),以及物流运输过程中货物的实时监控。其优势包括读取距离长、实时数据传输和高数据处理能力,但也面临电池寿命需要定期更换、系统成本较高以及可能受到频段共用设备干扰的问题。

所以我们就可以了解RFID-2.4G系统是利用2.4GHz频段进行数据传输,凭借其远距离读取和实时监控的能力,在资产追踪、人员定位和供应链管理等领域有着广泛应用。尽管面临一些挑战,其独特优势使其在许多应用场景中仍然是不可替代的技术手段。

实验步骤

  1. 前期准备:观看实验教学视频,了解实验步骤,理解实验原理,阅读参考手册,详细了解实验步骤,抓住实验细节;
  2. 标签连接好电源;
  3. 用公母直连线连接电脑串口和有源2.4G节点的DB9接头,S1开关拨打到左边,让DB9和2.4G读卡器相连;
  4. 打开串口调试助手,串口参数:9600 8 N 1 ,标签自动向读卡器发信息,其中 FB 10 00 00 0C 0F 01 01 就是读到的有源卡的卡号。
  5. 使用GUI显示界串口接收到的数据。

实验结果

1 标签连接好电源

image-20240626192948733

2 连接有源2.4G节点和电脑

image-20240626193000812

3 使用串口调试助手读取卡号

f7be87e9a07c64436af2ac66fa1149f4

4 使用Python编写可视化GUI,并接收数据

db6785af4fbc48c37961a5e5c45dee6c

完整代码+逐行注释

import threading  # 用于实现多线程
import serial  # pySerial库,用于串口通信
from tkinter import ttk  # ttk模块提供了若干新小部件
import tkinter as tk  # Tkinter是Python的标准GUI库
import binascii  # 用于二进制和ASCII字符串的相互转换

# 一个简单的信息窗口类


class InformWindow:
    def __init__(self, informStr):
        self.window = tk.Tk()
        self.window.title("Information")  # 设置窗口标题
        self.window.geometry("220x60")  # 设置窗口大小
        label = tk.Label(self.window, text=informStr)  # 显示信息的标签
        buttonOK = tk.Button(self.window, text="OK",
                             command=self.processButtonOK)  # 确定按钮
        label.pack(side=tk.TOP)
        buttonOK.pack(side=tk.BOTTOM)
        self.window.mainloop()  # 进入消息循环

    def processButtonOK(self):
        self.window.destroy()  # 销毁窗口

# 主GUI类


class mainGUI:
    def __init__(self):
        window = tk.Tk()
        window.title("GUI UART Tx/Rx Demo")  # 设置窗口标题
        self.uartState = False  # 标识串口是否打开

        # 包含COM信息和开始/停止按钮的框架
        frame_COMinf = tk.Frame(window)
        frame_COMinf.grid(row=1, column=1)
        labelCOM = tk.Label(frame_COMinf, text="COMx: ")  # COM端口标签
        self.COM = tk.StringVar(value="COM1")  # COM端口变量
        ertryCOM = tk.Entry(frame_COMinf, textvariable=self.COM)  # 输入COM端口
        labelCOM.grid(row=1, column=1, padx=5, pady=3)
        ertryCOM.grid(row=1, column=2, padx=5, pady=3)
        labelBaudrate = tk.Label(frame_COMinf, text="Baudrate: ")  # 波特率标签
        self.Baudrate = tk.IntVar(value=115200)  # 波特率变量
        ertryBaudrate = tk.Entry(
            frame_COMinf, textvariable=self.Baudrate)  # 输入波特率
        labelBaudrate.grid(row=1, column=3, padx=5, pady=3)
        ertryBaudrate.grid(row=1, column=4, padx=5, pady=3)
        labelParity = tk.Label(frame_COMinf, text="Parity: ")  # 校验位标签
        self.Parity = tk.StringVar(value="NONE")  # 校验位变量
        comboParity = ttk.Combobox(
            frame_COMinf, width=17, textvariable=self.Parity)  # 校验位下拉框
        comboParity["values"] = ("NONE", "ODD", "EVEN", "MARK", "SPACE")
        comboParity["state"] = "readonly"
        labelParity.grid(row=2, column=1, padx=5, pady=3)
        comboParity.grid(row=2, column=2, padx=5, pady=3)
        labelStopbits = tk.Label(frame_COMinf, text="Stopbits: ")  # 停止位标签
        self.Stopbits = tk.StringVar(value="1")  # 停止位变量
        comboStopbits = ttk.Combobox(
            frame_COMinf, width=17, textvariable=self.Stopbits)  # 停止位下拉框
        comboStopbits["values"] = ("1", "1.5", "2")
        comboStopbits["state"] = "readonly"
        labelStopbits.grid(row=2, column=3, padx=5, pady=3)
        comboStopbits.grid(row=2, column=4, padx=5, pady=3)
        self.buttonSS = tk.Button(
            frame_COMinf, text="Start", command=self.processButtonSS)  # 开始/停止按钮
        self.buttonSS.grid(row=3, column=4, padx=5, pady=3, sticky=tk.E)

        # 串口对象
        self.ser = serial.Serial()

        # 串口读取线程
        self.ReadUARTThread = threading.Thread(target=self.ReadUART)
        self.ReadUARTThread.start()

        # 接收数据的框架
        frameRecv = tk.Frame(window)
        frameRecv.grid(row=2, column=1)
        labelOutText = tk.Label(frameRecv, text="ReceivedData:")  # 接收数据标签
        labelOutText.grid(row=1, column=1, padx=3, pady=2, sticky=tk.W)
        frameRecvSon = tk.Frame(frameRecv)
        frameRecvSon.grid(row=2, column=1)
        scrollbarRecv = tk.Scrollbar(frameRecvSon)
        scrollbarRecv.pack(side=tk.RIGHT, fill=tk.Y)
        self.OutputText = tk.Text(frameRecvSon, wrap=tk.WORD, width=60,
                                  height=20, yscrollcommand=scrollbarRecv.set)  # 显示接收数据的文本框
        self.OutputText.pack()

        # 发送数据的框架
        frameTrans = tk.Frame(window)
        frameTrans.grid(row=3, column=1)
        labelInText = tk.Label(frameTrans, text="To Transmit Data:")  # 发送数据标签
        labelInText.grid(row=1, column=1, padx=3, pady=2, sticky=tk.W)
        frameTransSon = tk.Frame(frameTrans)
        frameTransSon.grid(row=2, column=1)
        scrollbarTrans = tk.Scrollbar(frameTransSon)
        scrollbarTrans.pack(side=tk.RIGHT, fill=tk.Y)
        self.InputText = tk.Text(frameTransSon, wrap=tk.WORD, width=60,
                                 height=5, yscrollcommand=scrollbarTrans.set)  # 输入发送数据的文本框
        self.InputText.pack()
        self.buttonSend = tk.Button(
            frameTrans, text="Send", command=self.processButtonSend)  # 发送按钮
        self.buttonSend.grid(row=3, column=1, padx=5, pady=3, sticky=tk.E)
        window.mainloop()

    def processButtonSS(self):
        if (self.uartState):
            self.ser.close()  # 关闭串口
            self.buttonSS["text"] = "Start"  # 更改按钮文字
            self.uartState = False
        else:
            # 重新启动串口
            self.ser.port = self.COM.get()
            self.ser.baudrate = self.Baudrate.get()
            strParity = self.Parity.get()
            if (strParity == "NONE"):
                self.ser.parity = serial.PARITY_NONE
            elif (strParity == "ODD"):
                self.ser.parity = serial.PARITY_ODD
            elif (strParity == "EVEN"):
                self.ser.parity = serial.PARITY_EVEN
            elif (strParity == "MARK"):
                self.ser.parity = serial.PARITY_MARK
            elif (strParity == "SPACE"):
                self.ser.parity = serial.PARITY_SPACE

            strStopbits = self.Stopbits.get()
            if (strStopbits == "1"):
                self.ser.stopbits = serial.STOPBITS_ONE
            elif (strStopbits == "1.5"):
                self.ser.stopbits = serial.STOPBITS_ONE_POINT_FIVE
            elif (strStopbits == "2"):
                self.ser.stopbits = serial.STOPBITS_TWO

            try:
                self.ser.open()  # 打开串口
            except:
                informStr = "Can't open " + self.ser.port
                InformWindow(informStr)

            if (self.ser.isOpen()):  # 打开成功
                self.buttonSS["text"] = "Stop"  # 更改按钮文字
                self.uartState = True

    def processButtonSend(self):
        if (self.uartState):
            strToSend = self.InputText.get(1.0, tk.END)
            bytesToSend = bytes.fromhex(strToSend[0:-1])  # 将输入的十六进制字符串转换为字节
            self.ser.write(bytesToSend)  # 发送数据
            print(bytesToSend)
        else:
            informStr = "UART is not open"
            InformWindow(informStr)

    def ReadUART(self):
        while True:
            if (self.uartState):
                try:
                    ch = self.ser.read()  # 读取一个字节
                    print(ch, end='')
                    data = str(binascii.b2a_hex(ch))  # 将字节转换为十六进制字符串
                    print(str(data[1:]).split('\\x'))
                    self.OutputText.insert(
                        tk.END, data.split('b\'\\x'))  # 在文本框中显示接收到的数据
                except:
                    informStr = "Error reading UART"
                    InformWindow(informStr)
                    self.ser.close()  # 关闭串口
                    self.buttonSS["text"] = "Start"
                    self.uartState = False


# 启动主GUI
mainGUI()

实验总结与感悟

本次实验是一次难忘且充实的学习体验,通过实际操作2.4G有源RFID系统,我不仅加深了对RFID技术的理解,也提升了自己在物联网领域的动手实践能力。

在实验的开始阶段,我观看了教学视频并阅读了相关文档,详细了解了实验的每一步骤和技术原理。通过预先的理论学习,使我在动手操作时更加得心应手。特别是在连接硬件和调试软件时,视频的演示和指导为我提供了清晰的操作路径,减少了许多可能遇到的困惑和问题。

实验过程中,我们小组齐心协力,按照步骤连接读卡器和标签,并通过串口调试助手成功读取到了有源RFID标签的数据。当我们在调试过程中遇到数据传输不稳定的问题时,通过查阅资料和与同学讨论,我们找到了问题的根源并成功解决。这一过程不仅增强了团队协作精神,也让我意识到理论知识和实际操作的紧密联系。

在整个实验中,最让我感到兴奋的是将理论转化为实践的过程。从代码编写到硬件连接,每一步都充满了挑战和乐趣。特别是通过Python编写的程序实现了对串口数据的实时监控和可视化展示,这不仅仅是一次编程练习,更是一次全面的系统设计和实现的过程。在看到实验结果成功显示在屏幕上的那一刻,我深深感受到了成就感和满足感。

通过这次实验,我深刻理解了2.4G有源RFID在物联网中的广泛应用,特别是在物流运输和人员定位等领域的巨大潜力。我们使用的有源RFID系统以其稳定、低功耗和长距离的特点,展示了其在实际应用中的优势。实验中的每一个环节都让我更加熟悉了物联网硬件和软件的结合,为未来的学习和工作打下了坚实的基础。

本次实验不仅巩固了课堂所学的理论知识,更让我在实际操作中收获颇丰。感谢老师的耐心指导和同学们的热心帮助,让我在学习的道路上不断进步。通过这次实验,我不仅学到了技术,更体会到了团队合作和持续学习的重要性。期待在未来的学习中,能够继续探索和应用更多的物联网技术,不断提升自己的专业素养和技能。