Go Down

Topic: Capacimètre spécial petites capacités, de 0,1 à 100 pF (Read 1 time) previous topic - next topic

ChristopheFr

Bonjour,
Je vous propose en partage mon capacimètre destiné à la mesure de faibles capacités.

Pourquoi?
Il existe déjà des capacimètres Arduino!
Cependant ils ont tous en commun de ne pas être efficace en dessous d'une dizaine de pF.
Ce capacimètre a donc été conçu pour y remédier.
Pour les capacités supérieures à 100pF vous pourrez utiliser un de ceux-là:
http://www.circuitbasics.com/how-to-make-an-arduino-capacitance-meter/

Ils utilisent d'autres algorithmes mieux adaptés aux capacités plus élevées (analogueRead).
Voir le tableau pour choisir le mieux adapté en fonction des capacités à mesurer.

Ce capacimètre permet la mesure de petites capacités de l'ordre du picoFarad avec une précision d'environ 3% avec un bon calibrage. Ce qui est difficile à obtenir avec un capacimètre du commerce (du moins je n'en connais pas, d'où ce programme).

Son domaine d'application concerne essentiellement la mesure des capacités parasites sur les circuits H.F.

L'étalonnage se fait en ajustant la constante K. Après après avoir soustrait l'offset avec la touche "c" on teste un condensateur de 100pF étalonné. Si la valeur lue est inférieure à la valeur réelle, on augmente la valeur de K et inversement.
Sans étalonnage, la précision est de l'ordre de 5%.

Code: [Select]

/* Capacimètre spécial faibles valeurs, de 0,1 à 100pF
 * Auteur Christophe JUILLET
 * 
 * A0 broche de lecture du condensateur
 * A1 broche de charge du condensateur
 *
 * Le condensateur est relié à la masse et à la broche A0
 * La résistance R1 est reliée à la broche A0 et à la broche A1
 * Les broches doivent être A0 et A1
 *
 * seuil = 1-(1/e^c) où c est la constante de temps
 * constante de temps = ln (1-Vseuil/VCC) où Vseuil est la tension de bascule
 */

#define R1  2200 // résistance de charge en KiloOhm (entre 1,5 et 3,3MOhm) compromis idéal à 2,2MOhm
#define K 0.059 // K = 0.059 coefficient correspondant à une constante de temps de 0,693 (seuil à 0,5*VCC) à ajuster pour calibrage

void setup() {
  Serial.begin(115200);
  TCCR1A = 0; // Timer 1 en mode compteur
  TCCR1B = 1; // prédiviseur du timer 1 à 1
  pinMode(A1, OUTPUT);
  Serial.println(F("Tapez \"0\" pour lire la valeur du condensateur\n\"c\" pour calibrer le capacimetre (a vide)\n\"p\" pour une mesure precise\n\"r\" pour une mesure rapide (par defaut)"));
}

void loop() {
  static long offset = 0;
  static unsigned imax = 2048;
  static bool precis = false;
  static float c; // capacité en pF
 
  if (Serial.available()) {
    char touche = Serial.read();
    if (touche == '0') {
      digitalWrite(A1, HIGH);
      delayMicroseconds(400); // test dépassement de capacité
      bool over = !digitalRead(A0);
      digitalWrite(A1, LOW);
      if (over) {
        Serial.println(F("Capacite superieure a 100pF"));
      }
      else {
        long tt = mesure(imax);         
        precis ? tt >>= 2 : tt <<= 1;
        c = (tt - offset) / (float) R1 * K;
        Serial.print(c, precis ? 2 : 1);
        Serial.println("pF");
      }
    }
    if (touche == 'c') {
      Serial.println(F("Calibrage offset en cours..."));
      offset = mesure(65536L);
      offset /= 16;     
      c = offset / (float) R1 * K;
      Serial.print(F("Capacite parasite: "));
      Serial.print(c, 2);
      Serial.println("pF");
    }
    if (touche == 'p') {
      imax = 16384;
      precis = true;
      Serial.println("Mode precis");
    }
    if (touche == 'r') {
      imax = 2048;
      precis = false;
      Serial.println("Mode rapide");
    }
  }
}

long mesure(long imax) {
  long tt = 0;
  int t;

  pinMode(A0, OUTPUT);
  delayMicroseconds(100); // vider le condensateur
  for (long i = 0; i < imax; i++) { // on répète la mesure afin d'améliorer la précision
    pinMode(A0, INPUT);
    byte oldSREG = SREG;
    cli();
    bitSet(PORTC, 1); // broche A1 HIGH
    TCNT1 = 0;
    asm volatile(
      "boucle:\n" // 3 cycles horloge
      "sbis 0x06, 0\n" // PINC 0 broche A0
      "rjmp boucle\n"
    );
    t = TCNT1;
    SREG = oldSREG;
    digitalWrite(A1, LOW); // vider le condensateur
    pinMode(A0, OUTPUT);
    tt += t / 3;
  }
  pinMode(A0, INPUT);
  return tt;
}





bricofoy

merci pour le partage, ça semble un projet fort utile ;)
-tu savais que si tu passe le CD de windows à l'envers, tu entends une chanson satanique ?
-non, mais il y a pire : à l'endroit, ça l'installe !

Go Up