首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Arduino开关开启继电器定时器

Arduino开关开启继电器定时器
EN

Stack Overflow用户
提问于 2015-11-29 06:20:29
回答 2查看 4K关注 0票数 0

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

我正试着在家里做百叶窗自动化。

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

如果我从中心向下切换开关,我想打开Relay#1最多30秒。换句话说,当我切换时,继电器打开,当计时器达到30秒时,继电器关闭。

类似地,如果我从中心向上切换开关,我想打开Relay#2恰好30秒

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

我想不出是怎么回事。有人能帮上忙吗?

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

然而,即使我可以在没有30秒限制的情况下工作继电器,我也找不出结束继电器工作的代码。下面是我当前的代码:

代码语言:javascript
复制
      #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////////////////////////////////////
EN

回答 2

Stack Overflow用户

发布于 2015-12-21 08:31:36

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

通过一小段示例代码,您可以了解如何实现此功能。变量'SystemState‘是一个整数,而SYSTEM_ABORT、SYSTEM_IDLE等是常量。

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

代码语言:javascript
复制
    // 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;
        }
票数 0
EN

Stack Overflow用户

发布于 2015-12-21 08:40:34

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

类似于:

Arduino Switch to Turn a Relay timer

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

Complicated state transitions: best practices

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33977086

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档