User Tools

Site Tools


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