【问题标题】:SerialDataReceived event doesn't fire (SerialPort setup for Arduino Clone)Serial DataReceived 事件未触发(Arduino Clone 的串行端口设置)
【发布时间】:2019-04-13 13:38:37
【问题描述】:

这是我在这里的第一个问题,因为我无法在任何地方找到答案。

我对 WPF 和 C# 并不是特别陌生,但我以前从未使用过 SerialData,而且我确信我遇到了一些基本问题。

设置:

Arduino 克隆(SparkFun Pro Micro)发送“你好!” + 一个数字到 USB 串行端口 (COM5) 每秒一次:

String hello = "hello!";
Serial.println(hello + i);
i++;
delay(1000);

并尝试在 WPF 中接收它,使用一个简单的按钮将数据刷新到 TextBlock (tbData)。

SerialPort sp = null;
String str = null;
int i = 0;

public MainWindow()
{
      InitializeComponent();
      sp = new SerialPort("COM5", 9600);
      sp.DataReceived += new SerialDataReceivedEventHandler(ReceiveData);
      sp.Open();
}


void ReceiveData(object sender, SerialDataReceivedEventArgs e)
{
      str = sp.ReadLine();
}

private void Refresh_Click(object sender, RoutedEventArgs e)
{
      tbData.Text = str;
}

但是什么也没发生,我似乎得到一个空字符串,因为当我按下 Refresh_Click 按钮时 TextBlock 没有显示任何内容。

我可以让它与一个新线程一起工作,但它一直超时,我在此处 (Timeouts in C# serial port) 读到最好的(并且看起来最简单的)方法是使用 SerialDataReceived 事件。

t = new Thread(() =>
{
      int i = 0;
      while (run)
      {
            SerialString = sp.ReadLine();
            Thread.Sleep(1000);
      }

      sp.Close();

});

我缺少的一定是改变缓冲区大小的东西吗?还是类似的?

【问题讨论】:

  • 为什么需要睡觉?您正在调用阻塞的 ReadLine 并且睡眠除了延迟结果之外什么都不做。在第一种方法中,程序正在终止,因为您没有阻塞。将 Console.ReadLine() 添加到程序末尾以阻止 after(sp.Open();)
  • 程序没有终止,它只是没有在我发送字符串的文本块中显示任何内容,它是一个 WPF 应用程序。我似乎正在读取一个空字符串并将其发送到文本块。在线程方法中,我只是认为我不需要比将信息发送到端口更频繁地读取信息。如果我删除 Sleep(1000),端口仍然超时。
  • 是否调用了 ReceiveData?你可以用断点检查。如果正在调用它,问题可能是 ReceiveData 事件在与主线程不同的线程上运行,因此在 SerialPort 读取线程上写入 str 可能不会更新在主线程上读取的值。您应该将 str 的读/写放在一个锁定块中或使用 BeginInvoke 来更新 str。关于超时,您是否尝试过更改 SerialPort.ReadTimeout?
  • 这似乎与 arduino 如何建立通信有关(阅读下面的答案)。现在它报告了您正在描述的问题,在另一个线程中更新文本块,所以我想我会尝试 beginInvoke !谢谢:)

标签: c# wpf events arduino serial-port


【解决方案1】:

看来我找到了答案!

我对串行通信一无所知,但今天我遇到了 MODE cmd 功能:

C:\Users\Username>mode

Status for device COM5:
-----------------------
    Baud:            9600
    Parity:          None
    Data Bits:       8
    Stop Bits:       1
    Timeout:         ON
    XON/XOFF:        OFF
    CTS handshaking: OFF
    DSR handshaking: OFF
    DSR sensitivity: OFF
    DTR circuit:     OFF
    RTS circuit:     OFF

而且我注意到,每当我让 Arduino IDE 向我报告数据时,它都会发生变化——它总是会成功! - 每当我试图让 WPF 做同样的事情时。 以上是我尝试运行自己的代码后的 MODE 返回,并且:

Status for device COM5:
-----------------------
    Baud:            9600
    Parity:          None
    Data Bits:       8
    Stop Bits:       1
    Timeout:         OFF
    XON/XOFF:        OFF
    CTS handshaking: OFF
    DSR handshaking: OFF
    DSR sensitivity: OFF
    DTR circuit:     ON
    RTS circuit:     ON

这是在Arduino IDE中打开Tools>Serial monitor后显示的,然后立即再次关闭。

我将 WPF 代码更改为:

sp = new SerialPort("COM5", 9600);
sp.Open();

到:

sp = new SerialPort("COM5", 9600);
//sp.ReadTimeout = 200;
sp.DtrEnable = true;
sp.RtsEnable = true;
sp.DataBits = 8;
sp.StopBits = StopBits.One;
sp.Open();

现在线程示例和 SerialDataReceived 事件都运行顺利(好吧,除了我无法在 SerialDataReceived 线程中更新 UI 线程)。

我希望有人觉得这很有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多