我可以创建一个代码作为输入的方法吗?

时间:2016-11-11 10:42:30

标签: c++ c arduino

我是C ++的初学者,目前正在使用arduino(类似于C ++,我被告知在这里提出这个问题)。

我已经写了以下代码:

int buttonPinState = digitalRead(buttonPin);

  if (buttonPinState != lastButtonPinState) {
    if (buttonPinState == 1) {  
      counter++; //Any random code goes here.
    }
  }
  lastButtonPinState = buttonPinState;

是否有可能从这段代码中创建一个方法,我可以在其中更改" counter ++;"到我需要执行的任何事情?

3 个答案:

答案 0 :(得分:3)

您可以使用指向函数的指针作为参数,然后您可以在if块中执行它。

void function(void (*arbitrary_function)()) {
    int buttonPinState = digitalRead(buttonPin);

    if (buttonPinState != lastButtonPinState) {
        if (buttonPinState == 1) {  
            arbitrary_function();
        }
    }

    lastButtonPinState = buttonPinState;
}

void arbitrary_function_1() {
    // some code here
}


void arbitrary_function_2() {
    // some other code here
}

void loop() {
     ...
     function(&arbitrary_function_1);
     ...
     function(&arbitrary_function_2);
     ...
}

答案 1 :(得分:2)

是的,你可以。如果buttonPinState == 1 != lastButtonPinState if

,我不确定您的问题是否如此简单?

说出您期待的条件是否为真,即按下按钮。

您不需要2个单独&&条件即可使用int buttonPinState = digitalRead(buttonPin); if ( (buttonPinState != lastButtonPinState) && (buttonPinState == 1) ) { counter++; //increment or do anything. } lastButtonPinState = buttonPinState; 并执行您想要的操作

解决方案1:

int buttonPinState = digitalRead(buttonPin);

  if ( (buttonPinState != lastButtonPinState) && (buttonPinState == 1) ) 
  {  
      functionCall(); //Call function to execute anything
  }

  lastButtonPinState = buttonPinState;

int functionCall()
{
   counter++;//increment counter
   // do your activity 
   return 0;
}

解决方案2:

通过调用函数

$(document).ready

答案 2 :(得分:0)

(我将一般性问题与其Arduino特定对应物分开)

一般注意事项

建议:阅读SICP 。它与Arduino无关,但它是对编程的一个很好的介绍,可以免费获得,并且会教你正确的术语和概念。

[你似乎缺乏很多通用的编程概念;你的问题可能不是Arduino特有的,与你相信的C或C ++相关的更少]

一般来说,您似乎 想要first class functional values或元编程设施。请详细了解functional programmingmetaprogramming。对于像Arduino这样的小型系统,它可能看起来像XY problem,你应该激发你的问题。

第一类函数通常使用closures实现。 C没有它们,C ++只有C++11才有它们(但我不确定你的Arduino交叉编译器是否符合C ++ 11)。在C ++ 11中,您将使用anonymous functionslambda expressionsstd::function

很可能,Arduino上提供的编程语言不提供一流的功能和闭包。然后,您将使用function pointers(它们存在于普通C99中)至callbacks,即使用传递某些客户端数据的附加约定。然后你可以看看这些(函数指针+回调客户端数据)作为一个穷人的约定来实现闭包。

或者,您可以考虑在运行时生成一些代码然后调用它。这是metaprogramming的一种形式。您可能需要一些JIT compilation库(例如GCCJITlibjit),但这些库要求可执行代码可以放在RAM中(如每个Von Neumann architecture),这可能不是适用于许多Arduino电路板(代码仅在Flash ROM中,在某些Harvard architecture中)。

continuationCPS的抽象概念也是间接相关的。

回到Arduino:

您可能会认为您的代码是某些finite statepushdown堆栈自动机,或者是某些bytecode解释器。 (所以我猜你不会真的需要元编程,或者一等关闭,即使你的问题与它们有关)。也许将每个按钮与一些回调相关联(即使用指针数组和回调客户端数据)。例如。

/// signature of callbacks
typedef void button_callback_sigt(int buttoncode, void*clientdata);

#define NB_BUTTONS 16
struct button_callback_st {
  button_callback_sigt* funptr; // function pointer
  void* data; // client data
};
struct button_callback_st buttoncb[NB_BUTTONS];

然后您需要一些其他代码来初始化该数组,并在按下按钮时运行回调(并处理键bounces)。也许某些回调可能会更新该数组(例如,如果某些按钮是modal,就像键盘上的shift键一样。)

你可能想要一个"通用" event loop处理按钮并消除毛刺和按键弹跳(遵循separation of concerns设计原则)。一旦确定按下按钮是真的(不是寄生虫),它将调用适当的回调:

int buttonnumber = .... ;
(*buttoncb[buttonnumber].funptr) (buttonnumber, buttoncb[buttonnumber].data);

一些回调的具体例子可能确实增加了一些全局计数器。这是相关按钮的编号(事实上,您最好有enum描述按钮)

#define COUNTBUTTON 3

这是计数器,一个全局变量:

extern int counter;

增加它的实际工作是在这个回调函数中。它的第二个参数是计数器的地址。

void counter_cbfun(int buttoncode, void*data) {
  int* pc = (int*)data;
  if (buttoncode == COUNTBUTTON)
     (*pc) ++;
};

并且您将初始化

  buttoncb[COUNTBUTTON].funptr = counter_cbfun; // function address
  buttoncb[COUNTBUTTON].data = (void*)&counter;

NB:思考的食物:http://norvig.com/21-days.html