【问题标题】:How do I receive serial packet from Arduino using C#?如何使用 C# 从 Arduino 接收串行数据包?
【发布时间】:2019-08-14 19:30:53
【问题描述】:

在某些情况下,我正在尝试创建自己的高扭矩伺服。

我创建了一个 Arduino 草图,它使用 2 个中断引脚跟踪 2 相旋转编码器的位置。它还使用 2 个额外的中断引脚跟踪 2 个限位开关的状态。

这一切正常,我可以在 Arduino 串行监视器中看到返回的数据(我正在使用 VSCode 来实际编写代码,但就串行监视器而言,它与 Arduino IDE 的工作方式相同。)

但是,我在编写针对 Windows x64 的 C# 控制台应用程序来接收我在 Arduino 草图中创建的串行数据包时遇到了问题。

我设置了断点并添加了 Console.WriteLines,但它们从未被命中。我在网上进行了大量搜索并尝试了几个不同的代码示例,但无济于事。感觉就像我做的一切都是正确的。过去我使用 .Net 框架完成了大量串行编程,所以我了解串行协议和使用 SerialPort 类的方法。不过,那是不久前(几年)的事了。

这是我的 C# 控制台应用程序代码:

using System;
using System.IO.Ports;

namespace ArduinoSerialTest
{
  class Program
  {

    public const byte PacketStart = 1;
    public const byte PacketEnd = 4;
    public const byte PacketSize = 5;

    static void Main(string[] args)
    {

      bool isStopping = false;

      SerialPort serialPort = new SerialPort();
      serialPort.PortName = "COM3";
      serialPort.BaudRate = 9600;
      serialPort.ReadTimeout = 500;

      serialPort.Open();

      try
      {
        while (!isStopping)
        {
          try
          {
            int startByte = serialPort.ReadByte();
            if (startByte == PacketStart)
            {
              byte[] positionState = new byte[] { (byte)serialPort.ReadByte(), (byte)serialPort.ReadByte() };
              byte limitSwitchState = (byte)serialPort.ReadByte();
              byte packetEnd = (byte)serialPort.ReadByte();

              // simple verification before we process the data
              if (packetEnd != PacketEnd)
              {
                throw new Exception("Invalid packet received.");
              }

              short position = BitConverter.ToInt16(positionState, 0);

              Console.WriteLine("Position: {0}", position); // TODO: Remove me
            }
          }
          catch (TimeoutException) { }
          catch (System.IO.IOException) { }
        }

      }
      finally
      {
        serialPort.Close();
      }

    }

  }
}

这是我的 Arduino 草图的适用部分:

void reportStatus() {
    Serial.write((byte)1); // SOH
    // position split into 2 bytes
    Serial.write((byte)lowByte(encoderAccumulator));
    Serial.write((byte)highByte(encoderAccumulator));
    // limit switches
    Serial.write((byte)limitSwitchState);
    Serial.write((byte)4); // EOT
}

它似乎从来没有收到过数据包;或任何与此有关的事情。我觉得有一些明显的东西我忽略了,但我不能指望它。

至于 try/catch,我在 VSCode 的调试器输出控制台中看到了超时异常。我有时也会看到 IOException,但只有当我使用 Ctrl+C 强制停止应用程序时。我在没有 IOException 捕获的情况下进行了尝试,但这也没有显示任何内容。

【问题讨论】:

  • P.S.我尝试使用 Visual Studio 2017 Community、相同的代码和 .Net framework 4.7.1,但仍然得到相同的结果。

标签: c# .net arduino serial-port


【解决方案1】:

尝试 SerialPort.ReadExisiting()。

【讨论】:

  • 返回一个字符串。我需要二进制数据(字节)。
  • 请问您为什么推荐这个?
  • 这是一个不必要的步骤,会影响性能。我不应该首先将字符串转换回不必要地转换为字符串的字节。
  • 你有一台运行 C# 的计算机,它会因为将字符串转换为字节而变慢。没有冒犯,但那是一些蹩脚的电脑。解析变量是计算机中的常见过程
【解决方案2】:

我知道出了什么问题。 Arduino 使用 DTR 信号来启动通信。我所要做的就是在打开串口之前设置SerialPort.DtrEnable = true,它就可以工作了。我知道这很简单!耶!

【讨论】:

    猜你喜欢
    • 2020-03-19
    • 2016-07-26
    • 2016-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多