【问题标题】:C# Sending data via Serial Port, data in byte array is received incompleteC#通过串口发送数据,字节数组中的数据接收不完整
【发布时间】:2014-09-07 09:07:31
【问题描述】:

我正在开发一个从 ATmega8A 接收信息的 GUI 界面。 GUI 中的以下代码必须执行以下操作:

  • 检查标头:在这里,我正在将数据读入一个字节数组 (byte[] test),该字节数组正在与 OxFF 进行检查
  • 如果header == 0xFF,则读取第二个字节数组(byte[] data

请看下面的代码。

现在,我有以下问题。如果我只发送一个数字,例如 1,则该数字将毫无问题地显示在 textBox1 中。但是,如果我尝试发送像 433 这样的号码,我总是收到 4,33 会丢失。我认为这是由于我包含了 if 语句,但我无法解释为什么该数据会丢失。

namespace RS232
{
   public partial class fclsRS232Tester : Form
   {
    string InputData = String.Empty;
    string initText = "waiting...";

    delegate void SetTextCallback(string text);

    public fclsRS232Tester()
    {
        InitializeComponent();

        // Nice methods to browse all available ports:
        string[] ports = SerialPort.GetPortNames();

        // Add all port names to the combo box:
        foreach (string port in ports)
        {
            cmbComSelect.Items.Add(port);
        }

        cmbBaud.Items.Add(2400);
        cmbBaud.Items.Add(9600);

        cmbComSelect.SelectedIndex = 0;
        cmbBaud.SelectedIndex = 1;

        button4.Enabled = false;
        textBox1.Text = initText;
        textBox2.Text = initText;

    }

    private void cmbComSelect_SelectionChangeCommitted(object sender, EventArgs e)
    {
        if (port.IsOpen) port.Close();
        port.PortName = cmbComSelect.SelectedItem.ToString();
        stsStatus.Text = port.PortName + ": 9600,8N1";

        // try to open the selected port:
        try
        {
            port.Open();
            button4.Enabled = true;
            textBox1.Clear();
            textBox2.Clear();
        }
        // give a message, if the port is not available:
        catch
        {
            MessageBox.Show("Serial port " + port.PortName + " cannot be opened!", "RS232      tester", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            cmbComSelect.SelectedText = "";
            stsStatus.Text = "Select serial port!";
        }
    }

    private void port_DataReceived_1(object sender, SerialDataReceivedEventArgs e)
    {
        int bytenumber;
        int bufferSize = port.BytesToRead;
        byte[] test = new byte[1];
        byte[] data = new byte[bufferSize];
        byte[] data2 = new byte[bufferSize];

        port.Read(test, 0, 1);

        if (test[0] == 0xFF)  //Receive X-andY- coordinates from MCU and plot the coordinates 
        {
            bytenumber = port.Read(data, 0, bufferSize);
            string info = System.Text.Encoding.ASCII.GetString(data);

            this.Invoke((MethodInvoker)delegate
            {
                this.txtIn.Text += info;                      
            }
        }
    }
}

【问题讨论】:

  • port 包含什么样的对象?
  • 我是这样定义端口的:
  • InitializeComponent(); // 浏览所有可用端口的好方法:string[] ports = SerialPort.GetPortNames(); // 将所有端口名称添加到组合框中: foreach (string port in ports) { cmbComSelect.Items.Add(port); }
  • 那不可能是方法中使用的port。该变量仅存在于foreach 的范围内,并且字符串没有任何BytesToRead 属性或Read 方法。
  • 这完全是设计使然,您只能获得接收缓冲区中可用的字节数。通常不超过一两个。您必须更改代码,以便在收到所有数据之前不要开始处理数据。

标签: c# arrays serial-port buffer data-loss


【解决方案1】:

只要接收缓冲区中有可用数据,就会调用 DataReceived 处理程序。因此,在接收到下一个突发数据之前,读取缓冲区中的所有数据,然后处理头部的有效性等。一旦接收到新数据,旧数据就会被覆盖,从而导致数据丢失。 在您的情况下,您在调用 port.Read() 时仅读取 1 个字节。我会将其更改为 port.Read(test, 0, bufferSize);

此外,我只需将数据存储在缓冲区中,并让数据处理在单独的线程上运行。您在处理程序中花费的时间越多,丢失数据的可能性就越大。

【讨论】:

    【解决方案2】:

    问题通过将所有数据存储到缓冲区中得到解决:

    private void port_DataReceived_1(对象发送者,SerialDataReceivedEventArgs e) { 整数字节数; 字节[] 数据 = 新字节[10];

            bytenumber = port.Read(data, 0, 10);
    
            if (data[0] == 0xFF)
            {
            }
        }
    

    等等

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-13
      • 2013-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多