实现按钮的有限状态机(FSM)-Arduino中文社区 - Powered by Discuz! Archiver

topdog 发表于 2021-3-23 23:50

实现按钮的有限状态机(FSM)

本帖最后由 topdog 于 2021-3-24 06:32 编辑

Arduino用按键来控制LED,一个按键的正确姿势如下图:


当你按下按钮时,按钮将电路中的两个点连接起来,UNO读取管脚3电平变化控制板载管脚13的LED亮或者灭。

const int buttonPin = 3;
const int ledPin =13;

int buttonState = 0;

void setup() {
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT);
}

void loop() {
buttonState = digitalRead(buttonPin);

if (buttonState == HIGH) {
    digitalWrite(ledPin, HIGH);
} else {
    digitalWrite(ledPin, LOW);
}
}
但是按钮是机械装置,通常会出现虚假甚至是欺骗的状态转变,不去除抖动(Debounce),按一次按钮可能会导致不可预知的结果。必须在短时间内检查两次以确保按钮确实被按下了。下面的示例是使用millis()函数来记录按钮被按下后所经过的时间,称之为非阻塞的方式,区别于delay(),后者称为阻塞方式。
const int buttonPin = 3;
const int ledPin = 13;

int ledState = HIGH;
int buttonState;
int lastButtonState = LOW;

unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;

void setup() {
pinMode(buttonPin, INPUT);
pinMode(ledPin, OUTPUT);

digitalWrite(ledPin, ledState);
}

void loop() {
int reading = digitalRead(buttonPin);

if (reading != lastButtonState) {
    lastDebounceTime = millis();
}

if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;

      if (buttonState == HIGH) {
      ledState = !ledState;
      }
    }
}

digitalWrite(ledPin, ledState);

lastButtonState = reading;
}
即要考虑防抖动的基本需求,还要在控制过程中用一个按钮实现有限状态机(finite state machine,简称:FSM),推荐使用onebutton库。下面的示例是双击触发事件。
#include "OneButton.h"

//简略写法
//OneButton button(3);

#define BUTTON_PIN 3

//初始化为高电平
OneButton button = OneButton(
BUTTON_PIN,
false,      
false      
);

void setup() {
pinMode(13, OUTPUT);      
button.attachDoubleClick(doubleclick);
}   

void loop() {
button.tick();
delay(10);
}

void doubleclick() {
static int m = LOW;
m = !m;
digitalWrite(13, m);
}
实现细节:
如果你想了解这个库是如何工作的,这里有一些解释:
在OneButton库的tick()函数内,您可以找到检查输入引脚检测单点击,双击或长按情况的实现。这种实现被称为有限状态机(FSM),它实现了以下状态图:




每当tick()函数被调用时,就会显示当前情况,分析当前状态和输入值,并在适用时调用外部函数或者改变当前状态。特别是OneButton库的实现从来不会调用delay()或类似的函数,因此在大多数情况下都会很快返回。总之,OneButton库可以非常便捷地实现有限状态机(FSM),它有助于降低实现的复杂性。
页: [1]
查看完整版本: 实现按钮的有限状态机(FSM)