这样学上位机,是不是有意思多了

写在前面

有小伙伴跟我说:

 

为了兑现承诺,这次给大家安排一个小项目案例,不管你是小白,还是有一定基础,都可以参与进来,一起把这个项目做出来。

项目需求

1、建立一个室内空气质量检测系统,要求电脑软件+单片机硬件,编程语言及硬件可以自行选择。

2、系统分为三部分:数据采集部分、数据传输部分、系统软件交互部分。

3、需求检测的数据:IAQ(Indoor Air Quality)、温度、湿度、PM2.5、CO2、CO。

4、数据传输可以选择串口、以太网、WIFI、蓝牙中的一种。

5、当检测到空气质量过差时,系统需要给出相应的解决方案(如:提示开窗通风等)。

协议分析

这个项目其实涉及到单片机开发,但这块并不是上位机的范畴。在确定好上位机与单片机之间的通信协议之后,双方都按照这个协议来开发,最终进行对接就可以了。这个协议一般是由单片机开发人员制定,本例协议制定如下:

  • 单片机发送的数据格式:#TXXX,YYY,S@

1、#后面的大写英文T表示对应的参数类型,具体对应关系如下:

序号参数名称参数代号
1 烟雾 S
2 温度 T
3 湿度 H
4 PM2.5 P
5 二氧化碳 C
6 一氧化碳 O

2、XXX:代表检测数值,占三个字符,例如010就是10。

3、YYY:代表该数组的限值,占三个字符,例如010就是10。

4、符号@前的S表示报警状态,1表示限值报警,0表示正常

  • 上位机进行限值设置发送数据格式:&SXXX$

1、&号后面的大写英文T表示对应的参数类型,对应关系同上。

2、XXX代表设置的限值数据,占三个字符

3、发送报文以$结束。

界面设计

根据项目需求,并结合协议设计界面如下:

 本案例的一个关键知识点在于自定义组合控件的使用。

如果让你来设计这个界面,你是否会考虑组合控件应用,如果全部用的是系统控件,那么代码会写得很复杂,而且容易出错,更重要的是扩展性会很差——如果需求发生变化,会需要改很多东西。

这里把参数的一系列状态及操作做成一个自定义控件,然后将相关的功能抽象成属性及事件。

序号名称读写类型
1 参数名称 读写 属性
2 实际值 读写 属性
3 报警状态 读写 属性
4 设定反馈 读写 属性
5 设定值 只读 属性
6 设置操作 --- 事件

实时通信

这里采用串口通信,针对SerialPort封装一个串口类,这里会涉及到串口通信、锁处理、委托技术,核心为串口接收事件,代码如下:

       private void MyCom_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            Thread.Sleep(50);
            int ByteToRead = MyCom.BytesToRead;
            lock (Lock)
            {
                //定义一个字节数组
                byte[] rcv = new byte[ByteToRead];
                //读取缓冲区里的数据放到字节数组中
                MyCom.Read(rcv, 0, ByteToRead);
                //这里如果想把字节数组给到主线程,需要使用委托
                ShowMsg?.Invoke(rcv);
            }
        }

参数设置功能:

        public bool SetValue(int Speed,Type type)
        {
            StringBuilder stringBuilder = new StringBuilder("&");
            stringBuilder.Append(type.ToString());
           stringBuilder.Append(Speed.ToString().PadLeft(3, '0'));
            stringBuilder.Append("$");
            lock (Lock)
            {
                try
                {
                    this.MyCom.Write(stringBuilder.ToString());
                }
                catch (Exception)
                {
                    return false;
                }
                return true;
            }
        }

主界面功能

有了以上的基础之后,主界面的功能开发就很容易了。

主界面的功能主要是两部分内容,第一部分内容是数据解析,将解析结果赋值给控件的属性进行显示,第二部分内容是通用的参数设置,将6个Monitor控件的参数设置事件都绑定同一个事件,然后在该事件里调用SetValue方法即可。

一般我们软件开发完成后,都应该先自我测试一下,便于及时发现问题,减少调试时间。

对于串口通信,可以我们通过虚拟串口来进行测试,仿真数据发送与数据接收,测试结果如下:

原文地址:https://www.cnblogs.com/xiketang/p/14809052.html