使用毫秒打开蠕动泵继电器x时间

  • 本文关键字:继电器 时间 c++ arduino relay
  • 更新时间 :
  • 英文 :


这是我在arduino中的第一个代码。我正试着为我的花园建立一个简单的浇水自动化系统。该代码包含3个主要功能,即:

  1. 往肥料罐里加水
  2. 在加水的同时向水箱中添加肥料,假设在此过程中会混合肥料
  3. 全天自动浇水

对于第一个和第三个函数,我已经完成了(理论上+小规模系统(。哈哈!

现在,对于肥料函数2(fertilize_PUMP(((,我使用2个蠕动泵将AB肥料溶液添加到槽中。我试图让泵运行x时间,但该功能只运行一次,之后,如果两个浮动开关都变干,则需要重置回路,并等待底部开关再次变湿。有人能帮我介绍一下我缺了哪一部分吗?我也愿意接受任何改进我的代码的建议。。非常感谢。

更新:

很抱歉让人感到困惑。实际上,对于这个功能,以下是我的要求。

  1. 如果顶部浮子干燥,底部浮子潮湿,打开两个蠕动泵10秒(或更长时间后会发生变化(并停止
  2. 然后,如果顶部浮子干燥且底部浮子干燥>重置
  3. 等待下一个顶部浮子变干,底部浮子变湿

我真的很抱歉再次混淆。之前的逻辑有点混乱。

#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 RTC;
#define relayON HIGH
#define relayOFF LOW
#define floatWET HIGH
#define floatDRY LOW
const byte bottom_float = 13; //bottom position float switch
const byte top_float = 12; //top position float switch
const byte relay_topup_PUMP = 2; //Relay 1 for PUMP/Solenoid to topup water into the fertilizer tank
const byte relay_watering_PUMP = 3; //Relay 2 for scheduled watering PUMP
const byte relay_fertilizer_PUMPA = 4; //Relay 3 for Peristaltic PUMP "A" solution fertilizer
const byte relay_fertilizer_PUMPB = 5; //Relay 4 for Peristaltic PUMP "B" solution fertilizer
unsigned long previousMillis = 0;   // stores last time relay was active(on)
unsigned long fertilizer_pumpON_interval = 10000; //(10s for testing)Time to turn ON fertilizer peristaltic pump to get required EC reading
void topup_PUMP();
void watering_PUMP();
void fertilizer_PUMP();
void setup ()
{
Serial.begin (9600);
Wire.begin();
//  RTC.begin();
if (! RTC.begin())
{
Serial.println("Couldn't find RTC");
while (1);
}
if (! RTC.isrunning())
{
Serial.println("RTC is NOT running!");
}
// following line sets the RTC to the date & time this sketch was compiled
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
pinMode (bottom_float, INPUT_PULLUP);
pinMode (top_float, INPUT_PULLUP);
pinMode (relay_topup_PUMP, OUTPUT);
pinMode (relay_watering_PUMP, OUTPUT);
pinMode (relay_fertilizer_PUMPA, OUTPUT);
pinMode (relay_fertilizer_PUMPB, OUTPUT);
//digitalWrite (relay_topup_PUMP, relayOFF);
//digitalWrite (relay_watering_PUMP, relayOFF);
digitalWrite (relay_fertilizer_PUMPA, relayOFF);
digitalWrite (relay_fertilizer_PUMPB, relayOFF);
DateTime now = RTC.now();
}   // end of setup
void loop ()
{
//  topup_PUMP();
//  watering_PUMP();
fertilizer_PUMP();
}
//void topup_PUMP()
//{
//  if (digitalRead (top_float) == floatDRY && digitalRead (bottom_float) == floatDRY)
//  {
//    Serial.println("TOPUP PUMP ON");
//    digitalWrite(relay_topup_PUMP, relayON);
//  }
//
//  if (digitalRead (top_float) == floatWET && digitalRead (bottom_float) == floatWET)
//  {
//    Serial.println("TOPUP PUMP OFF");
//    digitalWrite(relay_topup_PUMP, relayOFF);
//  }
//  delay (1000);
//}
//
//void watering_PUMP()
//{
////  DateTime now = RTC.now();
//      Serial.print(now.hour(), DEC);
//      Serial.print(':');
//      Serial.print(now.minute(), DEC);
//      Serial.print(':');
//      Serial.print(now.second(), DEC);
//      Serial.print(' ');
//      Serial.print(now.day(), DEC);
//      Serial.print('/');
//      Serial.print(now.month(), DEC);
//      Serial.print('/');
//      Serial.print(now.year(), DEC);
//      Serial.println();
//      delay(1000);
//
//  boolean watering_PUMPstate = false;
//  if (now.hour() == 15 && now.minute() >= 38 && now.minute() < 39) watering_PUMPstate = true;    //6:00 am - 5 mins
//  if (now.hour() == 15 && now.minute() >= 40 && now.minute() < 41) watering_PUMPstate = true;  //8:30 am - 5 mins
////  if (now.hour() == 11 && now.minute() >= 0 && now.minute() < 5) watering_PUMPstate = true;  //11:00 am - 5 mins
////  if (now.hour() == 13 && now.minute() >= 30 && now.minute() < 35) watering_PUMPstate = true;  //1:30 pm - 5 mins
////  if (now.hour() == 16 && now.minute() >= 0 && now.minute() < 10) watering_PUMPstate = true;  //4:00 pm - 10 mins
//
//  if (watering_PUMPstate == true)
//  {
//    digitalWrite(relay_watering_PUMP, relayON);
//    Serial.print("t");
//    Serial.println(F("Watering Plant"));
//    Serial.print("t");
//    Serial.println();
//  }
//  else
//  {
//    digitalWrite(relay_watering_PUMP, relayOFF);
//  }
//}
void fertilizer_PUMP()
{
unsigned long currentTime = millis();
boolean fertilizer_pumpON = false;
if ((digitalRead (top_float) == floatDRY) && (digitalRead (bottom_float) == floatWET) && (currentTime - previousMillis <= fertilizer_pumpON_interval)) //Turn on for 10s
{
Serial.print("t");
Serial.println(currentTime);
delay (1000);
fertilizer_pumpON = true;
}
if (fertilizer_pumpON == true)
{
Serial.print("t");
Serial.println(F("Adding Fertilizer A and B"));
delay (1000);
digitalWrite(relay_fertilizer_PUMPA, relayON);
digitalWrite(relay_fertilizer_PUMPB, relayON);
}
else
{
digitalWrite(relay_fertilizer_PUMPA, relayOFF);
digitalWrite(relay_fertilizer_PUMPB, relayOFF);
}
}

将当前时间和fertilizer_pumpON定义为全局

unsigned long currentTime = 0;
unsigned long previousMillis = 0;   // stores last time relay was active(on)
unsigned long fertilizer_pumpON_interval = 10000; //(10s for testing)Time to turn ON fertilizer peristaltic pump to get required EC reading

然后在中

函数void fertilizer_PUMP((

if ((digitalRead (top_float) == floatDRY) 
&& (digitalRead (bottom_float) == floatWET) 
&& (currentTime - previousMillis <= fertilizer_pumpON_interval))

应该包括泵的状态-我想你只想输入如果开启泵关闭状态

if ((digitalRead (top_float) == floatDRY)  // CAN BOTH STATES BE AT THE SAME TIME??
&& (digitalRead (bottom_float) == floatWET) 
&& (currentTime - previousMillis <= fertilizer_pumpON_interval))

我降低到

if((millis() - previousMillis > fertilizer_pumpON_interval) 
&& fertilizer_pumpON == true) {//time is up and state is on stop pump
fertilizer_pumpON = false; // switch off
}
else if (PUMP_ON_condition == true && fertilizer_pumpON == false){ //check if we have to switch on
fertilizer_pumpON = true; // switch on
previousMillis  = millis(); // set timer to switch on time
setRelaytoON = true; // Use YOUR COMMAND/PIN whatever you need
}
else {
// DO NOTHING OR something while waiting or running use more ELSE IF if needed
}

总结

  • 运行到停止时检查状态和时间
  • 检查INIT命令/条件AND状态设置状态&定时器
  • 如果需要,检查是否紧急停止
  • 如果以上都不适用,就做某事/什么都不做

将long子句分解为单个部分,并检查状态是否一次可以有不同的值(逻辑错误(

if (A == true && A == false)  // YOU CAN NEVER ENTER THIS CLAUSE

EDIT按照您描述的方式实现逻辑(阅读代码中的注释!(添加行

bool fertilizer_pumpON = false;

在Setup((之前添加到全局变量,并用下面的代码替换void fertilize_PUMP((。提示:永远不要使用delay((-这会阻塞处理并使时间驱动的逻辑变得无用。

void fertilizer_PUMP() {
// If top float dry and bottom float wet > turn on both peristaltic pump for 10s(or more will change later) and stop  CODE STARTS HERE
if ((digitalRead (top_float) == floatDRY) && (digitalRead (bottom_float) == floatWET) &&  fertilizer_pumpON == false) {      //Turn on
Serial.print("t");
Serial.println(millis());
// delay (1000); // NEVER use delays or the whole logic wont work - delays BLOCK processing!
fertilizer_pumpON = true;
previousMillis = millis();
Serial.print("t");
Serial.println(F("Adding Fertilizer A and B"));
// delay (1000);
digitalWrite(relay_fertilizer_PUMPA, relayON);
digitalWrite(relay_fertilizer_PUMPB, relayON);
}
else if (fertilizer_pumpON == true && (millis() - previousMillis > fertilizer_pumpON_interval)) {    //Run for 10s then stop
digitalWrite(relay_fertilizer_PUMPA, relayOFF);
digitalWrite(relay_fertilizer_PUMPB, relayOFF);
fertilizer_pumpON = false;
Serial.println(F("Time elapsed"));
}
// If top float dry and bottom float wet > turn on both peristaltic pump for 10s(or more will change later) and stop  CODE STARTS HERE
// Then, if top float dry and bottom float dry > reset.   CODE ENDS HERE
else  if ((digitalRead (top_float) == floatDRY) && (digitalRead (bottom_float) == floatDRY && fertilizer_pumpON == true) ) {
digitalWrite(relay_fertilizer_PUMPA, relayOFF);
digitalWrite(relay_fertilizer_PUMPB, relayOFF);
fertilizer_pumpON = false;
Serial.println(F("Reset condition encountered"));
}
// Then, if top float dry and bottom float dry > reset.   CODE ENDS HERE
else {  // Wait for next top float dry and bottom float wet. 
Serial.println(F("Waiting ......"));  // use only for testing comment out afterwards
} 
}

代码的编译使得逻辑测试由您决定。

您可能需要更改从循环调用函数的方式:

定义全局变量unsigned long previousMillis=-1;然后在空环中((:

void loop()
{
if((digitalRead (top_float) == floatDRY) && (digitalRead (bottom_float) == floatWET))
{ //If your above condition is correct(means you are read to pour fertilizer)
if(previousMillis==-1)
previousMillis=millis();//Set time elapsed till now in global variable
if(previousMillis!=-1)
{
fertilizer_PUMP();//call function with a fixed previousMillis till millis()-previousMillis becomes 10s
}
}
}

然后在fertilizer_PUMP((中:

void fertilizer_PUMP()
{
boolean fertilizer_pumpON = false;
if (millis() - previousMillis <= fertilizer_pumpON_interval)) //Turn on for 10s
{
Serial.print("t");
Serial.println(currentTime);
delay (1000);//This delay is not required because your effective interval would be 5 seconds then(10/2)
//As you have a delay(1000) in the next if block too.
fertilizer_pumpON = true;
}
...

在相同的功能:

else
{
digitalWrite(relay_fertilizer_PUMPA, relayOFF);
digitalWrite(relay_fertilizer_PUMPB, relayOFF);
previousMillis=-1;//Wait for top float dry and bottom float wet, then set previousMillis
}

最新更新