#define PIN_PH4502C 34 // measuring pH - PH-4502C sensor
#define VIN 3.3
#define PH_REF -5.7
#define PH_SAMPLES 10 // [x] pocet vzorku - prumerna hodnota
#define PH_SAMPLES_INTERVAL 1000 // [ms] perioda cteni senzoru
int PH_ARRAY[PH_SAMPLES]; // pamet pro prumernou hodnotu x poctu vzorku
int idxArrayPH = 0;
float reqPH = 6.4; // [-] required pH MEM
float actPH = 0.0; // [-] actual pH
int actPHv; // [V] analog pin voltage
float avgPH = 0.0; // [-] prumerna hodnota pH z x vzorku
float hysPH = 0.1; // [-] hysteresis for regulation
float minPH = 5.0; // [-] limit min pH MEM
float maxPH = 7.0; // [-] limit max pH MEM
// CO2
#define dKH 17.92 // [°] carbonate hardness MEM
float actCO2;
float minCO2 = 0.0; // limit min CO2
float maxCO2 = 400; // limit max CO2
bool firstPHSample = true;
unsigned long tmcPH; // [ms] pH measurement sampling cycle
// Kalibrace
#define PH_CAL_REF 6.86 // pH – hodnota pouzita jako referencni pri kalibraci
#define PH_DELAY_C_SAMPLES 500 // [ms] perioda cteni senzoru - kalibrace
#define PH_C_SAMPLES 7 // [x] pocet vzorku pri kalibraci
bool autoCalPH = false; // auto calibration – change calVal
bool autoCalPHM = false; // aut. kalibrace - pamet
unsigned long tmcPHC; // [ms] pH calibration sampling cycle
float calPH = 21.34; // [-] nastavit hodnotu pri kalibraci
bool a_PH_min, a_PH_max = false; // sensor PH-4502C (water) - pH
bool a_CO2_min, a_CO2_max = false;
long timeButton;
bool ButtonM = false;
#define LED 2
//----------------------------------------------+----------------------------------------------
void setup() {
Serial.begin(115200);
pinMode(27, INPUT_PULLUP);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
bool Button = (!digitalRead(27));
if (Button && !ButtonM) { // je-li ted stisknuto tlacitko
ButtonM = true;
timeButton = millis();
digitalWrite(LED, !digitalRead(LED)); // zmenit stav LED
autoCalPH = true;
}
else if (!Button && ButtonM && (millis() - timeButton) > 500) {
ButtonM = false;
}
readPH();
}
//----------------------------------------------+----------------------------------------------
// pH value - sensor PH-4502C
//----------------------------------------------+----------------------------------------------
//
void readPH() { // funkce cteni dat z PH-4502C
//----------------------------------------------+----------------------------------------------
// Automaticka kalibrace senzoru
//
if (autoCalPH) { // automaticka kalibrace -> start
if (autoCalPH && !autoCalPHM) {
autoCalPHM = true;
idxArrayPH = 0;
Serial.println("START kalibrace pH");
}
if (millis() - tmcPHC > PH_DELAY_C_SAMPLES) { // perioda cteni senzoru - kalibrace
tmcPHC = millis();
PH_ARRAY[idxArrayPH] = analogRead(PIN_PH4502C);// akt.hodnota pH senzoru do bufferu
Serial.println("Vstup : " + String(PH_ARRAY[idxArrayPH]));
idxArrayPH++;
if (idxArrayPH > PH_C_SAMPLES) { // kalibrace dokoncena -> vypocet kalibracni hodnoty "calPH"
calPH = -PH_REF * (getAverageValue(PH_ARRAY, PH_C_SAMPLES) * VIN / 4095.0) + PH_CAL_REF;
autoCalPH = false;
autoCalPHM = false;
// idxArrayPH = 0;
// for (int i = 0; i < PH_SAMPLES; i++) {
// PH_ARRAY[i] = actPHv;
// }
Serial.println("KONEC kalibrace calPH = " + String(calPH, 2));
}
}
}
//----------------------------------------------+----------------------------------------------
// Cteni hodnoty pH ze senzoru a vypocet mnozstvi CO2
//
if (millis() - tmcPH > PH_SAMPLES_INTERVAL && !autoCalPH) {
tmcPH = millis();
actPHv = analogRead(PIN_PH4502C); // vstupni hodnota = aktualni hodnota pH [mV]
if (firstPHSample) { // prvni cyklus -> napln buffer prvni zmerenou hodnotou
for (int i = 0; i < PH_SAMPLES; i++) {
PH_ARRAY[i] = actPHv;
}
firstPHSample = !firstPHSample;
} else { // cyklus mereni pH
if (idxArrayPH > PH_SAMPLES) { // pokud je max.pocet vzorku dosazen -> zacni od nuly
idxArrayPH = 0;
}
PH_ARRAY[idxArrayPH] = actPHv; // akt.hodnota pH do bufferu
idxArrayPH++;
actPH = PH_REF * (float)actPHv * VIN / 4095.0 + calPH; // aktualni pH
avgPH = PH_REF * (getAverageValue(PH_ARRAY, PH_SAMPLES) * VIN / 4095.0) + calPH; // prumer. hodnota
a_PH_min = (actPH < minPH); // prekrocen horni limit pH
a_PH_max = (actPH > maxPH); // prekrocen horni limit pH
// CO2 calculation; (pow function instead of "10^6,37-phValue",
// whitch is not defined in Wiring language
actCO2 = 12.84 * dKH * pow(10, (6.37 - avgPH));
a_CO2_min = actCO2 < minCO2;
a_CO2_max = actCO2 > maxCO2;
Serial.print("Vstup " + String(actPHv));
Serial.print(" pH " + String(actPH, 2));
Serial.print(" ø " + String(avgPH, 2));
Serial.println(" CO2 " + String(actCO2));
}
}
}
float getAverageValue(int* ARRAY, int AVG_ARRAY_SIZE) { // vrati prumernou hodnotu
float AMOUNT = 0;
if (AVG_ARRAY_SIZE <= 0){
Serial.println("ERROR!/n");
return 0;
}
for (byte i = 0; i < AVG_ARRAY_SIZE; i++) {
AMOUNT += ARRAY[i];
}
return (AMOUNT / AVG_ARRAY_SIZE);
}