Я работаю над проектом, отправляющим последовательные данные для управления анимацией светодиодов, которые должны синхронизироваться с движком анимации. Похоже, существует большой буфер последовательной записи (последовательное USB-устройство с набором микросхем OSX (POSIX) + FTDI), поэтому без ручного регулирования вызовов write () программа может опередить свет на несколько секунд.
В настоящее время я вручную ограничиваю скорость последовательной записи скоростью передачи данных (8N1 = 10 байт последовательного кадра на 8 байт данных, 19200 бит / с последовательного -> 1920 байт в секунду макс), но у меня проблема с дрейфом анимации со временем не синхронизируется со светом - все запускается нормально, но через 10 минут между анимацией и светом заметно (100 мс +) лаг.
Это код, который ограничивает скорость последовательной записи (вызывается один раз для кадра анимации, «истекший» - длительность текущего кадра, «скорость передачи» - бит / с (19200)):
void BufferedSerial::update( float elapsed )
{
baud_timer += elapsed;
if ( bytes_written > 1024 )
{
// maintain baudrate
float time_should_have_taken = (float(bytes_written)*10)/float(baudrate);
float time_actually_took = baud_timer;
// sleep if we have > 20ms lag between serial transmit and our write calls
if ( time_should_have_taken-time_actually_took > 0.02f )
{
float sleep_time = time_should_have_taken - time_actually_took;
int sleep_time_us = sleep_time*1000.0f*1000.0f;
//printf("BufferedSerial::update sleeping %i ms\n", sleep_time_us/1000 );
delayUs( sleep_time_us );
// subtract 128 bytes
bytes_written -= 128;
// subtract the time it should have taken to write 128 bytes
baud_timer -= (float(128)*10)/float(baudrate);
}
}
}
Очевидно, что где-то что-то не так.
Гораздо лучшим подходом было бы определение количества байтов, находящихся в настоящее время в очереди на передачу, и попытка сохранить это значение ниже фиксированного порогового значения, но я не могу понять, как это сделать в OSX (POSIX). ) система.
Любой совет приветствуется.