C-覆盆子PI,循环延迟功能



这是我的代码:

#include <wiringPi.h>
#include <stdio.h>
#define LED 18
#define IN 24
int main(void)
{
    wiringPiSetupGpio ();
    pinMode (LED, OUTPUT);
    pinMode (IN, INPUT);
    for (;;)
    {
        digitalWrite (LED, 1);
        delay (2000);
        digitalWrite (LED, 0);
        delay (2000);
        if (digitalRead (IN) == 1)
        {
            for (;;)
            {
                digitalWrite (LED, 1);
                delay(500);
                digitalWrite (LED, 0);
                delay(500);
            }
        }    
    }    
    return 0;
}

我使用开关从2000延迟到500延迟。问题在于,当我按开关时,它会等到循环结束直到它变得更快。反之亦然。我需要在代码中的某个地方写一个函数或循环,以使我可以按开关,而无需等待速度较慢/更快的速度。我正在使用接线Pi库和GPIO引脚编号在Raspberry Pi上对此进行编码。

首先,您所显示的代码将从不偏离2000的延迟,仅仅是因为没有办法从初始for(;;)循环退出。那可能是您需要检查和修复的第一个第一


在能够尽早结束延迟方面,您可以做更改之类的事情:

delay (2000);

进入:

for (i = 0; i < 2000; i += 10) {
    delay (10);
    if (digitalRead (IN) == 1)
        break;
}

如果开关发生变化,这基本上会尽早退出延迟,因此您永远不会等于10个时间单元(而不是2000年)。

请注意,可能会有一个开销可以反复调用延迟。换句话说,虽然delay(2000)可能需要非常接近2000个时间单元,但由于每个呼叫的设置时间等等,对delay(10)的两百个电话可能需要更多。


实际上,您可能根本不使用硬编码值可以极大地简化代码。取而代之的是,您可以使用一个最小延迟的单个循环,其中一些内部控件可以解决何时以及如何更改LED(即,不是每个通过循环)。

例如,这样的事情会做到。我没有测试过它,因为我的PI2仍在盒子里等着我玩的时间,但是它应该非常接近:

#include <wiringPi.h>
#include <stdio.h>
#define LED 18
#define IN 24
#define RES 10
int main (void) {
    int cycleTime, ledState, lastSwitch, currSwitch, timeLeft;
    wiringPiSetupGpio ();
    pinMode (LED, OUTPUT);
    pinMode (IN, INPUT);
    cycleTime = 2000;  // Initial cycle time
    ledState = 0;      //   and LED state.
    lastSwitch = 0;    // Previous switch state,
    // Start infinite loop with first cycle time.
    timeLeft = cycleTime;
    for (;;) {
        // Delay for minimal time and adjust time left.
        delay (RES);
        timeLeft = timeLeft - RES;
        // Detect switch change.
        currSwith = digitalRead (IN);
        if (currSwitch != lastSwitch) {
            // If so, store new state, change cycle time
            //   and force IMMEDIATE end of current cycle.
            lastSwitch = currSwitch;
            cycleTime = 2500 - cycleTime;  // switch 500 <-> 2000
            timeLeft = 0;
        }
        // Detect end of cycle.
        if (timeLeft <= 0) {
            // Toggle LED and start new cycle.
            ledState = 1 - ledState;
            digitalWrite (LED, ledState);
            timeLeft = cycleTime;
        }
    }
}

基本上,您有一个循环,但一个循环每十个单元,而不是每500或2000个循环。该计数器取决于当前周期时间。

当开关翻转时,该计数器为零,以使其(几乎)立即更改为下一个周期。

最新更新