首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >串行: write()节流?

串行: write()节流?
EN

Stack Overflow用户
提问于 2010-05-23 22:26:25
回答 5查看 1.6K关注 0票数 6

我正在做一个发送串行数据的项目来控制LED灯的动画,这需要与动画引擎保持同步。似乎有一个很大的串行写入缓冲区(OSX (POSIX) + FTDI芯片组usb串行设备),因此无需手动限制对write()的调用,软件就可以提前几秒钟。

目前我手动将串行写入速度限制在波特率(8N1 =每8字节数据10字节串行帧,最大19200 bps串行-> 1920字节每秒),但我遇到了动画随时间漂移与灯光不同步的问题-它开始很好,但10分钟后动画和灯光之间存在明显的(100ms+)延迟。

这是限制串行写入速度的代码(每个动画帧调用一次,'elapsed‘是当前帧的持续时间,'baudrate’是bps (19200)):

代码语言:javascript
复制
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)系统上做到这一点。

任何建议都很感谢。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-05-24 08:33:49

如果你想放慢你的动画速度以匹配你可以写入LED的最大速度,你可以只使用tcdrain();类似这样:

代码语言:javascript
复制
while (1)
{
    write(serial_fd, led_command);
    animate_frame();
    tcdrain(serial_fd);
}
票数 3
EN

Stack Overflow用户

发布于 2010-05-23 22:47:22

您可以使用硬件流控制。

我不知道串行链路的另一端有什么硬件,但展台两端可以通过RTS/CTS握手线路进行同步和节流。

毕竟,这就是他们的目的。

票数 2
EN

Stack Overflow用户

发布于 2010-05-24 00:20:29

必须将数据输入到串行热敏条形图记录器一次(非常类似于收据打印机),并有相同类型的问题。数据中的任何延迟都会导致打印输出中的跳转,这是不可接受的。

解决方案非常简单:如果您始终将数据保存在内核串行缓冲区中,则输出将精确到每秒(波特率/ (1 +数据位+停止位))个字符。所以只需添加足够的NUL字节填充来分隔数据即可。

我想,如果一些设备在数据中看到NUL字节,那么它们可能会做非常糟糕的事情,在这种情况下,这将不起作用。但许多人只是忽略了消息之间的额外NUL字节,这让你可以在串口内部使用非常精确的硬件计时器来控制计时。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2892096

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档