【问题标题】:Arduino Switch to Turn a Relay timerArduino 开关开启继电器定时器
【发布时间】:2015-11-28 22:20:29
【问题描述】:

简而言之:我想在打开一个开关后打开一个继电器 30 秒。

我正在尝试在家中进行百叶窗自动化。

我有一个简单的 ON-OFF-ON 开关,连接到连接到继电器的 Arduino。

如果我将开关从中心向下拨动,我想打开 Relay#1 最多 30 秒。也就是说,当我切换时继电器打开,当定时器达到 30 秒时继电器关闭。

同样,如果我从中心向上拨动开关,我想将 Relay#2 开启 30 秒

当我切换回中心时,我希望计时器重置。

我不知道怎么做。有人可以帮忙吗?

我一直在尝试为此使用 elapsedMillis 库,这是一个很好的库,可以帮助我避免使用延迟: http://playground.arduino.cc/Code/ElapsedMillis

尽管我可以在没有 30 秒限制的情况下使用继电器,但我无法找出结束继电器工作的代码。这是我当前的代码:

      #include <elapsedMillis.h>
    #define RELAY_ON 0
    #define RELAY_OFF 1

    #define RELAY1_TURNS_ON_BLINDS  5
    #define RELAY2_SHUTS_DOWN_BLINDS 6

    #define shutswitch A0
    #define openswitch A1

    bool LocalCommandToOpen;
    bool LocalCommandToShut;

    void setup() ////////SETUP////////
    {
    digitalWrite(RELAY1_TURNS_ON_BLINDS, RELAY_OFF);
     digitalWrite(RELAY2_SHUTS_DOWN_BLINDS, RELAY_OFF);

     pinMode(RELAY1_TURNS_ON_BLINDS, OUTPUT);
     pinMode(RELAY2_SHUTS_DOWN_BLINDS, OUTPUT);

     pinMode(shutswitch, INPUT);
     pinMode(openswitch, INPUT);
        } ////SETUP

  void loop() { ///////LOOP
         if (digitalRead(shutswitch) == 1)
     {
       LocalCommandToOpen = 1;
     }
     else
     {
       LocalCommandToOpen = 0;
     }

      if ( digitalRead(openswitch) == 1)
     {
       LocalCommandToShut = 1;
     }
     else
     {
       LocalCommandToShut = 0;
     }

    unsigned int CloseInterval = 14000;
     elapsedMillis timeElapsedSinceCloseButtonPush = 0;
     unsigned int OpenInterval = 14000;
     elapsedMillis timeElapsedSinceOpenButtonPush = 0;



     //MANUAL SWITCH OPERATION

     if ( LocalCommandToShut == 1 )
     {
       digitalWrite(RELAY1_TURNS_ON_BLINDS, RELAY_OFF);
       digitalWrite(RELAY2_SHUTS_DOWN_BLINDS, RELAY_ON);
     }
     else
     {
       digitalWrite(RELAY2_SHUTS_DOWN_BLINDS, RELAY_OFF);
     }

    //MANUEL DUGME ILE ACMA
     if ( LocalCommandToOpen == 1)
     {
       digitalWrite(RELAY2_SHUTS_DOWN_BLINDS, RELAY_OFF);
       digitalWrite(RELAY1_TURNS_ON_BLINDS, RELAY_ON);
     }
     else
     {
       digitalWrite(RELAY1_TURNS_ON_BLINDS, RELAY_OFF);
     }

     delay(500);

    } /////////////////LOOP////////////////////////////////////

【问题讨论】:

    标签: timer arduino switch-statement toggle


    【解决方案1】:

    这里的一个建议是使用“状态机”,以便在切换转换时获得“状态 1”;在该状态下,计时器启动,并将您置于“状态 2”。在“状态 2”中,您检查时间,如果超过 X 秒,则进入“状态 3”。您可以监视开关从低到高(或从高到低)的转换,并使用它来重置系统状态。

    一段示例代码让您了解如何实现这一点。变量“SystemState”为整数,SYSTEM_ABORT、SYSTEM_IDLE等为常量。

    这样做的美妙之处在于过渡很容易弄清楚。例如,如果您处于 SYSTEM_WAIT 状态,那么您唯一要查找的就是大于 5 秒的时间。此外,您可以查看输入转换或值来设置状态(如 SystemStopButton == 0,将状态设置为“SYSTEM_ABORT”)。

        // SystemStopButton is an input
    
        void SystemStateMachine(void)
          ///////////////////////////////////////////////////////////////////////////////////////////
            {
    
              if (SystemStopButton == 0)
              {
                SystemState = SYSTEM_ABORT;
              }
    
              switch (SystemState)
              {
                case SYSTEM_IDLE:
                  {
                    RunPinState = OFF;
                    StopPinState = OFF;
                    if (SystemRunButton == 0)
                    {
                      SystemState = SYSTEM_START;
                      ShowStep();
                    }
                    break;
                  }
                case SYSTEM_START:
                  {
                    StandardMessage = "START  ";
                    RunPinState = ON;
                    StopPinState = OFF;
                    SystemState = SYSTEM_WAIT;
                    ShowStep();
                    break;
                  }
                case SYSTEM_WAIT: // wait for 5 seconds
                  {
                    StandardMessage = "WAIT    ";
                    if ((CurrentMillis - StateStepTimeMillis) > 5000)
                    {
                      SystemState = SYSTEM_RETRACT;
                      ShowStep();
                    }
                    break;
                  }
    
                case SYSTEM_RETRACT: //
                  {
                    StandardMessage = "RETRACT";
                    /* motor stuff goes here... */
                    if ((CurrentMillis - StateStepTimeMillis) > 5000)
                    {
                      SystemState = SYSTEM_ADVANCE_TAPE_WAIT
                      ShowStep();
                    }
                    break;
                  }
    
                // etc. etc. etc.
    
              case SYSTEM_ABORT: //
                  {
                    StandardMessage = "ABORT";
                    /* motor stop stuff goes here... */
              SystemState=SYSTEM_IDLE;
                    break;
                  }
    
                default:
                  {
                    break;
                  }
              }
    
    
            }
    
            void ShowStep(void)
            /////////////////////////////////////////////////////////////////////
            // show step and set time so we can keep track of time in each step
            {
              Serial.print("SystemState = ");
              Serial.println(String(SystemState));
              SetStepTime();
            }
    
            void SetStepTime(void)
            /////////////////////////////////////////////////////////////////////
            {
              StateStepTimeMillis = CurrentMillis;
            }
    

    【讨论】:

      【解决方案2】:

      您可以使用状态机;这使事情更容易理解。

      类似于:

      Arduino Switch to Turn a Relay timer

      这里是关于状态机的一个很好的讨论:

      Complicated state transitions: best practices

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-07-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-15
        相关资源
        最近更新 更多