measure capacity for wires in order to detect water level. how mutch wires are submerged in water {{:esp32:pasted:20250921-172035.png}} #define CAP_PIN 34 // ADC input-only #define DRIVE_PIN 25 // per 10 MΩ (RC matavimas) #define FAST_PIN 27 // tiesiogiai į ● greitam pre-charge/discharge #define R_OHMS 10000000.0 // 10 MΩ const int THRESH_ADC = 2000; // ~1.6 V (matavimo slenkstis) const int ADC_LOW_FAST = 150; // ~artima 0 V (fast discharge) const int ADC_HIGH_FAST = 3900; // ~artima Vcc (fast charge) const unsigned long TIMEOUT_US = 3000000UL; // matavimo saugiklis const unsigned long TIMEOUT_FAST_US= 20000UL; // fast fazės saugiklis (~20 ms) const int N_SAMPLES = 100; void setup() { Serial.begin(115200); analogSetAttenuation(ADC_11db); pinMode(DRIVE_PIN, INPUT); // Hi-Z pinMode(FAST_PIN, INPUT); // Hi-Z } // Greitas iškrovimas iki beveik 0 V, be fiksuoto delay bool fast_discharge_until() { pinMode(FAST_PIN, OUTPUT); digitalWrite(FAST_PIN, LOW); unsigned long t0 = micros(); int v; do { v = analogRead(CAP_PIN); if (micros() - t0 > TIMEOUT_FAST_US) { // saugiklis pinMode(FAST_PIN, INPUT); return false; } } while (v > ADC_LOW_FAST); pinMode(FAST_PIN, INPUT); // Hi-Z, kad netrukdytų matavimui return true; } // Greitas pakrovimas iki beveik Vcc, be fiksuoto delay bool fast_charge_until() { pinMode(FAST_PIN, OUTPUT); digitalWrite(FAST_PIN, HIGH); unsigned long t0 = micros(); int v; do { v = analogRead(CAP_PIN); if (micros() - t0 > TIMEOUT_FAST_US) { pinMode(FAST_PIN, INPUT); return false; } } while (v < ADC_HIGH_FAST); pinMode(FAST_PIN, INPUT); // Hi-Z return true; } unsigned long measure_rise_us() { if (!fast_discharge_until()) return 0; // 0 V startas pinMode(DRIVE_PIN, OUTPUT); digitalWrite(DRIVE_PIN, HIGH); // kraunam per 10 MΩ unsigned long t0 = micros(); while (analogRead(CAP_PIN) < THRESH_ADC) { if (micros() - t0 > TIMEOUT_US) { pinMode(DRIVE_PIN, INPUT); return 0; } } unsigned long dt = micros() - t0; pinMode(DRIVE_PIN, INPUT); // Hi-Z return dt; } unsigned long measure_fall_us() { if (!fast_charge_until()) return 0; // Vcc startas pinMode(DRIVE_PIN, OUTPUT); digitalWrite(DRIVE_PIN, LOW); // iškraunam per 10 MΩ unsigned long t0 = micros(); while (analogRead(CAP_PIN) > THRESH_ADC) { if (micros() - t0 > TIMEOUT_US) { pinMode(DRIVE_PIN, INPUT); return 0; } } unsigned long dt = micros() - t0; pinMode(DRIVE_PIN, INPUT); // Hi-Z return dt; } void loop() { // Pastovūs koeficientai (k = Vth/Vcc) const double k = 2000.0/4095.0; const double a_up = -log(1.0 - k); // ≈ 0.673 (kilimas) const double a_dn = -log(k); // ≈ 0.717 (kritimas) // Vidurkinimas per N_SAMPLES double sum_tr = 0, sum_tf = 0, sum_C = 0; int ok = 0; for (int i = 0; i < N_SAMPLES; i++) { unsigned long tr = measure_rise_us(); unsigned long tf = measure_fall_us(); if (tr == 0 || tf == 0) { // praleidžiam timeout'ą continue; } double C_up_F = (tr * 1e-6) / (R_OHMS * a_up); double C_dn_F = (tf * 1e-6) / (R_OHMS * a_dn); double C_pF = (C_up_F + C_dn_F) * 0.5 * 1e12; sum_tr += tr; sum_tf += tf; sum_C += C_pF; ok++; } pinMode(12, INPUT); analogSetAttenuation(ADC_11db); pinMode(14, OUTPUT); digitalWrite(14, LOW); delay(10); double battery_voltage = analogRead(12)/4095.0 * 4.2; pinMode(14, INPUT); if (ok > 0) { double avg_tr = sum_tr / ok; double avg_tf = sum_tf / ok; double avg_CpF = sum_C / ok; // CSV: tr_us,tf_us,C_pF Serial.printf("%.0f,%.0f,%.1f,%.1f\n", avg_tr, avg_tf, avg_CpF, battery_voltage); } else { Serial.println("0,0,NaN"); // jei visi matavimai suvažiavo į timeout } //delay(800); }