c# - Serial port write究竟是如何从缓冲区写入数据的呢?

标签 c# c++ .net winforms arduino

因此,我正在使用 Visual Studios Windows 窗体创建 GUI,以便将数据发送到 Arduino。我一直在测试如何在 Arduino 端接收数据,但我似乎找不到关于如何发送数据的解释。我一直在使用 port.Write() 发送缓冲区。

port.Write Information from the Microsoft page

Arduino 串行监视器读取 ASCII 字符,但由于我使用 GUI 与 Arduino 通信,所以我不确定数据是如何传输的。在 Arduino 串行监视器中,我输入数据并按下回车键。这意味着如果我输入所有数据并按回车键,它会将所有数据读取为 1 个字节。通过单独输入数据,然后输入它是一个正在读取的字节并由换行符终止。

  1. 数据传输的具体方式是什么?从 MS 页面上说它“使用缓冲区中的数据将指定数量的字节写入串行端口”,我假设它同时发送所有字节而不是单独发送。

    即如果我将数据发送为 port.Write(new byte[] { b0, b1, b2, b3, b4, b5, b6, b7}, 0, 8); 是吗基本上一次发送所有 8 个字节,或者它是单独发送每个元素,如果是的话,字节之间的终止是什么?我假设它是第一个,因为它要求写入(计数)字节数,因此它从数组发送 8 个字节。

  2. 传输期间字节之间终止的是什么?逗号分隔数组数据,但在传输中,它甚至发送逗号终止还是只是一个数据流?

    即。在代码运行的串行监视器中,我分别输入每个字节,然后是换行符。 Arduino 然后读取字节,直到遇到换行符

  3. 在使用 C++ 的 Arduino 上,您可以使用 Serial.print 或 Serial.println 让它自动应用一个新行。在 MS 页面上,WriteLine 方法仅写入一个字符串并且没有任何重载,所以我认为这意味着无法在此命令中使用字节?

  4. 如果我尝试使用 for 循环打印单个数组,它说无法从 byte 转换为 char[]。为什么我把它定义为一个字节数组,却说它是一个字符数组? 我之前使用//port.Write(sendbyte, 0, 8); 发送整个数组并获取一些数据。

从 Windows 窗体 GUI 发送的代码:

//bytes declared and data stored earlier
byte[] sendbyte = new byte[] { b1, b2, b3, b4, b5, b6, b7, b8};
            
port = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
port.Open();
//port.Write(sendbyte, 0, 8);

port.Write(new byte[] { b1, b2, b3, b4, b5, b6, b7, b8}, 0, 8);
/*for( int x = 0; x <=7; x ++)
{
    port.Write( sendbyte[x], 0, 1);
} 
*/
port.Close();

读取传入字节的代码

void recvBytesWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    byte startMarker = 42;
    byte endMarker = 24;
    byte rb;
    byte comp;

    while (Serial.available() > 0 && newData == false) 
    {
        rb = Serial.read();
        if (recvInProgress == true) 
        {
            if (rb != endMarker)
            {
                receivedBytes[ndx] = rb;
                ndx++;
                if (ndx >= numBytes) 
                {
                    ndx = numBytes - 1;
                }
            }
            else 
            {
                receivedBytes[ndx] = ','; // terminate the string
                recvInProgress = false;
                numReceived = ndx;  // save the number for use when printing
                ndx = 0;
                newData = true;
            }
        }
        else if (rb == startMarker) 
        {
            recvInProgress = true;
        }
    }
}

最佳答案

  1. 串行端口通常有缓冲,但 Microsoft 文档让我相信它会将整个缓冲区一次性全部写入线路,因为它可能会引发超时异常。但是,如果您一次从窗口写入 1000 个字节,则不能保证在 arduino 上的每个循环中读取相同数量的字节。

  2. 各个字节之间没有分隔符。分隔数组字节的逗号实际上只是您的编程语言的语法,即。它只存在于您的代码文件中。字节始终按顺序排列在内存中。

  3. 除非您将字节数组转换为字符串值,否则不会。 How convert byte array to string

  4. 试试 port.Write( &sendByte[x], 0, 1 );

关于c# - Serial port write究竟是如何从缓冲区写入数据的呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52414408/

相关文章:

c# - Azure 搜索 SDK 创建数据源

c# - 我正忙于编写 C# IBM MQ 客户端应用程序,并不断收到 "Exception: The type initializer for ' IBM.WMQ.Nmqi.UnmanagedNmqiMQ' 抛出异常。”

c# - 即使在 try catch 之后继续执行程序

c++ - opencv 使用 cvFindStereoCorrespondenceBM 给出异常

c++ - 更改变量值时,使用 int x = 100 有什么区别;对 x = x + 100;

.net - 使用IOC将POCO作为Web服务公开-Spring.net的WebServiceExporter的替代产品?

c# - 检查类字段事件背后生成字段的属性

c++ - 将公共(public)成员函数指针传递给构造函数

c# - 如何打开实际上已关闭的 Wifi 适配器的 radio ?

.net - F#:使用 DU 来限制属性的类型