为什么我的 serial.write 发送了两次数据

Why is my serial.write sending data twice

我正在尝试通过创建一个应用程序来模拟微控制器通过串行端口发送数据,该应用程序使用接收例程将字节连续发送到另一个应用程序以用于 GUI 目的。

我正在使用此方法从发送方实例发送我的字节:

Write(vout, 0, 13);

其中 Write 定义为:

public void Write(byte[] buffer, int offset, int count)
{
    // preconditions checks are omitted
    serialPort1.Write(buffer, offset, count);
}

vout 是我从实时模拟传感器的数据手动填充的字节数组。

在 GUI 应用程序中接收数据时,我使用的是:

private void comport_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
      if (!comport.IsOpen) return;
      int bytes = comport.BytesToRead;
      //For loop for getting all values in buffer to 0
      comport.Read(buffer, 0, 13);
      Update_counter();//Updates counter by 1.
}

秒time/any之后我发送了一些东西,它被发送了两次,或者至少这是我的计数器变量所暗示的。

我不确定这是否与实际的串行缓冲区有关,或者我是否使用了不正确的写入和读取方法。

此外,我将 COMPORT 设置为 9600 波特率、8 位、停止位 1、奇偶校验 NONE。

感谢任何帮助。

你的问题的原因是,你读取的字节数超过了现在可用的字节数:

int nrOfAvailableBytes = comport.BytesToRead;
comport.Read(buffer, 0, 13);

所以即使comport告诉你只有一个字节可用,你还是决定读取13个字节。

SerialPort.Read告诉你:

Fewer bytes are read if count is greater than the number of bytes in the input buffer.

解决方案:只读取当前可用的字节。

不要忽略 Read() 返回的值,它 returns 是放入缓冲区的字节数。因此,如果您想读取 13 个字节并且它 returns 少于此,请跟踪计数并读取直到达到所需的字节数。

换句话说,您将不得不实施您的 //For loop 评论:

int totalBytesRead = 0;
int bytesToRead = 13;
do
{
    totalBytesRead += comport.Read(buffer, 0, bytesToRead - totalBytesRead);
} 
while (totalBytesRead < bytesToRead);

通过结合这两个答案,我能够得到一致的结果。我觉得有点多余,但这是最有希望的。

        int n_available_bytes = comport.BytesToRead;

        //Reset buffer array
        for (int i = 0; i < buffer.Length; i++)
        {
            buffer[i] = 0;
        }
        
        //Read, update charts, save to CSV only when the buffer has all the bytes
        if (n_available_bytes == bytesToRead)
        {
            do
            {
            totalBytesRead += comport.Read(buffer, 0, bytesToRead - totalBytesRead);
            }
            while (totalBytesRead < bytesToRead);

            if (totalBytesRead == bytesToRead)
            {
                totalBytesRead = 0;
            }

            HandleSerialData(buffer);

            this.Invoke(new EventHandler(Fill_chart));
      
       }