每x秒运行一次代码,无论循环内执行多长时间 [英] Running code every x seconds, no matter how long execution within loop takes

查看:37
本文介绍了每x秒运行一次代码,无论循环内执行多长时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使LED闪烁到某首歌曲的节拍.这首歌正好是125 bpm.
我编写的代码起初似乎起作用,但是运行时间越长,LED闪烁和下一个节拍开始之间的时间差越大.LED似乎闪烁得太慢了一点.

I'm trying to make an LED blink to the beat of a certain song. The song has exactly 125 bpm.
The code that I wrote seems to work at first, but the longer it runs the bigger the difference in time between the LED flashes and the next beat starts. The LED seems to blink a tiny bit too slow.

我认为发生这种情况是因为lastBlink取决于之前保持同步的眨眼,而不是使用一个静态初始值来同步...

I think that happens because lastBlink is kind of depending on the blink which happened right before that to stay in sync, instead of using one static initial value to sync to...

unsigned int bpm = 125;
int flashDuration = 10;
unsigned int lastBlink = 0;
for(;;) {
    if (getTickCount() >= lastBlink+1000/(bpm/60)) {
        lastBlink = getTickCount();
        printf("Blink!\r\n");
        RS232_SendByte(cport_nr, 4); //LED ON
        delay(flashDuration);
        RS232_SendByte(cport_nr, 0); //LED OFF
    }
}

推荐答案

我认为漂移问题可能是由于您使用相对时间延迟而睡了 for 持续时间而不是在绝对时间之前一直保持睡眠.问题是线程由于调度问题而不能总是精确地按时唤醒.

I think the drift problem may be rooted in your using relative time delays by sleeping for a fixed duration rather than sleeping until an absolute point in time. The problem is threads don't always wake up precisely on time due to scheduling issues.

这种解决方案可能对您有用:

Something like this solution may work for you:

// for readability
using clock = std::chrono::steady_clock;

unsigned int bpm = 125;
int flashDuration = 10;

// time for entire cycle
clock::duration total_wait = std::chrono::milliseconds(1000 * 60 / bpm);

// time for LED off part of cycle
clock::duration off_wait = std::chrono::milliseconds(1000 - flashDuration);

// time for LED on part of cycle
clock::duration on_wait = total_wait - off_wait;

// when is next change ready?
clock::time_point ready = clock::now();

for(;;)
{
    // wait for time to turn light on
    std::this_thread::sleep_until(ready);

    RS232_SendByte(cport_nr, 4); // LED ON

    // reset timer for off
    ready += on_wait;

    // wait for time to turn light off
    std::this_thread::sleep_until(ready);

    RS232_SendByte(cport_nr, 0); // LED OFF

    // reset timer for on
    ready += off_wait;
}

这篇关于每x秒运行一次代码,无论循环内执行多长时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