首页 > 解决方案 > 串行端口写入实际上如何从缓冲区写入数据?

问题描述

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

port.Write 来自 Microsoft 页面的信息

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

  1. 数据究竟是如何传输的?从 MS 页面开始,因为它说它“使用缓冲区中的数据将指定数量的字节写入串行端口”,我假设它同时发送所有字节,而不是单独发送。

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

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

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

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

  4. 如果我尝试使用 for 循环来打印单个数组,它会说 cannot convert from byteto 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;
        }
    }
}

标签: c#c++.netwinformsarduino

解决方案


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

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

  3. 除非您将字节数组转换为字符串值。如何将字节数组转换为字符串

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


推荐阅读