我正在開發一個項目,發送串行數據來控制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