我正在从串行端口读取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。