如何检测Arduino中按下/释放按钮的时间长度,然后再打印一些自定义输出?
答案 0 :(得分:11)
Arduino只能检测按钮的状态(按下或未按下)。
您可以使用计时器变量(基于其文档中的this example)来保存按下或释放按钮的确切时间,这样您就可以了可以检查两个变量之间的差异,以计算它被按下和释放的时间。
代码看起来像这样:
const int buttonPin = 2;
int buttonState = 0; // current state of the button
int lastButtonState = 0; // previous state of the button
int startPressed = 0; // the time button was pressed
int endPressed = 0; // the time button was released
int timeHold = 0; // the time button was hold
int timeReleased = 0; // the time button was released
void setup() {
pinMode(buttonPin, INPUT); // initialize the button pin as a input
Serial.begin(9600); // initialize serial communication
}
void loop() {
buttonState = digitalRead(buttonPin); // read the button input
if (buttonState != lastButtonState) { // button state changed
updateState();
}
lastButtonState = buttonState; // save state for next loop
}
void updateState() {
// the button was just pressed
if (buttonState == HIGH) {
startPressed = millis();
timeReleased = startPressed - endPressed;
if (timeReleased >= 500 && timeReleased < 1000) {
Serial.println("Button was idle for half a second");
}
if (timeReleased >= 1000) {
Serial.println("Button was idle for one second or more");
}
// the button was just released
} else {
endPressed = millis();
timeHold = endPressed - startPressed;
if (timeHold >= 500 && timeHold < 1000) {
Serial.println("Button was hold for half a second");
}
if (timeHold >= 1000) {
Serial.println("Button was hold for one second or more");
}
}
}
但是,如果你想触发一个事件而按下按钮(或者你想在某个显示中增加一个计数器),你仍然可以做同样的数学运算。
将循环函数中的条件更改为:
if (buttonState != lastButtonState) {
updateState(); // button state changed. It runs only once.
} else {
updateCounter(); // button state not changed. It runs in a loop.
}
然后实现你的新功能:
void updateCounter() {
// the button is still pressed
if (buttonState == HIGH) {
timeHold = milis() - startPressed;
if (timeHold >= 1000) {
Serial.println("Button is hold for more than a second");
}
// the button is still released
} else {
timeReleased = milis() - endPressed;
if (timeReleased >= 1000) {
Serial.println("Button is released for more than a second");
}
}
}
答案 1 :(得分:0)
为了您的兴趣,这里有一个代码示例,它使用 2 个数组来存储分配给相应输入按钮的 arduino 引脚的按钮状态。在循环期间,您可以对想要的重复进行简单的检查:
if(button_down(But1_pin, BTN_LOOP_DELAY_MS))
{
// code here repeated if the button is either clicked or maintained
}
button_down()
还将第一次重复推迟 DELAY_WAIT_BEFORE_REPEAT
毫秒。
这里是完整的测试示例:
#define BTN_LOOP_DELAY_MS 100
#define DELAY_WAIT_BEFORE_REPEAT 500
#define NB_MAX_PIN_INPUT 13
#define But1_pin 7
#define But2_pin 6
// array to check status change
bool prev_button[NB_MAX_PIN_INPUT];
unsigned long button_last_down[NB_MAX_PIN_INPUT];
// macro : our read init with prev_button storage
#define READ_INIT_BUTTON(pin) \
do{ \
pinMode(pin, INPUT); \
prev_button[pin] = digitalRead(pin); \
} while(false)
// function at the end of the code
bool button_down(byte pin_num, unsigned int delay_repeated);
void setup() {
READ_INIT_BUTTON(But1_pin);
READ_INIT_BUTTON(But2_pin);
Serial.begin(115200);
}
void loop() {
if(button_down(But1_pin, BTN_LOOP_DELAY_MS))
{
Serial.print("new inpulse");
Serial.print(millis());
Serial.println();
}
if(button_down(But2_pin, BTN_LOOP_DELAY_MS))
{
Serial.println("button2");
}
}
bool button_down(byte pin_num, unsigned int delay_repeated)
{
bool b = digitalRead(pin_num);
bool r = false;
unsigned long currentMillis = millis();
if(prev_button[pin_num] != HIGH && b == HIGH)
{
r = true;
button_last_down[pin_num] = currentMillis + DELAY_WAIT_BEFORE_REPEAT;
}
else if(b == HIGH
&& prev_button[pin_num] == HIGH
&& currentMillis > button_last_down[pin_num]
&& currentMillis - button_last_down[pin_num] > delay_repeated
)
{
// save the last time we give a button impusle at true
button_last_down[pin_num] = currentMillis;
r = true;
}
// store button state, if changed
if(prev_button[pin_num] != b)
{
prev_button[pin_num] = b;
}
return r;
}