Включите реле насоса перистальти c на x времени, используя миллис - PullRequest
0 голосов
/ 07 апреля 2020

Это мой самый первый код в Arduino. Я пытаюсь построить простую систему полива для моего сада. Код содержит 3 основные функции:

  1. Для наполнения бака для удобрений водой.
  2. Для добавления удобрения в резервуар для воды, в то время как вода, добавляемая с допущением, будет смешиваться с удобрениями. process.
  3. К автоматическому процессу полива в течение дня.

Для 1-й и 3-й функции, я уже сделал это (теоретически + система малого масштаба), я думаю. ха-ха!

Теперь, для функции удобрения № 2 (удобрение_PUMP ()), я использую 2 насоса peristalti c, чтобы добавить растворы удобрений AB в бак. Я пытаюсь заставить насос работать в течение x раз, но функция запускается только один раз, после этого l oop необходимо сбросить, если оба поплавковых переключателя станут dry и дождаться, пока нижний переключатель снова станет влажным. Может ли кто-нибудь помочь и направить меня, какую часть я пропустил? Я открыт для любых предложений по улучшению моего кода. Спасибо.

ОБНОВЛЕНИЕ:

Мне очень жаль, что я запутался. Собственно для этой функции ниже приведены мои требования.

  1. Если верхний поплавок dry и нижний поплавок мокрые> включить насос перистальти c на 10 с (или более изменится позже) и остановиться.
  2. Затем, если верхний float dry и нижний float dry> reset.
  3. Ожидание следующего верхнего float dry и нижнего float wet.

Мне очень жаль снова за путаницу. Кинда напутала с логикой c ранее.

#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);

  }
}

Ответы [ 2 ]

1 голос
/ 07 апреля 2020

Определите ваш currentTime и silkizer_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 Удобрение_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 И состояние установки состояния и таймер
  • Проверка аварийного останова, если необходимо
  • сделать что-нибудь / ничего, если ничего из вышеперечисленного применяется

Разбить длинное предложение на отдельные части и проверить, могут ли состояния иметь разные значения за раз (логическая ошибка)

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

РЕДАКТИРОВАТЬ Реализовано логика c, как вы описали (читайте комментарии в коде!) Добавьте строку

bool fertilizer_pumpON = false;

перед установкой () в глобальные переменные и замените void ferizer_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
  } 
}

Код компилируется, поэтому тестирование логики c остается за вами.

0 голосов
/ 07 апреля 2020

Возможно, вы захотите изменить способ вызова функции с l oop:

Определить глобальную переменную unsigned long previousMillis = -1; Затем в пустоте l oop ():

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
   }
  }
}

Затем в удобрении_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
   }
...