物联网工程关键技术-停车场收费系统

20210320069-苏荣意

本章讲解运用C#及Visual Studio 2022编写代码获取高频RFID卡实现简单的停车场收费系统

1. 介绍
在物联网工程的学习过程中,我深入了解了RFID技术,并掌握了其关键技术。同时,我也学会了使用串口工具,这为我在RFID应用中的数据传输提供了便利。

2. RFID技术
RFID技术(Radio Frequency Identification)是一种通过无线电频率识别和追踪标签的技术。它可以实现对物体的自动识别和数据采集,使得物联网系统更加智能化和高效。

3. 学会使用RFID技术
在学习过程中,我深入了解了RFID技术的原理和应用。我学会了选择合适的RFID标签和读写器,并掌握了其配置和使用方法。通过实践,我成功地实现了RFID标签的读取和写入,为物联网应用中的数据采集和追踪提供了基础支持。

4. 学会使用串口工具
为了更好地实现RFID数据的传输和处理,我学会了使用串口工具。串口工具可以连接RFID读写器和计算机,通过串口通信实现数据的传输和控制。我学会了设置串口的参数,如波特率、数据位、停止位等,并成功地实现了RFID数据的读取和写入实现简单停车场收费系统。

硬件连接

串口线:连接计算机串口与 NEWLab 平台串口。电源适配器:连接电源适配器 DC12V 到 NEWLab 平台。I0 口: H 射频模块和 M3 核心模块采用 SPI 通信方式。SPI 是行外设接SerialPeripheral Interface 简写)。SPI 的通信原理很简单,它以主从方式工作,这种模式通常有一个主设备和一个或多个从设备,需要至少4 根线。HF 射频模块 MISO、MOSI、SCK、NSS、RST分别连接 M3 核心模块的 PA6、PA7、PA5、PA4、PA0

 

VS Form的窗体界面及代码

串口配置

 停车场收费系统

