如何用millis()替换delay()?

时间:2015-08-16 16:09:49

标签: c arduino ide delay

过了一会儿,我得到了我想要的最终结果,但我不能使用延迟,因为我需要不同的时间用于不同的条带,所以我需要在此代码中用delay()替换millis()

#include <FastLED.h>
#define NUM_LEDS1 10
#define NUM_LEDS2 6
#define DATA_PIN1 6
#define DATA_PIN2 7
CRGB leds1[NUM_LEDS1];
CRGB leds2[NUM_LEDS2];

void setup() { 
  FastLED.addLeds<NEOPIXEL, DATA_PIN1>(leds1, NUM_LEDS1);
  FastLED.addLeds<NEOPIXEL, DATA_PIN2>(leds2, NUM_LEDS2);
}

int dot_delay1[ ] = { 100,200,300,400,500,600,700,800,900,1000 };
int dot_delay2[ ] = { 100,200,300,400,500,600 };

void loop() {
  for(int dot = 0; dot < NUM_LEDS1; dot++)
    for(int dot = 0; dot < NUM_LEDS2; dot++) 
    { 
      leds1[dot] = CRGB::Blue;
      leds2[dot] = CRGB::Blue;
      FastLED.show();
      leds1[dot] = CRGB::Black;
      leds2[dot] = CRGB::Black;
      delay( dot_delay1[ dot ] );
      // this is where I need to put the second delay,
      // but I can't put more then 1 delay.
      // I need to refactor my code with millis() function instead of delay()
    }
}

2 个答案:

答案 0 :(得分:0)

您可以使用以特殊频率或时间执行的非阻塞代码模式。在下文中,我将举一个简短示例,说明如何在不阻塞主循环的情况下替换delay(1000)delay(5000)。此外,您可以检查类似帖子的stackoverflow(例如Pause without Delay() arduino)。

   
// 1 sec. frequency
unsigned long interval=1000;    // the time we need to wait
unsigned long previousMillis=0; // millis() returns an unsigned long.

// 5 sec. frequency  
unsigned long interval1=5000;    // the time we need to wait
unsigned long previousMillis1=0; // millis() returns an unsigned long.

void setup() {
   //...
}

void loop() {

 // other CMD's...

 // replace delay(1000) 
 if ((unsigned long)(millis() - previousMillis) >= interval) {
    previousMillis = millis();
    // every first second
    // ... 
 }

 // other CMD's...

 // replace delay(5000) 
 if ((unsigned long)(millis() - previousMillis1) >= interval1) {
    previousMillis1 = millis();
    // every fifth second
    // ... 
 }

 // other CMD's...
}

答案 1 :(得分:0)

我看到你正在使用NeoPixels!碰巧的是,Adafruit有一些很好的教程,可以使用millis()micros()来代替delay()。如果你感到雄心勃勃并且希望完全将你的时间与主要功能分开(如果你有时间和资源,这是一项有价值的工作),它们还包括关于中断的好材料。

第1部分(使用millis()的基础知识):

https://learn.adafruit.com/multi-tasking-the-arduino-part-1/overview

第2部分(介绍中断):

https://learn.adafruit.com/multi-tasking-the-arduino-part-2/overview

第3部分(将所有内容放在一起):

https://learn.adafruit.com/multi-tasking-the-arduino-part-3/overview

编辑1:

好吧,我编辑了你的代码,添加了一个循环,用于检查使用millis()完成的两个延迟时间。我试图坚持你一直在使用的变量命名约定,以便于阅读。我清理了你的代码语法还有一些其他问题。确保有效地评论您的代码,以便为自己和他人理解这些代码!

希望这可以按你想要的方式工作!

/*The goal of the sketch is to run multiple strip where each dot could be 
controlled on/off one after the others but with different times on/off between each
pixel on each strip. All be independent and separate and automated and structured
already like FastLED library recommendation.*/

// Library include
#include <FastLED.h>

#define NUM_LEDS1 10
#define NUM_LEDS2 6

// Define pin (each strip be connected on)
#define DATA_PIN1 5
#define DATA_PIN2 6

// Declare some strip name and attribute (number of led per strip)
CRGB leds1[NUM_LEDS1];
CRGB leds2[NUM_LEDS2];

void setup() {
  FastLED.addLeds<NEOPIXEL, DATA_PIN1>(leds1, NUM_LEDS1);
  FastLED.addLeds<NEOPIXEL, DATA_PIN2>(leds2, NUM_LEDS2);
}

int dot_delay1[] = {100, 200, 300, 400, 500, 600, 700, 800, 900, 1000};
int dot_delay2[] = {100, 200, 300, 400, 500, 600};

void loop() {
  for (int dot1 = 0; dot1 < NUM_LEDS1; dot1++) {
    for (int dot2 = 0; dot2 < NUM_LEDS2; dot2++) {
      // LED turns blue
      leds1[dot1] = CRGB::Blue;
      leds2[dot2] = CRGB::Blue;
      // Show LED status
      FastLED.show();
      // LED turns black
      leds1[dot1] = CRGB::Black;
      leds2[dot2] = CRGB::Black;
      // Create timing variables
      unsigned long previousMillis = millis();
      unsigned long currentMillis = millis();
      // Create boolean variables to monitor if the delays have triggered yet
      bool delayFlag1 = false, delayFlag2 = false;
      // Loop continuously
      while (1) {
        currentMillis = millis();
        // If the first delay time has passed, delayFlag1 is true
        if ((unsigned long)(millis() - previousMillis) >= dot_delay1[dot1]) {
          delayFlag1 = true;
        }
        // If the second delay time has passed, delayFlag2 is true
        if ((unsigned long)(millis() - previousMillis) >= dot_delay2[dot2]) {
          delayFlag2 = true;
        }
        // If both delay times have passed (both delay flags are true), exit while loop
        if ((delayFlag1 && delayFlag2) == true) {
          break;
        }
      }
    }
  }
}

这个新代码应该可以运行,我已经对它进行了测试,它在我的机器上按预期工作。

作为附注,你原来的问题是&#34;我如何用millis()代替delay()?&#34;。这个问题已经由我自己和前一个答案作者user3704293回答。将来,将问题分开以获得更高质量的答案并更好地为那些正在寻找相同问题答案的人提供服务可能会有所帮助。一旦您的问题得到解答,我希望现在就提出这个问题,您应该接受最适合您的答案。

让我知道这一切是否成功!

编辑2:

要让LED彼此独立更改,请将上一代码中的loop()功能替换为此功能。

void loop() {
  // Create timing variable
  unsigned long previousMillis = millis();
  // Loop through all LEDs
  for (int dot = 0; dot < NUM_LEDS1; dot++) {
    // If the first delay time has passed, change first LED strip
    if ((unsigned long)(millis() - previousMillis) >= dot_delay1[dot1]) {
      leds1[dot - 1] = CRGB::Black;
      leds1[dot] = CRGB::Blue;
    }
    // If the second delay time has passed, change second LED strip
    if ((unsigned long)(millis() - previousMillis) >= dot_delay2[dot2]) {
      leds2[dot - 1] = CRGB::Black;
      leds2[dot] = CRGB::Blue;
    }
    // Show LEDs
    FastLED.show();
  }
  // Turn last LED Black
  leds1[9] = CRGB::Black;
}