我正在开发一个项目,发送串行数据来控制LED灯的动画,这需要与动画引擎保持同步。似乎有一个大的串行写入缓冲区(OSX(POSIX)+ FTDI芯片组usb串行设备),所以如果不手动调节write()的调用,软件可以在灯光前几秒钟。串口:write()限制?
目前我手动将串行写入速度限制为波特率(8N1 = 10字节串行帧每8字节数据,19200bps串行 - > 1920字节每秒最大),但我遇到了动画问题随着时间流逝与灯光不同步 - 它开始很好,但在10分钟后,动画和灯光之间出现明显的(100ms +)延迟。
这是真实限制串行写入速度的代码(每个动画帧调用一次,“经过”是当前帧,“波特率”的持续时间是BPS(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)系统。
任何意见赞赏。
跨缓冲区同步是POSIX通常不适合处理的东西;在所有消费者操作系统上同步音频和视频的早期尝试是多么糟糕的一个很好的例子。您可能需要直接写入串行UART或查找或写入允许准同步ioctl的驱动程序,例如“不会早于时间发出此字节_n_ – msw 2010-05-23 15:07:30
您是否可以控制动画引擎? – 2010-05-23 15:12:09
动画帧率是否固定? – 2010-05-23 16:02:39