[ERP]实时读取串口数据注意点

需求

erp通过com口与地磅连接,地磅每隔100ms传送一串子节数据给erp,erp显示数据稳定后对数据进行保存

难点

由于串口传输速度没有电脑处理的速度快,如果电脑也实时触发读取数据的方法就会造成数据的不完整

原因

当erp打开串口,数据就会存到缓存中,若一直不处理就一直存在缓存中,一旦通过serialPort.Read()进行读取就会清理缓存继而读取下一次的串口数据,就这个原因,数据有时会只读到串口传过来完整数据的其中一部分,这造成了显示不完整的情况

解决

比较简单粗暴的方法就是通过 Thread.Sleep();延时,等待串口发送完再做处理,延时时间要看串口的发送频率而定


image.png
具体实现代码如下
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;//设置该属性 为false
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            RegistryKey keyCom = Registry.LocalMachine.OpenSubKey("Hardware\\DeviceMap\\SerialComm");
            if (keyCom != null)
            {
                string[] sSubKeys = keyCom.GetValueNames();
                cmbPort.Items.Clear();
                foreach (string sName in sSubKeys)
                {
                    string sValue = (string)keyCom.GetValue(sName);
                    cmbPort.Items.Add(sValue);
                }
                if (cmbPort.Items.Count > 0)
                    cmbPort.SelectedIndex = 0;
            }
          
                cmbBaud.Text = "9600";

        }
        
        bool isOpened = false;//串口状态标志
        private void button1_Click(object sender, EventArgs e)
        {
            if (!isOpened)
            {
                serialPort.PortName = cmbPort.Text;
                serialPort.BaudRate = Convert.ToInt32(cmbBaud.Text, 10);
                try
                {
                    serialPort.Open();     //打开串口
                    button1.Text = "关闭串口";
                    cmbPort.Enabled = false;//关闭使能
                    cmbBaud.Enabled = false;
                    isOpened = true;
                    serialPort.DataReceived += new SerialDataReceivedEventHandler(post_DataReceived);//串口接收处理函数
                }
                catch
                {
                    MessageBox.Show("串口打开失败!");
                }
            }
            else
            {
                try
                {
                    serialPort.Close();     //关闭串口
                    button1.Text = "打开串口";
                    cmbPort.Enabled = true;//打开使能
                    cmbBaud.Enabled = true;
                    isOpened = false;
                }
                catch
                {
                    MessageBox.Show("串口关闭失败!");
                }
            }
            
        }
        string f = "";
        private void post_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                string s = "";
                Thread.Sleep(80);//用来读取完数据的字节数
                int byteNumber = serialPort.BytesToRead;

                //延时等待数据接收完毕。
                while ((byteNumber < serialPort.BytesToRead) && (serialPort.BytesToRead < 4800))
                {
                    byteNumber = serialPort.BytesToRead;
                    Thread.Sleep(20);//用来每个字节给多少时间处理
                }

                int n = serialPort.BytesToRead; //记录下缓冲区的字节个数 

                byte[] data = new byte[n];

                serialPort.Read(data, 0, n);

                foreach (byte item in data)
                {
                    s += Convert.ToChar(item);
                }
                f = s;
                this.ReceiveTbox.Text = s.ToString();


            }
            catch (Exception ee)
            {
            }
        }
        
        private void button2_Click(object sender, EventArgs e)
        {           
            string d = f;
            this.Close();
         }
        private void button3_Click(object sender, EventArgs e)
        {
            
            SendTbox.Text = f;          
            
        }
    }
}

你可能感兴趣的:([ERP]实时读取串口数据注意点)