public partial class Form1 : Form
{
    public delegate void showReceiveDelegate(string text); //当采用响应模式,应申明一个委托,实现不同线程的控件实验
    SerialPort com = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One);
    int com_num = 0;
    int timer_num;
    /*-------------------------------------------------------------
        * status_num状态字
        * 1,表示读取信息
         
        --------------------------------------------------------------*/
    int status_num=0;//状态字

        

    public Form1()
    {
        InitializeComponent();
    }
        
    //窗体加载
    private void Form1_Load(object sender, EventArgs e)
    {
        //串口初始化
        cmbPort.SelectedIndex = 2;
        cmbBaudRate.SelectedIndex = 4;
        cmbDataBits.SelectedIndex = 0;
        cmbStopBits.SelectedIndex = 0;
        cmbParity.SelectedIndex = 0;
        //定时器初始化
        System.Timers.Timer t = new System.Timers.Timer(50);//实例化Timer类,设置间隔时间为1000毫秒 就是1秒;
        t.Elapsed += new System.Timers.ElapsedEventHandler(theout);  //到达时间的时候执行事件;
        t.AutoReset = true;  //设置是执行一次(false)还是一直执行(true);
        t.Enabled = true;    //是否执行System.Timers.Timer.Elapsed事件;
        timer_num = 0;

    }
    //串口打开与关闭
    private void btnOpen_Click(object sender, EventArgs e)
    {
        if (btnOpen.Text == "打开串口")
        {
            try
            {
                if (!com.IsOpen)
                {
                    com.PortName = cmbPort.Text;
                    com.BaudRate = int.Parse(cmbBaudRate.Text);
                    com.DataBits = int.Parse(cmbDataBits.Text);
                    switch (cmbStopBits.SelectedIndex)
                    {
                        case 0:
                            com.StopBits = StopBits.One; break;
                        case 1:
                            com.StopBits = StopBits.Two; break;
                        case 2:
                            com.StopBits = StopBits.OnePointFive; break;
                        case 3:
                            com.StopBits = StopBits.None; break;
                    }
                    switch (cmbParity.SelectedIndex)
                    {
                        case 0: com.Parity = Parity.None; break;
                        case 1: com.Parity = Parity.Odd; break;
                        case 2: com.Parity = Parity.Even; break;
                    }

                    com.Open();//打开串口
                }
                btnOpen.Text = "关闭串口";
                txtStatus.Text = "串口已打开!";
                btnInformation.Enabled = true;
                btnClear.Enabled = true;
                button1.Enabled = true;
                //button2.Enabled = true;
                // 数据接收模式变化时,设置串口的数据接收侦听事件
                try
                {
                    com.DataReceived += new SerialDataReceivedEventHandler(com_DataReceived);  //加载接收事件
                }
                catch (Exception err)
                {
                    txtStatus.Text = err.ToString();
                } 
            }
            catch
            { txtStatus.Text = "串口打开错误或串口不存在!";
            }
        }
        else //关闭串口
            try
            {
                if (com.IsOpen)
                    com.Close(); //关闭串口
                btnOpen.Text = "打开串口";
                txtStatus.Text = "串口已关闭!";
                btnInformation.Enabled = false;
                btnClear.Enabled = false;
                button1.Enabled = false;
                //button2.Enabled = false;
            }
            catch
            {
                    
                txtStatus.Text = "串口关闭错误或串口不存在!";
            }
    }
    //--------------------------------------------------------------------------------
    //定时器相关设置
    public void theout(object source, System.Timers.ElapsedEventArgs e)
    {
        timer_num++;
        this.BeginInvoke(new TextOption(function1));//invok 委托实现跨线程的调用            
    }
    delegate void TextOption();//定义一个委托

    void function1()
    {
        if ((timer_num > 10)&&(com_num>5))
        {
            com_num = 0;
            try
            {
                int count = com.BytesToRead;
                byte[] readBuffer = new byte[count];
                com.Read(readBuffer, 0, count);
                //String strReceive = Encoding.Default.GetString(readBuffer);  //字母、数字、汉字转换为字符串                
                String strReceive = getStringFromBytes(readBuffer);  //转十六进制                
                this.Invoke(new showReceiveDelegate(doShowReceive), strReceive);
            }
            catch (Exception err)
            {
                txtStatus.Text = err.ToString();
            }                
        }
    }
    //--------------------------------------------------------------------------------
    // 响应模式时,串口接收数据事件        
    private void com_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {
        com_num = com.BytesToRead;
        timer_num = 0;
    }
            // 把字节数组转换为十六进制格式的字符串。
    // <param name="pByte">要转换的字节数组。</param>
    // <returns>返回十六进制格式的字符串。</returns>
    public static string getStringFromBytes(byte[] pByte)
    {
        string str = "";     //定义字符串类型临时变量。
        //遍历字节数组,把每个字节转换成十六进制字符串,不足两位前面添“0”,以空格分隔累加到字符串变量里。
        for (int i = 0; i < pByte.Length; i++)
            str += (pByte[i].ToString("X").PadLeft(2, '0') + " ");
        str = str.TrimEnd(' ');     //去掉字符串末尾的空格。
        return str;     //返回字符串临时变量。
    }
        //<summary>
        //把十六进制格式的字符串转换成字节数组。
        //</summary>
        //<param name="pString">要转换的十六进制格式的字符串</param>
        //<returns>返回字节数组。</returns>
    public static byte[] getBytesFromString(string pString)
    {
        string[] str = pString.Split(' ');     //把十六进制格式的字符串按空格转换为字符串数组。
        byte[] bytes = new byte[str.Length];     //定义字节数组并初始化,长度为字符串数组的长度。
        for (int i = 0; i < str.Length; i++)     //遍历字符串数组,把每个字符串转换成字节类型赋值给每个字节变量。
            bytes[i] = Convert.ToByte(Convert.ToInt32(str[i], 16));
        return bytes;     //返回字节数组。
    }
    //------------------------------------------------------------
    //清空接收框内容
    private void btnClear_Click(object sender, EventArgs e)
    {
        txtSend.Text = "";
        txtReceive.Text = "";
        txtInformation.Text = "";
        txtStatus.Text = "数据已经清除!";
    }
    //异步线程处理接受的字符,显示在接收的文本框中
    public void doShowReceive(string str)
    {            
        txtReceive.Text = str;

        //高频卡获取卡信息
        if (status_num == 20)
        {
            status_num = 0;
            int i;
            for (i = 0; i < 10; i++)
            {
                if (str.Substring(i, 20).Equals("FF 55 00 00 81 03 08"))
                {
                    btn_Entrance.Enabled = true;
                    txtInformation.Text = str.Substring(i + 21, 11);//截取4个字节
                    txtStatus.Text = "高频卡信息读取成功!";
                    break;
                }
            }
            if (i >= 10)
            {
                txtStatus.Text = "无法获取高频卡信息!";
            }
        }

        //入场
        if (status_num == 21)
        {
            status_num = 0;
            if (str.Substring(18, 2).Equals("08"))
            {
                string str1 = str.Substring(21, 11);
                txtInformation.Text = str1;
                if (!File.Exists(@"E:\物联网关键技术\20210320069\停车场信息1.txt"))
                {
                    FileStream fs = new FileStream(@"E:\物联网关键技术\20210320069\停车场信息1.txt", FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None);
                    fs.Close();
                }
                List<string> lines2 = new List<string>(File.ReadAllLines(@"E:\物联网关键技术\20210320069\停车场信息1.txt"));
                        
                for (int j = 0; j < lines2.Count; j++)
                {
                    if (str1 == lines2[j])
                    {
                        txtStatus.Text = "卡信息已注册!";
                        textBox13.Text = "";
                        textBox14.Text = "";
                        textBox17.Text = "";
                        textBox18.Text = "";
                        textBox19.Text = "";
                        return;
                    }
                }
                textBox13.Text = DateTime.Now.ToString();
                textBox14.Text = "10000";
                string[] lines1 = { textBox13.Text, textBox14.Text, txtInformation.Text };
                File.AppendAllLines(@"E:\物联网关键技术\20210320069\停车场信息1.txt", lines1);
                txtStatus.Text = "读卡成功,进入停车场,开始记录时间!";
            }
             
        }

        //出场
        if (status_num == 22)
        {
            status_num = 0;
            if (str.Substring(18, 2).Equals("08"))
            {
                string str1 = str.Substring(21, 11);//截取4个字节
                List<string> lines = new List<string>(File.ReadAllLines(@"E:\物联网关键技术\20210320069\停车场信息1.txt"));
                for (int i = 0; i < lines.Count; i++)
                {
                    if (str1 == lines[i])
                    {
                        var t = Convert.ToDateTime(lines[i - 2]);
                        textBox18.Text = t.ToString();
                        var tt = DateTime.Now - t;
                        textBox17.Text = tt.ToString();
                        txtStatus.Text = "出场成功!";
                        int h, m, s, sum;
                        string a;
                        h = tt.Hours;
                        m = tt.Minutes;
                        s = tt.Seconds;
                        s = h * 3600 + m * 60 + s * 2;
                        a = lines[i - 1];
                        sum = int.Parse(a) - s;
                        textBox19.Text = s.ToString();
                        textBox14.Text = sum.ToString();
                        textBox13.Text = lines[i - 2];
                        txtInformation.Text = str1;

                        lines.RemoveAt(i);
                        lines.RemoveAt(i - 1);
                        lines.RemoveAt(i - 2);
                        File.WriteAllLines(@"E:\物联网关键技术\20210320069\停车场信息1.txt", lines.ToArray());
                        return;
                    }
                }
                txtStatus.Text = "出厂失败,卡号是否已入场!";
                textBox13.Text = "";
                textBox14.Text = "";
                textBox17.Text = "";
                textBox18.Text = "";
                textBox19.Text = "";
            }
        }
    }
    //获取高频卡信息
    private void btn_HighFrequencyCardInformation_Click(object sender, EventArgs e)
    {
        txtSend.Text = "";
        txtReceive.Text = "";
        status_num = 20;

        String str1 = "FF 55 00 00 01 03 00 30 75";
        byte[] data = getBytesFromString(str1);
        com.Write(data, 0, data.Length);
        txtSend.Text = str1;
    }

    //入场
    private void btn_Entrance_Click(object sender, EventArgs e)
    {
        txtSend.Text = "";
        txtReceive.Text = "";
        status_num = 21;

        String str1 = "FF 55 00 00 01 03 00 30 75";
        byte[] data = getBytesFromString(str1);
        com.Write(data, 0, data.Length);
        txtSend.Text = str1;
    }

    //出场
    private void btn_Leave_Click(object sender, EventArgs e)
    {
        txtSend.Text = "";
        txtReceive.Text = "";
        status_num = 22;

        String str1 = "FF 55 00 00 01 03 00 30 75";
        byte[] data = getBytesFromString(str1);
        com.Write(data, 0, data.Length);
        txtSend.Text = str1;
    }
}

列子

入场冲突

 出场

出场冲突 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值