新手和无法编译的计时器模块

A newbie and the timer module that doesn't compile

我是 C/C++ 的新手。我已经使用了一些高级语言,例如 Java 和 C#,但这是我必须要说的其他内容。我正在尝试为 Arduino 构建一个定时器模块,这样我就可以轻松地将必须在一定时间后执行的工作排队,而无需使用 delay()。我想尽可能直观地创建它,以便我可以轻松地重新使用它。

到目前为止,我已经尝试了很多不同的方法。我所做的主要是阅读有关如何在 C/C++ 中实现特定目标的教程,并以此创建我的小项目。

主 .ino 文件:

#include "Timer.h"

Timer timer;

void setup()
{
    // Init the timer
    timer.init();

    pinMode(13, OUTPUT);

    // Define the state
    int state = 1;

    // Create the action
    TimerAction action;
    action.create(1000, &timerElapsed, 1 -1);
    action.state = &state;
}

void loop()
{
    timer.run();
}

void timerElapsed(TimerAction action) {
    int *state = (int*)action.state;
    if (state == 0) {
        digitalWrite(13, HIGH);
        *state = 1;
    }
    else
    {
        digitalWrite(13, LOW);
        *state = 0;
    }
}

很简单。我正在尝试使板载 LED 灯闪烁以作为概念证明。

这是 Timer.h 文件:

#ifndef _TIMER_h
#define _TIMER_h

#if defined(ARDUINO) && ARDUINO >= 100
    #include "arduino.h"
#else
    #include "WProgram.h"
#endif

struct Timer {
    TimerAction* actions;
    uint8_t size;

    void init();
    void queue(TimerAction action);
    void dequeue(TimerAction action);
    void dequeueIdx(int idx);
    void run();
};

struct TimerAction {
    // Sets whether to repeat the action
    uint8_t repetitive;
    // Sets how many times to repeat the action, -1 for infinite
    // Will only be used when repetitive == 1
    long finite;

    void (*callback)(TimerAction sender);
    void *state;

    unsigned long last;
    unsigned long interval;

    void create(long interval, void(*callback)(TimerAction sender), uint8_t repetitive = 0U, long finite = -1L);
};

#endif

这是 Timer.ino 文件:

#include "Timer.h"

void Timer::init() {
    size = 0;
    actions = new TimerAction[10];
}

void Timer::queue(TimerAction action) {
    action.last = millis();
    actions[size - 1] = action;

    size++;
}

void Timer::dequeue(TimerAction action) {
    for (int i = 0; i < size; i++)
        if (&(actions[i]) == &action) {
            memmove(actions + i, actions + i + 1, (size - (i + 1)) * sizeof(TimerAction));
            break;
        }
}

void Timer::dequeueIdx(int idx) {
    memmove(actions + idx, actions + idx + 1, (size - (idx + 1)) * sizeof(TimerAction));
}

void Timer::run() {
    for (int i = 0; i < size; i++)
        if ((actions[i].last + actions[i].interval) >= millis()) {
            TimerAction action = actions[i];
            action.callback(action);
            if (action.repetitive == 1) {
                if (action.finite > 0)
                    action.finite--;
                else
                    if (action.finite == 0)
                        dequeueIdx(i);
            }
            else
                dequeueIdx(i);
        }
}

void TimerAction::create(long _interval, void(*_callback)(TimerAction sender),
                         uint8_t _repetitive = 0U, long _finite = -1L) {
    interval = _interval;
    callback = _callback;
    repetitive = _repetitive;
    finite = _finite;
}

这些是编译器抛出的错误:

Arduino: 1.6.1 (Windows 8.1), Board: "Arduino Uno"

In file included from Stoplicht.ino:1:0:

Timer.h:13:2: error: 'TimerAction' does not name a type

  TimerAction* actions;

  ^

Timer.h:17:13: error: 'TimerAction' has not been declared

  void queue(TimerAction action);

             ^

Timer.h:18:15: error: 'TimerAction' has not been declared

  void dequeue(TimerAction action);

               ^

Timer.ino: In member function 'void Timer::init()':

Timer.ino:5:2: error: 'actions' was not declared in this scope

Timer.ino: At global scope:

Timer.ino:8:6: error: prototype for 'void Timer::queue(TimerAction)' does not match any in class 'Timer'

In file included from Stoplicht.ino:1:0:

Timer.h:17:7: error: candidate is: void Timer::queue(int)

  void queue(TimerAction action);

       ^

Timer.ino:15:6: error: prototype for 'void Timer::dequeue(TimerAction)' does not match any in class 'Timer'

In file included from Stoplicht.ino:1:0:

Timer.h:18:7: error: candidate is: void Timer::dequeue(int)

  void dequeue(TimerAction action);

       ^

Timer.ino: In member function 'void Timer::dequeueIdx(int)':

Timer.ino:24:10: error: 'actions' was not declared in this scope

Timer.ino: In member function 'void Timer::run()':

Timer.ino:29:8: error: 'actions' was not declared in this scope

Timer.ino: At global scope:

Timer.ino:45:52: error: default argument given for parameter 3 of 'void TimerAction::create(long int, void (*)(TimerAction), uint8_t, long int)' [-fpermissive]

In file included from Stoplicht.ino:1:0:

Timer.h:36:7: error: after previous specification in 'void TimerAction::create(long int, void (*)(TimerAction), uint8_t, long int)' [-fpermissive]

  void create(long interval, void(*callback)(TimerAction sender), uint8_t repetitive = 0U, long finite = -1L);

       ^

Timer.ino:45:52: error: default argument given for parameter 4 of 'void TimerAction::create(long int, void (*)(TimerAction), uint8_t, long int)' [-fpermissive]

In file included from Stoplicht.ino:1:0:

Timer.h:36:7: error: after previous specification in 'void TimerAction::create(long int, void (*)(TimerAction), uint8_t, long int)' [-fpermissive]

  void create(long interval, void(*callback)(TimerAction sender), uint8_t repetitive = 0U, long finite = -1L);

       ^

让我解释一下为什么我使用 Array 而不是 std::vector。我的思路是这样的:Arduino 非常薄弱,actions 将被大量访问。所以我认为最初实现它需要做更多的工作,但它将确保计时器不会使用太多 Arduino 的资源。

我试了很多东西,但我不太明白问题出在哪里。所以这就是为什么我要请专家查看我的代码并可能让我走上正轨的原因。

在 Timer.h 你有:

TimerAction* actions;

在编译器看到那行代码的时候,它还没有看到 TimerAction 是什么。因此它不知道类型是什么并且给你一个错误。您需要做的是 forward declare TimerActionTimer 之前,以便编译器知道它在做什么。

#ifndef _TIMER_h
#define _TIMER_h

#if defined(ARDUINO) && ARDUINO >= 100
    #include "arduino.h"
#else
    #include "WProgram.h"
#endif

struct TimerAction;

struct Timer {
//...