// C++ code
//********************** Управление наполнения бака водой биполярным реле Claber ********************************
//
// Скетч упавления биполярным клапаном реализован на кратковременной подачей на контакты соленоида
// напляжения 9-12в со сменой полярности.
// Подача напряжения управляется шилдом с 4-мя реле. Реле TIANDO HJR4102,контакты AgNi+Au, коммутация до 3А
// с напряжением до DC24В или AC125В. Подключение к МС через гальваноразвязку на p-n-p транзисторе - 
// срабатываjние реле digitalWrite (pin, LOW), отключение реле digitalWrite (pin, HIGH).
// Сменой полярности управляют пины 4 и 5 (реле 1 и 2). Пин6 (реле3) управляет стартом процесса.
// Параметры процесса в скетче определены как константы: cyclesV1 = 10; cycleLengthV2 = 150; igleV4 = 30
// и предполагают расход воды 500 л.
// Дальнейшее развитие кода предполагает управление
// этими параметрами. Управление МС реализуется сервисом Blynk.
// Скетч загружен в МС с настройками: "Плата": Arduino Uno.
// Для запуска выполнения скетча необходимо в сериал порт направить цыфру от 1 до 255.
// Это значение присвоется переменной cyclesV1 отвечающей за количество циклов наполнения и подастся команда на включение реле
// Для скетча не отладочного а рабочего при заливка в МК проконтролировать:
// - строка 30: скорость порта 115200 ( в соответствии со скоростью порта МК
// - строка 42: переменной cycleLengthV2 (продолжительность наполнения бака) присвоить значение в секундах = 150
// - строка 43: переменной idleV4 (время между циклами: концом предидущего цикла и началом следующего) присвоить значение в мин = 30
// - строка 100: в формуле delay(1000 * (idleV4 * 1)); поменять 1 на 60
//
//**************************************************************************************************************

int cyclesV1, cycleLengthV2, timeBalanceV3, idleV4, cycleBalanceV5, counter;
bool startStop;
byte relayPin[3] = {4,5,6};
uint32_t timer = 0;


void setup()
{
  Serial.begin(2400);
  while(!Serial)
  {}
  
  pinMode(4, OUTPUT); // Пин для подключения реле №1 смены полярности(включение реле: LOW);
  pinMode(5, OUTPUT); // Пин для подключения реле №2 смены полярности(включение реле: LOW);
  pinMode(6, OUTPUT); // Пин для подключения реле №3 Старт/Стопа(включение реле: LOW);
  
  //Начальное состояние реле-выключено (HIGH).
  //Гальванически развязаное оптопарой управление реле включает его сигналом LOW
  for(int i=0; i<3; i++) digitalWrite(relayPin[i], HIGH);

  //cycleLengthV2 = 2; //продолжительность наполнения бака
  //idleV4 = 2; // время между циклами: концом предидущего цикла и началом следующего
     
    Serial.println("VAL at start loop:");
    Serial.print("startStop  ");
    Serial.println(startStop);
    Serial.print("cyclesV1 = ");
    Serial.println(cyclesV1);
    Serial.print("cycleLengthV2 =");
    Serial.println(cycleLengthV2);
    Serial.print("idleV4 = ");
    Serial.println(idleV4);
    Serial.print("Serial now is  ");
    Serial.println(Serial.available());
    Serial.println();

  Serial.println("If you want some water, hurry up ENTER something");
}

void loop()
{
 if (Serial.available()>0)
  {
  char metka = Serial.read();
  int val=Serial.parseInt();
  Serial.println();
  Serial.print("Metka is  ");
  Serial.println(metka);
      switch(metka)
     {
       case 'a':
      startStop = val;
      break;
      
      case 'b':
      cyclesV1 = val;
      break;

      case 'c':
      cycleLengthV2 = val;
      break;

      case 'd':
      idleV4 = val;
      break;
     }
     Serial.print("a: startStop....... ");
     Serial.println(startStop);
     Serial.print("b: cyclesV1........ ");
     Serial.println(cyclesV1);
     Serial.print("c: cycleLengthV2... ");
     Serial.println(cycleLengthV2);
     Serial.print("d: idleV4.......... ");
     Serial.println(idleV4);
  }
   
  
  if (cyclesV1 && cycleLengthV2 && idleV4 > 0 && startStop == 1) 
  {
    cycleBalanceV5 = cyclesV1;
    Serial.println("VAL afte IF(compare):");
    Serial.print("startStop  ");
    Serial.println(startStop);
    Serial.print("cyclesV1 = ");
    Serial.println(cyclesV1);
    Serial.print("cycleLengthV2 =");
    Serial.println(cycleLengthV2);
    Serial.print("idleV4 = ");
    Serial.println(idleV4);
    Serial.print("time of process = ");
    Serial.println((cyclesV1 * (cycleLengthV2 + idleV4)));
    Serial.println();

      for (counter = 0; counter < cyclesV1; ++counter)
      {
        Serial.print("Cycle is ");
        Serial.println(cyclesV1-cyclesV1+counter+1);
        digitalWrite(6, LOW); // Включаем клапан
        delay(500); // кратковременное включение реле клапана: 500 millisecond(s)
        digitalWrite(6, HIGH);
        Serial.println("Valve is on");
        
        // Продолжительность потока определяет переменная cycleLengthV2.
        if(millis() - timer >= cycleLengthV2*1000)  // Wait for 1000 * cycleLengthV2 millisecond(s)
        {
        timer = millis();
        }
        
        // Меняем полярнось для выключения клапана
        digitalWrite(4, LOW);
        digitalWrite(5, LOW);
        Serial.println("Polarity is change");
        delay(1000); // задерживаемся на 1 с для гарантированного срабатывания реле

        // Выключаем клапан
        digitalWrite(6, LOW);
        delay(500); // Задержка 500 мс при подачи напряжения на саленоид клапана
        digitalWrite(6, HIGH);
        Serial.println("Valve is off");
        delay(1000); // Задержка для срабатывания реле клапана:1000 millisecond(s)
        
        // Возвращаем полярность для включения клапана
        digitalWrite(4, HIGH);
        digitalWrite(5, HIGH);
        
        // Расчет остатка процесса наполнения бака: циклов и общего времени 
        cycleBalanceV5 = --cycleBalanceV5;
        Serial.print("cycleBalance  = ");
        Serial.println(cycleBalanceV5);
        timeBalanceV3 = (cycleBalanceV5 * (cycleLengthV2 + idleV4));
        Serial.print("timeBalance =  ");
        Serial.println(timeBalanceV3);
        Serial.println();
        
        // Время простоя между циклами включения - переменная idleV4
        if(millis() - timer >= (idleV4 * 1)*1000) // Контроль формулы: 1000 * (idleV4 * 60) millisecond(s)
        {
        timer = millis();
        }
      } 
   startStop = 0;
   Serial.println("STOP"); 
   Serial.println("If you want anything...");
  }
}

  
  

  
uno:A5.2
uno:A4.2
uno:AREF
uno:GND.1
uno:13
uno:12
uno:11
uno:10
uno:9
uno:8
uno:7
uno:6
uno:5
uno:4
uno:3
uno:2
uno:1
uno:0
uno:IOREF
uno:RESET
uno:3.3V
uno:5V
uno:GND.2
uno:GND.3
uno:VIN
uno:A0
uno:A1
uno:A2
uno:A3
uno:A4
uno:A5
led1:A
led1:C
r1:1
r1:2
led2:A
led2:C
r2:1
r2:2
led3:A
led3:C
r3:1
r3:2