我想创建一个类似 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
}
以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 初始化以来经过了多少毫秒。然后,您存储上次执行代码的时间并比较自上次执行以来经过的时间。 它不是用于定义新间隔的动态函数,但如果您只需要一对,则可以轻松编写代码。
编辑:
我已经用它为 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();
}