Я пытаюсь считывать данные и метки времени с устройства с последовательным интерфейсом под WinXP 32. Я использую boost :: asio для моего последовательного получения, но столкнулся с некоторыми ограничениями.Если я попытаюсь прочитать и пометить меткой времени каждое 2-байтовое измерение диапазона, сказав asynch_read_some использовать 2-байтовый буфер, я получу огромную задержку при измерениях диапазона.
Чтобы обойти это, мой план заключался в использовании большого(5 kb) буферов, отметка времени, время, когда я получаю каждый буфер и выгружаю буфер, отметку времени и некоторые другие вещи (размер, заголовок, нижний колонтитул и т. Д.) В файл.Мне нужны эти временные метки, так как я должен синхронизировать данные датчика с данными с другого устройства на одном ПК.Процесс регистрации для этого устройства также применяет временные метки почти таким же образом, и я собираюсь подключить все это в автономном режиме после того, как я взял свои журналы.
Эта функция вызывается непосредственно из моего boost :: asioпоследовательный обратный вызов RX, как только данные получены, и передан указатель на буфер и количество полученных байтов.
void AR2500CallbackFunction(char * RXBuff, unsigned int bytesRcvd)
{
boost::posix_time::ptime nowPTime( boost::posix_time::microsec_clock::local_time() );
uint64_t pktTimestamp( nowPTime.time_of_day().total_microseconds() );
// Log Packet Header - PacketStartSentinel
m_logFileStream.write((char *)PacketStartSentinel, sizeof(PacketStartSentinel));
// Log Packet ID - m_packetCounter
m_logFileStream.write((char *)&m_packetCounter, sizeof(m_packetCounter));
// Add number of bytes recieved - bytesRcvd
m_logFileStream.write((char *)&bytesRcvd, sizeof(bytesRcvd));
// Log Data - RXBuff
m_logFileStream.write(RXBuff, bytesRcvd);
// Add Timestamp - pktTimestamp
m_logFileStream.write((char *)&pktTimestamp, sizeof(pktTimestamp));
// Add End Sentinel - PacketEndSentinel
m_logFileStream.write((char *)PacketEndSentinel, sizeof(PacketEndSentinel));
m_packetCounter++;
}
Поскольку мои данные поступают в виде постоянного потока через последовательный порт, я затемсделать то, что кажется разумным предположением.Я предполагаю, что отметка времени, которую я записываю с каждым пакетом, является повторяемой (но не обязательно точной, будет некоторая приблизительно постоянная задержка, прежде чем обратный вызов будет фактически выполнен), измерения времени, в которое я получил последнюю выборку в пакете.На этапе постобработки я беру метку времени из предыдущего пакета, метку времени текущего пакета и линейно интерполирую, чтобы оценить метку времени каждой из выборок в текущем пакете.
Что япосле постобработки обнаружилось, что даже для чрезвычайно низких скоростей передачи данных, когда для каждого обратного вызова есть только 1 или 2 показания диапазона, я получаю крайне нестабильную временную метку.Некоторые пакеты помечаются как имеющие одинаковое время, некоторые последовательные пакеты помечаются как имеющие невероятно большие промежутки.Когда я устанавливаю частоту дискретизации датчика равной 10 Гц, я по-прежнему получаю некоторые различия в метках времени между выборками по 125 миллисекунд, а некоторые - до 80 миллисекунд.Если я увеличу частоту дискретизации (датчик может возвращать показания 2-байтового диапазона на частоте до 30 кГц по каналу RS232 со скоростью 921600 бод), я обнаружу, что нестабильность становится еще хуже.Используя осциллограф на последовательных линиях, я знаю, что датчик фактически выплевывает данные с заданной скоростью, поэтому недостаток должен быть где-то на стороне программного обеспечения.
Есть ли что-то, что я делаю неправильно, серьезный недостаток в одном из моих предположений, или мне просто придется делать все это в Linux вместо того, чтобы получать точные метки времени?Я бы действительно предпочел избежать этого последнего варианта, поскольку, хотя мой последовательный код кроссплатформенный, код моего другого устройства было бы трудно сделать переносимым.