如何细化和扩展Arduino有限状态机

如何细化和扩展Arduino有限状态机,arduino,arduino-c++,Arduino,Arduino C++,我正在努力在我的Arduino程序中建立一个状态机,我想我有一个足够简单的程序来学习有限状态机。目前我遇到的问题是,每次程序改变状态时,它都会将其状态或记录的数据淹没串行监视器。我创建了一些在非常有限的级别上工作的代码,但是我觉得我不能扩展它,因为这段代码只有在我有3个状态时才有效。但是如果我想要4或5个州呢 我希望在程序继续运行时,每当状态改变时,串行监视器中只提示我一次。 比如说, 如果程序空闲(状态0),串行监视器中不显示任何内容 如果程序为只读,则提示串行监视器(状态1)一次,而不是每次

我正在努力在我的Arduino程序中建立一个状态机,我想我有一个足够简单的程序来学习有限状态机。目前我遇到的问题是,每次程序改变状态时,它都会将其状态或记录的数据淹没串行监视器。我创建了一些在非常有限的级别上工作的代码,但是我觉得我不能扩展它,因为这段代码只有在我有3个状态时才有效。但是如果我想要4或5个州呢

我希望在程序继续运行时,每当状态改变时,串行监视器中只提示我一次。 比如说,

  • 如果程序空闲(状态0),串行监视器中不显示任何内容
  • 如果程序为只读,则提示串行监视器(状态1)一次,而不是每次执行读取
  • 如果由于SPST开关状态改变而导致程序正在读取和记录,则提示串行监视器(状态2)一次,而不是每次执行读取和记录时
  • 我还想了解如何更好地处理这个问题,因为我觉得这只适用于3状态的示例。如果添加更多开关或更多状态,会发生什么

    快速编程功能:

  • 等待100毫秒。
    • LED1州高
    • LED2状态低
  • 如果SPST开关为高电平,读取模拟输入引脚并返回空闲状态。(此时将有一个挂钩的显示器,无论是否记录数据,都将显示值)。
    • LED1状态低
    • LED2状态低
  • 如果SPST开关处于低位,则将读取的数据记录到文件中。
  • 如果这是第一次,请使用unix名称创建一个文件
  • 如果这不是第一次(文件存在),请打开它并附加到它。
    • LED1状态低
    • LED2州高
  • 我有这样的工作,但觉得效率很低,我到这里只是运气好。我一直在努力执行有限状态机

    void setup(){
    串行。开始(57600);//启动串行
    延迟(100);
    //设置pinmodes
    //启动并调整RTC
    //开始RTC
    延迟(100);
    //初始化SD卡
    }
    void循环(){
    //阅读以查看开关是否已改变状态
    引脚状态=数字读取(引脚开关);
    当前毫秒=毫秒();
    //状态0-空闲
    if(当前毫秒-先前毫秒<间隔){
    STATE=STATE;//状态标志集
    led_状态(高、低);
    数字写入(引脚读取、LED读取);
    }
    //状态1-只读
    如果((引脚状态==高)和&(当前毫秒-以前的毫秒>=间隔)){
    如果(更改_状态){
    STATE=1;//状态标志集
    Serial.println(“更改状态:读取”);
    }
    previousMillis=currentMillis;//记住时间
    led_状态(低,低);//更新led
    read();//读取引脚
    改变状态=错误;
    }
    //状态2-读取和记录
    否则如果((引脚状态==低)和&(当前毫秒-先前毫秒>=间隔)){
    如果(!更改_状态){
    Serial.println(“更改状态:读取并记录”);
    }
    previousMillis=currentMillis;//记住时间
    led_状态(低、高);//更新led
    read();//读取引脚
    如果(状态<2){//是否已创建文件?
    //创建新文件
    }
    filename=文件名;
    open();//打开文件
    write();//写入文件
    close();//关闭文件
    STATE=2;//设置了状态标志
    改变状态=真;
    }
    }
    无效读取(){
    //读取值
    //计算值
    }
    空开(){
    //打开文件
    }
    无效写入(){
    //写入文件
    }
    无效关闭(){
    //关闭文件
    }
    无效led灯状态(int led灯一、int led灯二){
    //更改LED的状态
    

    更新,解决了。 从下面由Arcadien提供的文章中,我能够重新思考程序流程,并将其重写为switch case状态机

    //声明状态
    枚举状态{
    _重新声明,
    _显示状态,
    _createState,
    _openState,
    _不动产,
    _拯救国家,
    _错误状态
    };
    void循环(){
    pinState=数字读取(pinSwitch);
    //绿色LED高
    //黄色发光二极管低电平
    当前毫秒=毫秒();
    如果((当前毫秒-以前的毫秒)>=间隔){
    开关(当前状态){
    案例_readState:
    //Serial.println(“当前状态:_readState”);
    //绿色发光二极管低电平
    _currentState=\u readState;
    前一毫秒=当前毫秒;
    //读取值
    案例显示状态:
    //Serial.println(“当前状态:_displayState”);
    _当前状态=_显示状态;
    前一毫秒=当前毫秒;
    如果(pinState!=LOW){//如果未录制,则中断
    filename=“”;
    _currentState=\u readState;
    打破
    };
    案例_createState:
    //Serial.println(“当前状态:_createState”);
    //黄色LED高
    _currentState=_createState;
    前一毫秒=当前毫秒;
    如果(文件名==NULL){
    //Serial.print(“创建新文件…”);
    DateTime now=rtc.now();
    filename=String(现在是.unixtime(),DEC);
    文件名=文件名+“.txt”;
    //Serial.print(文件名);
    //Serial.println(“已创建!”);
    //Serial.print(“将标题写入文件…”);
    //dataFile=SD.open(文件名,文件写入);
    dataFile=SD.open(文件名,O|u WRITE | O|u CREAT);
    println(“时间(毫秒)、TPS、AFR”);
    //Serial.println(“标题已写入!”);
    dataFile.close();
    };
    案例_openState:
    //Serial.println(“当前状态:_openState”);
    _currentState=\u openState;
    dataFile=SD.open(filename,O|u create | O|u APPEND | O|u WRITE);//openfilename.txt
    案件(不动产):
    //Serial.println(“当前状态:_writeState”);
    _当前状态=_writeState;
    //如果文件可用,请写入:
    如果(数据文件){
    //创建单行数据字符串
    dataFile.println(