#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C LCD = LiquidCrystal_I2C(0x27, 16, 2);
// Tryb płukania
const int I2 = 35;
// Tryb pracy
const int I1 = 36;
// Minimalne ciśnienie na wejściu
const int I3 = 32;
// Maksymalne ciśnienie na wyjściu pompy wysokociśnieniowej (NWD)
const int I4 = 39;
// Minimalny poziom antyskalantu
const int I5 = 34;
// Maksymalny poziom permeatu
const int I6 = 14;
// CZERWONY - pompa wody
const int Q1 = 27;
// ZIELONY - zawór wejścia
const int Q2 = 26;
// ŻÓŁTY - zawór płukania
const int Q3 = 25;
// NIEBIESKI - zawór płukania permeatu
const int Q4 = 33;
// 0 - oczekiwanie, 1 - praca, 2 - płukanie, 3 - start pracy
int modeStatus = 0;
// int workMode = 0;
int gydroFlushingMode = 0;
// czujniki
int permiatMaxLevel = 0;
int antiscalantMinLevel = 0;
int pressureOutputPump = 0;
int pressureInput = 0;
// czas płukania hydrodynamicznego (sek.)
int timerGydroFlushing = 5;
// czas płukania permeatem (ms)
int timerFlushingPermiat = 3000;
// czas oczekiwania na ciśnienie na wejściu (sek.)
int timerInputPressure = 10;
// czas opóźnienia startu pompy wysokociśnieniowej (sek.)
int delayWaterPompStart = 3;
// licznik oczekiwania na ciśnienie na wejściu (sek.)
int counterInputPressure = 0;
// licznik oczekiwania na włączenie pompy (sek.)
int counterWaterPompStart = 0;
// licznik okresu płukania hydrodynamicznego (sek.)
int counterGydroFlushing = 0;
// licznik czasu pracy płukania hydrodynamicznego (sek.)
int counterGydroFlushingWork = 0;
// okres odczytu czujników (główna pętla) w ms
#define MY_PERIOD 1000
// okres włączenia płukania hydrodynamicznego w sek.
#define GYDRO_FLUSHING_PERIOD 10
// zmienna timera
uint32_t tmr1;
//uint32_t tmr2; // zmienna timera
void setup() {
Serial.begin(115200);
pinMode(I1, INPUT);
pinMode(I2, INPUT);
pinMode(I3, INPUT);
pinMode(I4, INPUT);
pinMode(I5, INPUT);
pinMode(I6, INPUT);
pinMode(Q1, OUTPUT);
pinMode(Q2, OUTPUT);
pinMode(Q3, OUTPUT);
pinMode(Q4, OUTPUT);
LCD.init();
LCD.setCursor(0, 0);
LCD.println("Status: Oczekiwanie");
}
void loop() {
// szukamy różnicy
if (millis() - tmr1 >= MY_PERIOD) {
// resetuj timer
tmr1 = millis();
int workMode = digitalRead(I1);
int flushingMode = digitalRead(I2);
// odczytaj ciśnienie na wejściu
pressureInput = digitalRead(I3);
// odczytaj ciśnienie na wyjściu pompy NWD
pressureOutputPump = digitalRead(I4);
// odczytaj minimalny poziom antyskalantu
antiscalantMinLevel = digitalRead(I5);
// odczytaj maksymalny poziom permeatu
permiatMaxLevel = digitalRead(I6);
// tryb pracy
// jeśli włączono tryb pracy
if (workMode == HIGH) {
// jeśli poziom antyskalantu jest wystarczający i poziom permeatu nie jest maksymalny
if (permiatMaxLevel == HIGH && antiscalantMinLevel == HIGH) {
// jeśli ciśnienie na wejściu jest wystarczające
if (pressureInput == HIGH) {
if (modeStatus != 1) {
startWork();
} else {
if (pressureOutputPump == LOW) {
if (gydroFlushingMode != 1) {
if (counterGydroFlushing < GYDRO_FLUSHING_PERIOD) {
counterGydroFlushing++;
Serial.println(counterGydroFlushing);
} else {
// włącz zawór płukania hydrodynamicznego
digitalWrite(Q3, HIGH);
// ustaw flagę płukania
gydroFlushingMode = 1;
LCD.setCursor(0, 1);
LCD.println("PLUKANIE HYDRO.");
}
} else {
if (counterGydroFlushingWork < timerGydroFlushing) {
counterGydroFlushingWork++;
Serial.println(counterGydroFlushingWork);
} else {
// wyłącz zawór płukania hydrodynamicznego
digitalWrite(Q3, LOW);
// usuń flagę płukania
gydroFlushingMode = 0;
// wyzeruj liczniki
counterGydroFlushing = 0;
counterGydroFlushingWork = 0;
LCD.clear();
LCD.setCursor(0, 0);
LCD.println("Status: PRACA");
}
}
} else {
// zatrzymanie z powodu wysokiego ciśnienia po pompie
LCD.clear();
LCD.setCursor(0, 0);
LCD.println("WYSOKIE CISN. I4");
}
}
} else {
// jeśli ciśnienie na wejściu spadło - wyłącz tryb pracy
modeStatus = 0;
// WYŁĄCZ POMPĘ !!!!!
if (counterInputPressure < timerInputPressure) {
counterInputPressure++;
LCD.clear();
LCD.setCursor(0, 0);
LCD.println("NISKIE CISN. I3");
Serial.println(counterInputPressure);
} else {
// wyłącz pompę NWD
digitalWrite(Q1, LOW);
// wyłącz zawór płukania hydrodynamicznego
digitalWrite(Q3, LOW);
// ustaw flagę oczekiwania
modeStatus = 0;
LCD.clear();
LCD.setCursor(0, 0);
LCD.println("BLAD CISN. I3");
}
}
// jeśli poziom antyskalantu lub permeatu jest za niski/wysoki
} else {
LCD.clear();
LCD.setCursor(0, 0);
if (permiatMaxLevel == LOW && antiscalantMinLevel == LOW) {
LCD.println("BLAD I5 i I6");
} else if (antiscalantMinLevel == LOW) {
LCD.println("BLAD I5");
} else {
LCD.println("BLAD I6");
}
}
// tryb płukania
} else if (flushingMode == HIGH) {
if (modeStatus != 2) {
// flushing();
}
// tryb oczekiwania
} else {
if (modeStatus != 0) {
counterInputPressure = 0;
waiting();
}
}
}
}
void startWork() {
// otwórz zawór WEJŚCIE
digitalWrite(Q2, HIGH);
// wyzeruj licznik oczekiwania na ciśnienie na wejściu
counterInputPressure = 0;
// opóźnienie przed włączeniem pompy NWD
if (counterWaterPompStart < delayWaterPompStart) {
counterWaterPompStart++;
LCD.clear();
LCD.setCursor(0, 0);
LCD.println("Status: CZEKAJ pompa");
} else {
// włącz pompę NWD
digitalWrite(Q1, HIGH);
// ustaw flagę PRACY
modeStatus = 1;
LCD.clear();
LCD.setCursor(0, 0);
LCD.println("Status: PRACA");
}
}
// void flushing() {
// modeStatus = 2;
// digitalWrite(Pin4, HIGH);
// delay(1000);
// digitalWrite(Pin5, HIGH);
// delay(1000);
// digitalWrite(Pin6, HIGH);
// LCD.clear();
// LCD.setCursor(0, 0);
// LCD.println("Status: Płukanie");
// delay(1000);
// }
void waiting() {
digitalWrite(Q1, LOW);
digitalWrite(Q2, LOW);
digitalWrite(Q3, LOW);
modeStatus = 0;
LCD.clear();
LCD.setCursor(0, 0);
LCD.println("Status: Oczekiwanie");
}
void stopMaxPermiat() {
digitalWrite(Q3, HIGH);
digitalWrite(Q2, LOW);
digitalWrite(Q4, HIGH);
delay(timerFlushingPermiat);
digitalWrite(Q1, LOW);
delay(5000);
digitalWrite(Q4, LOW);
delay(5000);
digitalWrite(Q3, LOW);
modeStatus = 0;
LCD.clear();
LCD.setCursor(0, 0);
LCD.println("Status: Oczekiwanie na poziom permeatu");
}
void spinner() {
static int8_t counter = 0;
const char* glyphs = "\xa1\xa5\xdb";
LCD.setCursor(15, 1);
LCD.print(glyphs[counter++]);
if (counter == strlen(glyphs)) {
counter = 0;
}
}
pompa wysokiego ciśnienia
zawór wejścia
zawór płukania hydrodynamicznego
zawór płukania permeatem
tryb płukania
I3
I4
I5
tryb pracy
I6