有限状态机模拟数字计数器

时间:2018-01-24 22:53:29

标签: arduino

我必须使用Arduino C中的enumswitch/case属性编码创建一个有限状态机(FSM)来创建一个数字计数器。我应该有16个州:0-7计数和7-0倒计时。只要用户单击键盘上的某个键,计数就会反转。例如,它应该打印(0,1,2,3,4,5,6,7,0,1,2,3,4,...),然后在按下某个键后,会打印(4,3,2,1,0,7,6,5...)等。我完全陷入困境,想要一些帮助。谢谢!

我有一个代码的一般框架:

enum State {
    0;
    1;
    2;
    // 16 of these...
}

void setup() {
   Serial.begin(9600);
   Serial.println("FSM Forwards & Backwards");
}

void loop() {
    state = nextState(state);
    switch (state) {
       case 0:
       // more states(cases) here
       // create a FSM to determine the next state of the machine.
}

State nextState(State state){
    char input = Serial.read();
    // more states(cases) here
}

bool checkReverse(){
    // which reverses the direction of the counter if a key on the 
    keyboard has been pressed
}

1 个答案:

答案 0 :(得分:0)

对我来说似乎是功课。 Arduino使用Wiring语言,实际上是C ++。它包含了许多各种思想库。

您可能想要这样的事情,请注意其内部状态由变量状态和方向组成。它会每秒更新自动机的状态。同时,它将扫描输入的数据以便' r'性格和逆转方向。

struct FSM {
  enum state_t {
    step0,
    step1,
    ...
    step8,
    step9,
    ...
  };
  state_t state;
  bool direction;

  FSM() {state = step0;}
  void nextState(bool toggle) {
    state_t oldState = state;
    state_t ret;
    if(direction) {
      switch(oldState) {
        case step0:
          ret = step8;
          break;
        case step1:
          ret = step8;
          break;
        ...
      }
    else {
      case step0:
        ret = step1;
        break;
      case step1:
        ret = step2;
        break;
      ...
    }
    state = ret; // Update state
    direction = toggle ? !direction: direction; // Update toggle
  }
  int getOutput() {
    switch(state) {
      case step0:
        return 0;
      ...
      case 8:
        return 7;
      case 9:
        return 6;
      ...
};
FSM fsm;
bool toggle = false;
unsigned intlastTime;
void setup() {
        lastTime = millis();
}
void loop() {
        int c = Serial.read();
        if(c == 'r') toggle = ! toggle;

        bool timeToCount = false;
        if(lastTime + 1000 < millis()) { // Every second
                timeToCount = true;
                lastTime = millis();
                fsm.nextState(toggle); // 
                Serial.println(fsm.getOutput());
                toggle = false;
        }


}