简而言之:当我打开一个开关后,我想打开继电器30秒。
我正试着在家里做百叶窗自动化。
我有一个简单的开关,连接到一个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////////////////////////////////////发布于 2015-12-21 08:31:36
这里的一个建议是使用“状态机”,这样在切换转换时,您将获得“状态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;
}发布于 2015-12-21 08:40:34
https://stackoverflow.com/questions/33977086
复制相似问题