为什么从串行端口上限读取一定数量的字节数?

时间:2019-04-09 18:48:36

标签: c++ winapi serial-port

我正在从串行端口读取250Hz的串行数据。 (如果相关,我正在使用USB串行适配器)。每个样本为26个字节(制表符分隔的列和行以换行符终止)。我使用的波特率为115200。我一直在尝试读取最大缓冲区长度,在大多数情况下,最终得到3968(约153个样本) )一次。我已经打印出样本以确认样本没有掉落。我不明白为什么它总是每次读取约153个样本。理想情况下,我希望经常读取较少的样本:一次读取10个样本,这样可以使我获得更快的刷新率并读取更多的“实时”数据。

到目前为止,我尝试减小最大缓冲区长度,这增加了读取端口的延迟,因为即使在停止发送数据后,我仍会获取数据。 以下问题似乎相关,但我不明白为什么这是“非问题”。 Stange Behavior of the Serial Port Input Buffer

#define MAX_DATA_LENGTH 11520

SerialPort::SerialPort(char *portName)
{
...
            dcbSerialParameters.BaudRate = CBR_115200;
            dcbSerialParameters.ByteSize = 8;
            dcbSerialParameters.StopBits = ONESTOPBIT;
            dcbSerialParameters.Parity = NOPARITY;
            dcbSerialParameters.fDtrControl = DTR_CONTROL_ENABLE;
...

}


int SerialPort::readSerialPort(char *buffer, unsigned int buf_size)
{
    DWORD bytesRead;
    unsigned int toRead;

    ClearCommError(this->handler, &this->errors, &this->status);

    if (this->status.cbInQue > 0){
        if (this->status.cbInQue > buf_size){
            toRead = buf_size;
        }
        else toRead = this->status.cbInQue;
    }

    if (ReadFile(this->handler, buffer, toRead, &bytesRead, NULL)) return bytesRead;

    return 0;
}

int main()
{
  SerialPort arduino(port_name);

  std::string temp_buffer;
  std::string msg;

  while (arduino.isConnected()){

    memset(&incomingData[0], 0, sizeof(incomingData));

    //Check if data has been read or not
    int read_result = arduino.readSerialPort(incomingData, MAX_DATA_LENGTH);

    //prints out data
    if(read_result > 0){

        cout << "Bytes read = " << read_result << endl;
        std::string inData(incomingData);
        inData = temp_buffer + inData;

        int end_idx = inData.rfind('\n');
        if(end_idx > 0){
            msg = inData.substr(0, end_idx+1);
            temp_buffer = inData.substr(end_idx);
        }
        else{
            msg = inData;
        }
    }
    //wait a bit
    Sleep(1);
  }
}

当我将最大缓冲区长度设置为高时,我注意到我正在获取所有样本,在发送侧生成数据和读取端口之间的延迟最小。当我降低该延迟时,延迟会不断增加。

编辑:我打印了cbInQue,结果发现它大部分为零,一次获取3968个字节。因此,没有连续的字节流进来,而是一次一批采样。这仅仅是串行设备的属性,还是我可以做些什么?当我读腻子时,它也不是连续的,好像数据每隔几毫秒就更新一次。

编辑:我从设备管理器更改了COM端口的延迟计时器值。默认值为16ms,我将其更改为2ms,现在我正在清空cbInQue缓冲区,它不会等到3968个字节为止。阅读肯定变得更快。由于我的缓冲区大小限制为500,所以每次都读取所有cbInQue。

0 个答案:

没有答案