esp32:capacity_measure
measure capacity for wires in order to detect water level. how mutch wires are submerged in water
#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);
}
esp32/capacity_measure.txt · Last modified: by aistis

