FastLED КАЖДЫЕ N_SECONDS — генерирует ли статический код?

led-strip

Я понимаю, что мой вопрос неточен, поэтому у меня есть простой надуманный пример, чтобы лучше проиллюстрировать то, о чем я спрашиваю.

Я пытаюсь использовать EVERY_N_SECONDS внутри функции-члена класса, который вызывается в методе loop() скетча. И это прекрасно работает, но когда у меня есть два экземпляра класса, у каждого есть своя функция-член, вызываемая в цикле (), но один экземпляр, кажется, «выигрывает»; а другой экземпляр никогда не попадает внутрь блока КАЖДЫЕ_N_SECONDS.

Например, следующий код создает этот вывод (я ожидал, что и a2, и a1 появятся в "a2 находится в цикле КАЖДЫЕ_N_SECONDS"):

a1 is in the loop
a1 is in the EVERY_N_SECONDS loop
a2 is in the loop
a1 is in the loop
a1 is in the EVERY_N_SECONDS loop
a2 is in the loop
a1 is in the loop
a1 is in the EVERY_N_SECONDS loop
a2 is in the loop

Вот код, маленькая глупая программа, иллюстрирующая вопрос:

#include <Streaming.h>
#include <FastLED.h>

class A {
public:
 String tag;
 void loop() 
 { 
   Serial << tag << " is in the loop" << endl;
   EVERY_N_SECONDS(2) {
      Serial << tag << " is in the EVERY_N_SECONDS loop" << endl;
   }
 }
};

A a1, a2;

void setup() {
  Serial.begin(9600);
  a1.tag = "a1";
  a2.tag = "a2";
}

void loop() {  
  a1.loop();
  a2.loop();
  FastLED.delay(5000);
}

, 👍1

Обсуждение

Глядя на [его определение] (https://github.com/FastLED/FastLED/blob/5eaea812de970393bee4dcd17f9e4d17bf7a9f37/src/lib8tion.h#L1387) и строку ниже, он кажется статичным. Хотя я не совсем понимаю, что они там делают, @chrisl


1 ответ


1

Предположим, что ссылка chrisl указывает на соответствующий источник.. .

Ваш исходный код:

    EVERY_N_SECONDS(2) {
        Serial << tag << " is in the EVERY_N_SECONDS loop" << endl;
    }

расширяется до (разбивка строки для удобства чтения):

    static CEveryNSeconds PER__COUNTER__(2);
    if( PER__COUNTER__ ) {
        Serial << tag << " is in the EVERY_N_SECONDS loop" << endl;
    }

Так что да, экземпляр, управляющий условным оператором, является static.

Это определение CEveryNSeconds. :

template<typename timeType,timeType (*timeGetter)()>
class CEveryNTimePeriods {
public:
    timeType mPrevTrigger;
    timeType mPeriod;
    CEveryNTimePeriods() { reset(); mPeriod = 1; };
    CEveryNTimePeriods(timeType period) { reset(); setPeriod(period); };
    void setPeriod( timeType period) { mPeriod = period; };
    timeType getTime() { return (timeType)(timeGetter()); };
    timeType getPeriod() { return mPeriod; };
    timeType getElapsed() { return getTime() - mPrevTrigger; }
    timeType getRemaining() { return mPeriod - getElapsed(); }
    timeType getLastTriggerTime() { return mPrevTrigger; }
    bool ready() {
        bool isReady = (getElapsed() >= mPeriod);
        if( isReady ) { reset(); }
        return isReady;
    }
    void reset() { mPrevTrigger = getTime(); };
    void trigger() { mPrevTrigger = getTime() - mPeriod; };
    operator bool() { return ready(); }
};
typedef CEveryNTimePeriods<uint16_t,seconds16> CEveryNSeconds;

Его оператор bool() возвращает один раз значение true, если период истек. Первый экземпляр вашего A получает это true, но никогда не получает второй экземпляр.

Это соответствующие методы, отсортированные и отформатированные для лучшего понимания:

    operator bool() {
        return ready();
    }

    bool ready() {
        bool isReady = (getElapsed() >= mPeriod);
        if ( isReady ) {
            reset();
        }
        return isReady;
    }

    timeType getElapsed() {
        return getTime() - mPrevTrigger;
    }

    void reset() {
        mPrevTrigger = getTime();
    }
,