【问题标题】:Displaying received data from serial port显示从串口接收到的数据
【发布时间】:2015-07-22 01:56:50
【问题描述】:

我在处理串行数据接收事件处理程序时遇到问题。一半时间数据显示在文本框上,一半时间不显示。应该是跨线程操作的问题。

这是我的 Arduino 代码:

int Loop = 1;

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.println(Loop);
  Loop++;

  delay(1000);
}

这是我的 C# 代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;

namespace arduino_test
{
public partial class Form1 : Form
{
    SerialPort sPort;

    public Form1()
    {
        InitializeComponent();

        initialiseArduino();
    }

    public void initialiseArduino()
    {
        sPort = new SerialPort();
        sPort.BaudRate = 9600;
        sPort.PortName = "COM16";
        sPort.Open();

        //sPort.DataReceived += new SerialDataReceivedEventHandler(sPort_DataReceived);
    }

    void sPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        SerialPort sp = (SerialPort)sender;
        string data = sp.ReadExisting();
        displayMessage(data);
    }

    public void displayMessage(string data)
    {
        if (InvokeRequired)
        {
            this.Invoke(new Action<string>(displayMessage), new object[] { data });
            return;
        }
        textBox1.Text = data;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        while (true)
        {
            string data = sPort.ReadLine();
            textBox1.Text = data;
        }
    }
}
}

当我使用串行数据接收事件处理程序时,即使在调用之后也会出现这个问题。

所以我尝试通过单击一个按钮来运行相同的线程操作,它工作得非常好。

谁能告诉我我做错了什么?

【问题讨论】:

    标签: c# multithreading


    【解决方案1】:

    明显的区别和问题的原因是您执行此操作的两种不同方式。您在 DataReceived 事件处理程序中使用 ReadExisting(),但在 Click 事件处理程序中使用 ReadLine()

    ReadExisting() 只是没有做你希望它做的事情,你只会得到 1 或 2 个字符。无论是“存在”什么,都不会因为 DataReceived 事件快速触发而现代台式计算机非常快。然后事件再次触发,您又读取了 1 或 2 个字符。您的 TextBox 只显示最后出现的内容。

    请改用 ReadLine()。

    【讨论】:

      【解决方案2】:

      您可能想用

      更新 displayMessage 方法
      public void displayMessage(string data)
      {
          if (InvokeRequired)
          {
              this.Invoke(new Action<string>(displayMessage), new object[] { data });
              return;
          }
          **textBox1.Text = textBox1.Text + data;**
      }
      

      通过这种方式,您将永远不会清除 textBox1 的内容,并且您将拥有所有值。

      请考虑(取决于您的数据)您的传入数据可能包含控制字符或其他无法在文本框控件中很好显示的内容。

      【讨论】:

      • 好的!感谢您的提示:-)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多