我是C ++的初学者,目前正在使用arduino(类似于C ++,我被告知在这里提出这个问题)。
我已经写了以下代码:
int buttonPinState = digitalRead(buttonPin);
if (buttonPinState != lastButtonPinState) {
if (buttonPinState == 1) {
counter++; //Any random code goes here.
}
}
lastButtonPinState = buttonPinState;
是否有可能从这段代码中创建一个方法,我可以在其中更改" counter ++;"到我需要执行的任何事情?
答案 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 programming和metaprogramming。对于像Arduino这样的小型系统,它可能看起来像XY problem,你应该激发你的问题。
第一类函数通常使用closures实现。 C没有它们,C ++只有C++11才有它们(但我不确定你的Arduino交叉编译器是否符合C ++ 11)。在C ++ 11中,您将使用anonymous functions,lambda expressions和std::function。
很可能,Arduino上提供的编程语言不提供一流的功能和闭包。然后,您将使用function pointers(它们存在于普通C99中)至callbacks,即使用传递某些客户端数据的附加约定。然后你可以看看这些(函数指针+回调客户端数据)作为一个穷人的约定来实现闭包。
或者,您可以考虑在运行时生成一些代码然后调用它。这是metaprogramming的一种形式。您可能需要一些JIT compilation库(例如GCCJIT或libjit),但这些库要求可执行代码可以放在RAM中(如每个Von Neumann architecture),这可能不是适用于许多Arduino电路板(代码仅在Flash ROM中,在某些Harvard architecture中)。
continuation和CPS的抽象概念也是间接相关的。
您可能会认为您的代码是某些finite state或pushdown堆栈自动机,或者是某些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