Передача параметров функции в параметры указателя функции класса - PullRequest
0 голосов
/ 07 января 2019

Попытка создать класс в Arduino, который легко справится с задержкой в ​​миллисекундах. Моя идея состоит в том, чтобы создать класс, в котором вы можете передать функцию, которую хотите запустить, и время для задержки. Вызов метода run проверяет, прошло ли время задержки, и может ли он запустить функцию.

MillisTimer MT_measureAndWrite(measureAndWrite, 1000);

measureAndWrite функция имеет void тип возвращаемого значения и нулевые параметры. Я был в состоянии сделать это. Это было нормально.

Однако я столкнулся с проблемой, когда хочу использовать функцию с параметрами. Я пытался использовать шаблон класса, но не повезло

MillisTimer<float, float, float, float> MT_LCDrefresh(LCDrefresh(1.5,2.5,3.5,4,5), 500);


template <class A = void, class B = void, class C = void, class D = void>
class MillisTimer
{
private:

    void(*mFunc0)(A,B,C,D);
    const uint16_t mDelayTime;
    unsigned long mPreviousTime;
    const bool mDebugMode;

public:
    MillisTimer(void(*func)(), uint16_t delayTime, bool debugMode = false) : mDelayTime(delayTime), mDebugMode(debugMode)
    {
        mFunc0 = func;
        mPreviousTime = millis();
    }
    MillisTimer(void(*func)(A), uint16_t delayTime, bool debugMode = false) : mDelayTime(delayTime), mDebugMode(debugMode)
    {
        mFunc0 = func;
        mPreviousTime = millis();
    }
    MillisTimer(void(*func)(A, B), uint16_t delayTime, bool debugMode = false) : mDelayTime(delayTime), mDebugMode(debugMode)
    {
        mFunc0 = func;
        mPreviousTime = millis();
    }
    MillisTimer(void(*func)(A, B, C), uint16_t delayTime, bool debugMode = false) : mDelayTime(delayTime), mDebugMode(debugMode)
    {
        mFunc0 = func;
        mPreviousTime = millis();
    }
    MillisTimer(void(*func)(A, B, C, D), uint16_t delayTime, bool debugMode = false) : mDelayTime(delayTime), mDebugMode(debugMode)
    {
        mFunc0 = func;
        mPreviousTime = millis();
    }

    void run() {
        if (millis() - mPreviousTime >= mDelayTime)
        {
            if (mDebugMode) Serial.println("uId: " + String((unsigned long)this) + " millis: " + String(millis() + "ms"));
            mPreviousTime = millis();
            mFunc0();
        }
    }
};

РЕШЕНИЕ:

class MillisTimer
{
private:
    void (*mFunc)();
    const uint16_t mDelayTime;
    unsigned long mPreviousTime;
    const bool mDebugMode;

public:
    MillisTimer(void(*func)(), uint16_t delayTime, bool debugMode = false) : mDelayTime(delayTime), mDebugMode(debugMode), mPreviousTime(millis())
    {
        mFunc = func;
    }

    void run() {
        if (millis() - mPreviousTime >= mDelayTime)
        {
            if (mDebugMode) Serial.println("uId: " + String((unsigned long)this) + " millis: " + String(millis() + "ms"));
            mPreviousTime = millis();
            mFunc();
        }
    }
};

MillisTimer MT_measureAndWrite(measureAndWrite, 1000);
MillisTimer MT_LCDfrissit([](){LCDfrissit_(U_Akku, Teljesitmeny, U_Atlag, U_Korrekt);},500);

1 Ответ

0 голосов
/ 07 января 2019

Передайте непосредственно функтору в ваш класс:

template <class F>
class MillisTimer
{
private:
    F mF;
    const uint16_t mDelayTime;
    unsigned long mPreviousTime = 0;
    const bool mDebugMode;

public:
    MillisTimer(F f, uint16_t delayTime, bool debugMode = false) :
        f(f), mDelayTime(delayTime), mPreviousTime(millis()), mDebugMode(debugMode)
    {
    }

    void run() {
        if (millis() - mPreviousTime >= mDelayTime)
        {
            if (mDebugMode) {
                Serial.println("uId: " + String((unsigned long)this)
                               + " millis: " + String(millis() + "ms"));
            }
            mPreviousTime = millis();
            mF();
        }
    }
};

template <typename F>
MillisTimer<F> MakeMillisTimer(F f, uint16_t delayTime, bool debugMode = false)
{
    return {f, delayTime, debugMode};
}

При использовании:

auto MT_measureAndWrite = MakeMillisTimer(&measureAndWrite, 1000);
auto MT_LCDrefresh =  = MakeMillisTimer([](){ LCDrefresh(1.5, 2.5, 3.5, 4, 5); }, 500);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...