如何制作一个可以在 void 循环内每隔一定时间间隔执行的函数?

问题描述 投票:0回答:2

我想创建一个类似 void 循环的函数,其中该函数可以在一定的时间间隔内执行另一个代码。

unsigned long NOW;

void setup() {
}

void loop() {
  
  void doEvery(2){ //do Every 2 second
    //Put Code that Execute every 2 second
  }

  void doEvery(4){ //do Every 4 second
    //Put Code that Execute every 4 second
  }

}

如何声明/定义函数 doEvery? 我认为该函数必须包含这个:

if(millis()-NOW>=EVERY){
NOW=millis();
//THE LINE CODE
}
c++ arduino
2个回答
3
投票

THIS为最初的想法:

unsigned long previousMillis2 = 0, previousMillis100 = 0;

void setup() {
}

void loop() {
  unsigned long currentMillis = millis();

  //doEvery 2
  if (currentMillis - previousMillis2 >= 2) {
    previousMillis2 = currentMillis; //stores last execution's timestamp
    //CODE EVERY 2  millis
  }

  //doEvery 100
  if (currentMillis - previousMillis100 >= 100) {
    previousMillis100 = currentMillis; //stores last execution's timestamp
    //CODE EVERY 100  millis
  }
}

这样,您将使用 millis() 来询问自 Arduino 初始化以来经过了多少毫秒。然后,您存储上次执行代码的时间并比较自上次执行以来经过的时间。 它不是用于定义新间隔的动态函数,但如果您只需要一对,则可以轻松编写代码。

编辑:

如果您需要更动态的东西,您应该使用匿名函数。 查看这个这个这里的重点是函数作为参数


1
投票

我已经用它为 WS2812 ledstrip 制作了一个动画库:

https://github.com/laurijssen/ledstripanimator/blob/master/ledanim.c

jabujavi 描述的计时内容发生在 UpdateFrame 函数中,其中列表中的每个动画在配置的毫秒后前进到下一帧。

class AnimList
{
  Animation *first = NULL;
  Adafruit_NeoPixel strip;

public:
  AnimList(int nleds) : strip(nleds, 9, NEO_GRB + NEO_KHZ800)
  {
    strip.begin();
  }

  void UpdateFrame()
  {
    strip.clear();
    
    Animation **anim = &first;

    while (*anim)
    {
      if (millis() - (*anim)->last >= (*anim)->ms)
      {
        if (!(*anim)->UpdateFrame(strip))
        {
          *anim = (*anim)->next;
        }
        else
        {
          (*anim)->last = millis();
          anim = &(*anim)->next;
        }
      }
    }
  }
};

现在你只需在loop()内尽可能快地调用AnimList::UpdateFrame

void loop() {   
  list->UpdateFrame();
  list->Render();

  if (!list->Find(&r1))
  {
    r1 = Rain (rand() % NUMLEDS, rand() % NUMLEDS, {BRIGHTNESS, 0, 15 }) ;
    list->AddFirst(&r1);
  } 
}

编辑

因此,如果您想每 2 秒执行一次代码,您可以创建一个继承自 Animation 的类并覆盖 Updateframe。然后将 ms 变量放在您想要在帧之间传递的时间处。 当然,如果您只想要一个基于任务的库,请删除所有 Adafruit 和动画引用。

class TaskA : public Task
{
public:
  TaskA() { ms = 2000; }

  bool UpdateFrame()
  {    
    Serial.println("2 seconds passed");
    
    return true;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
  }
  
};

TaskA t;

void setup()
{
  list->AddTask(&t);
}

void loop()
{
  list->UpdateTasks();
}
© www.soinside.com 2019 - 2024. All rights reserved.