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%.
/* 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;
}