Кіші сыйымдылықты тіркеу

Мен мультиметр арқылы жүйенің сыйымдылығын өлшеп жатырмын және мән өте аз (50pF-тен 100 pF-ге ауытқу) екенін анықтадым. Жүйе динамикалық, сондықтан сыйымдылық уақыт бойынша өзгереді.

Енді осы мәнді кейбір мәтіндік файлға (мысалы, csv) тіркеу керек. Мұны Ардуиномен қалай жасауға болады? Егер қарсылық болса, мен қарапайым кернеу бөлгішті сала аламын және ADC арқылы кернеуді сезіндім. Сондай-ақ C өте аз, мен C үшін кейбір өлшеу тізбегін құра алмадым.

5
Бұл сыйымдылығы сезімтал қосымшасы.
қосылды автор roetnig, көзі
Қанша дәлдік қажет? Сізге сыйымдылықты дәл өлшеу керек немесе сапар жағдайын анықтау жеткілікті ме? Сіздің өтінішіңіз қандай?
қосылды автор Arperum, көзі

6 жауаптар

The standard way to measure a resistance with an Arduino is to build a voltage divider by putting it in series with a known resistance. I have tried the same approach for measuring capacitances, and it turns out it works well in the 100 pF range! The circuit is like this:

  ┌───────────── Arduino digital output
  │
──┴── known
──┬── cap
  │
  ├───────────── Arduino analog input
  │
──┴── unknown
──┬── cap
  │
 GND

Жалғыз пойыз - бұл өлшемді салыстырмалы түрде жылдам орындау керек, әйтпесе Сіз ағып кетудің кедергісінің қатынасын өлшеп отырасыз. Өлшеу протоколы:

  1. Set both pins to OUPUT LOW in order to discharge both capacitors.
  2. Delay for one or two CPU cycles to make sure they are fully discharged.
  3. Set the analog input pin to INPUT mode: this will make it high impedance and isolate the node connected to it.
  4. Set the digital output to HIGH: this will charge the two capacitors in series to 5 V.
  5. Delay for one or two CPU cycles for the voltage to stabilize.
  6. Take an analog reading.

Енді сіз сыйымдылықты оқудан бірдей пайдалана аласыз резисторлармен қолданылатын формула, тек impedances (немесе, жай 1/С) кедергілердің орнына:

C_unknown = C_ref × (1024 − reading) ÷ reading;

Сол формуланы түйін қосылғанымен ескере отырып алуға болады әр конденсатордың бір табақшасын қамтитын аналогтық енгізуге ие нөлдік таза төлем.

Айта кету керек, бірнеше нәрсе:

  • You will get the best resolution by choosing the reference capacitance close to the one you want to measure.
  • The delays are not actually needed: as the capacitors charge and discharge very fast, a single CPU cycle is about 24 time constants.
  • If you were to measure large capacitances (several nanofarads) with this setup, you would want protective resistors in series with the Arduino pins, but then the delays become mandatory. In the 100 pF range I would not worry about the in-rush currents.
  • If the delay in step 5 is too long, your measurement will be affected by the leakage of the caps and the analog input pin.
  • You need not worry about the 14 pF cap on the sample and hold circuit: it will slightly affect the very first measurement but, once that cap is charged, subsequent measurement will not be affected as long as the unknown cap does not change to much between consecutive measurements. You do need to calibrate out the stray capacitance of the pin and probes.
2
қосылды

RC тұрақты бағалау арқылы кіші сыйымдылықты өлшеу айтарлықтай уақытты нақты өлшеуді талап етеді. ATmega чиптерінде әрбір сағаттық циклді ұлғайту үшін бағдарламаланатын TCNT1 таймері бар, және ACSR тізбесінде ACIC арқылы бітуге болады. 16 МГц жиіліктегі контроллерді іске қосу сізге 62,5 нс рұқсат береді, бұл пикофарад ауқымында сыйымдылықты өлшеу үшін жеткілікті. Мұнда пайдаланатын кодтың мысалы өлшеу әдісі.

AnalogRead is about 1000 times slower, so you'll be limited to nF range if you use it.

Осындай шағын сыйымдылықты өлшеу кезінде сіздің жүйеңізді калибрлеу керек екенін ескеріңіз. Бұл сіздің зондтарыңызбен , бірақ мақсатты жүйемен өлшеуді орындау арқылы жасалады. Сіз өзіңіздің жүйеңіздегі сыйымдылықты алу үшін осы шамадан тыс өлшемдеріңізден осы сыйымдылықты (әдетте 20-50 фунт, сіз пайдаланатын зондтарға байланысты) шегеріңіз.

2
қосылды

PF ретінде аз сыйымдылық үшін, RC уақытша тұрақты әдісі Arduino тақтасына кір нәтижесін береді.

Сіз «сыйымдылықты бөлгіш» тізбегін құру үшін шағын көлемде салынған (Pf-тің өзі) салынған Arduino түйреуіштерін пайдалана аласыз және сіз кернеуді бөлгіш тізбектің қарсыласуымен салыстыра аласыз.

See this excellent post by Nethercott for reference Arduino capacitance meter

1
қосылды
Рахмет :-) Сенің дұрыс деп ойлаймын, бірақ мен бұл әдісті өз шегіне дейін соза алмадым. Менің тәжірибемнен бастап, Arduino Uno тақтасын және күнделікті ортада 15 см ұзындықты секіргіш сымдармен қанағаттанарлық нәтижелерді шығара алдым.
қосылды автор christoff, көзі
Жақсы табу, + 1! Паразиттік пин сипаттамаларына негізделгендіктен, бұл әдіс қалай дәл болып көрінетініне таң қаламын. Менің ойымша, бұл жақсы EMI экрандауымен немесе EMI ​​жағдайында ғана жақсы жұмыс істейді деп ойлаймын.
қосылды автор nreich, көзі

(50 pF-тан 100 pF-ге дейін ауытқу).

a few ways for such small values -> assuming you can really read it like a capacitor.

1) form a lc tank and measure its frequency -> most effective in measuring small value capacitance. but needs precision inductor/calibration, and is subject to parasitics.

2) ОКҚ арқылы оны зарядтаңыз/шығарыңыз: уақытты өлшеңіз. ең кіші дисктер арқылы үлкен қарсылық арқылы құрылуға болады. шын мәнінде шағын сыйымдылықпен тиімді емес;

3) charge transfer: using the capacitance of the adc. very effective against small capacitance: < 10x of adc capacitance. needs calibration.

әрқайсысының өз проблемалары бар.

1
қосылды
CCS дегеніміз не ??
қосылды автор nreich, көзі

Өлшенетін сыйымдылық 1 НФ (50-100 фунт) төмен болғандықтан, оның кіріс сыйымдылығы (деректер кестесіне сәйкес 14 фунт) болғандықтан, оны Arduino компаниясының АЦП-мен өлшеуге тырысады. Сымдардың, тақырыптардың және Arduino тақтасының өз бетімен шығатын сыйымдылығын қосыңыз және сіз өлшеуге тырысатын нәрсеңіздің шамасы (= ӨТЕ ҚҰРЫЛҒЫ) сияқты 25 фунт кіріс сыйымдылығымен оңай аяқталады.

Сонда не істеу керек? Ал, негізгі нұсқалар - бұл ...

Сыртқы өлшеу тізбегін пайдаланыңыз

Бұл белсенді құрылғыларды (ампер ампер, компаратор, таймер ...) және нақты пассивті компоненттерді қосады. HW негізіндегі нақты шешім.

Бұл жағдайда өлшеу дәлдігі сыртқы тізбектің конструкциясына (тізбектің топологиясы және компоненттерін таңдау) толығымен дейін жетеді. Схема аналогтық кернеуді немесе сигналды қамтамасыз етеді, оның жиілігі кез-келген қосымша маңызды қателерді енгізбестен Ардуино тарапынан өлшенуі мүмкін.

555 таймерді қолданатын мысал (жақсартылған дәлдік үшін OUT және TH арасында қосымша 4 фФ компенсациялық конденсатор қажет):

555 timer capacitance meter

Frequency vs capacitance

Source: Use Analog Techniques To Measure Capacitance In Capacitive Sensors, an article by Martin Tomasz published in Electronic Design.

Сыртқы тізбекті «сенсор» немесе «сенсор» үшін сигнал беру контуры ретінде қарастырыңыз (өлшенетін сыйымдылық). Шын мәнінде өлшеуге тырысатын динамикалық сыйымдылық сенсордан (ылғалдан, ылғалдылықтан) келеді, солай емес пе?

Конденсаторды Uno аналогтық сымдарына тікелей қосып, оқылымды калибрлеңіз

Бұл таңғажайып көрінуі мүмкін, бірақ бұл қалай жұмыс істейтіні соншалықты қарапайым (әрине дәлдіктің есебінен):

Uno as capacitance meter

Ол қалай? Бастапқыда анықталған кіріс сыйымдылығының мәселесі дәлдікті айтарлықтай төмендетуге жеткілікті үлкен, бірақ өлшеуді мүлдем жарамсыз етеді. Осылайша, біз бұл нәтижені калибрлай аламыз және мақсатты диапазонда (50-100 фунт) төменгі дәлдікпен өлшеуге болады.

Калибрлеу келесі Arduino эскизіндегі кейбір қатты кодталған әдепкі мәндер арқылы жүзеге асырылады (brauio777-дан here ). Жақсы нақтылық үшін кейбір конденсаторларды өлшеуді әлдеқашан белгілі сыйымдылық мәндерімен салыстыру арқылы (егер сіз мұны жасасаңыз), IN_STRAY_CAP_TO_GND және R_PULLUP мәндерін калибрлеуіңіз керек.

//Digital Capacitance Meter
//Measuring from 0.000pF to 1000uF

#include 
LiquidCrystal lcd(11, 9, 5, 4, 3, 2);
const int OUT_PIN = A4;
const int IN_PIN = A0;
const float IN_STRAY_CAP_TO_GND = 24.48;
const float IN_CAP_TO_GND  = IN_STRAY_CAP_TO_GND;
const float R_PULLUP = 34.8;  
const int MAX_ADC_VALUE = 1023;

void setup()
{
  pinMode(OUT_PIN, OUTPUT);
  pinMode(IN_PIN, OUTPUT);
  lcd.begin(16, 2);
  }

void loop()
{
    pinMode(IN_PIN, INPUT);
    digitalWrite(OUT_PIN, HIGH);
    int val = analogRead(IN_PIN);
    digitalWrite(OUT_PIN, LOW);

    if (val < 1000)
    {
      pinMode(IN_PIN, OUTPUT);

      float capacitance = (float)val * IN_CAP_TO_GND/(float)(MAX_ADC_VALUE - val);

      lcd.setCursor(0,0);
      lcd.print("Capacitance = ");
      lcd.setCursor(0,1);
      lcd.print("                ");
      lcd.setCursor(0,1);
      lcd.print(capacitance, 3);// for the best precision
      lcd.print("pF ");

    }

    else
    {
      pinMode(IN_PIN, OUTPUT);
      delay(1);
      pinMode(OUT_PIN, INPUT_PULLUP);
      unsigned long u1 = micros();
      unsigned long t;
      int digVal;

      do
      {
        digVal = digitalRead(OUT_PIN);
        unsigned long u2 = micros();
        t = u2 > u1 ? u2 - u1 : u1 - u2;
      } 

      while ((digVal < 1) && (t < 400000L));

      pinMode(OUT_PIN, INPUT);  
      val = analogRead(OUT_PIN);
      digitalWrite(IN_PIN, HIGH);
      int dischargeTime = (int)(t/1000L) * 5;
      delay(dischargeTime);   
      pinMode(OUT_PIN, OUTPUT);  
      digitalWrite(OUT_PIN, LOW);
      digitalWrite(IN_PIN, LOW);

      float capacitance = -(float)t/R_PULLUP
                             /log(1.0 - (float)val/(float)MAX_ADC_VALUE);

      lcd.setCursor(0,0);
      lcd.print("Capacitance = ");
      if (capacitance > 1000.0)
      {
        lcd.setCursor(0,1);
        lcd.print("                ");
        lcd.setCursor(0,1);
        lcd.print(capacitance/1000.0, 2);
        lcd.print("uF ");

      }

      else
      {
        lcd.setCursor(0,1);
        lcd.print("                ");
        lcd.setCursor(0,1);
        lcd.print(capacitance, 2);
        lcd.print("nF ");

      } 

    while (millis() % 1000 != 0);
}
    }

Жоғарыдағы мысалдың коды LCD-дисплейге өлшенген мәндерді шығарады. Сіздің мақсатты қолданысыңыз үшін ең жақсы опция деректерді сыртқы SD картасына жазу болып табылады.

Disclosure: I have not tested the code above myself.

1
қосылды

Әрбір Arduino сыйымдылығы есептегіш резисторлық конденсатордың (RC) тізбектерінің сипатына негізделген - уақыттың тұрақты мәні. RC тізбегінің уақытша константасы конденсатордың кернеуіне толық зарядталған кезде оның кернеуінің 63,2% -на жету уақыты ретінде анықталады. Үлкен конденсаторлар зарядтауға ұзағырақ уақыт кетеді, сондықтан үлкен уақытты тұрақтандырады. RC тізбегіндегі сыйымдылық теңдеу арқылы уақытты тұрақтыға қатысты:

TC = R x C

where TC = time constant in seconds R = resistance in ohms C = capacitance in farads

Қуаттылықты шешу үшін теңдеуді қайта құру:

C = TC/R

schematic

simulate this circuit – Schematic created using CircuitLab

Example: 1 megohm * 1 microfarad = 1 second enter image description here

Әрбір сыйымдылықты өлшеуіште белгілі резисторлық мәндер және белгісіз конденсатордың мәні бар RC тізбегі бар. Arduino кернеуді конденсатордағы өлшейді және оны толығымен зарядталған кезде (уақытша тұрақты) 63,2% -ға жету үшін уақытты жазып алады. Қарсылық мәні белгілі болғандықтан, жоғарыда көрсетілген формуланы белгісіз сыйымдылықты есептейтін бағдарламада қолдануға болады.

Сіздің Capacitance Pico Farad Range-де тым кішкентай болғандықтан, дәл осындай аналогтық арқау арқылы Capacitance мүмкіндігін тікелей өлшеуге болады ... «Схема» Сіз конденсатордың динамикалық сипатта екендігін айттыңыз, сондықтан сіз 10 мәнді қабылдап, нақты мәнді алу үшін орташа мәнге ие боласыз.

Өлшеудің коды PF диапазонында төмен сыйымдылық

const int OUT_PIN = A5;
const int IN_PIN = A0;
const float IN_STRAY_CAP_TO_GND = 24.48;
const float IN_CAP_TO_GND  = IN_STRAY_CAP_TO_GND;
const float R_PULLUP = 34.8;  
const int MAX_ADC_VALUE = 1023;

void setup()
{
  pinMode(OUT_PIN, OUTPUT);
  pinMode(IN_PIN, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
    pinMode(IN_PIN, INPUT);
    digitalWrite(OUT_PIN, HIGH);
    int val = analogRead(IN_PIN);
    digitalWrite(OUT_PIN, LOW);

    if (val < 1000)
    {
      pinMode(IN_PIN, OUTPUT);

      float capacitance = (float)val * IN_CAP_TO_GND/(float)(MAX_ADC_VALUE - val);

      Serial.print(F("Capacitance Value = "));
      Serial.print(capacitance, 3);
      Serial.print(F(" pF ("));
      Serial.print(val);
      Serial.println(F(") "));
    }
    else
    {
      pinMode(IN_PIN, OUTPUT);
      delay(1);
      pinMode(OUT_PIN, INPUT_PULLUP);
      unsigned long u1 = micros();
      unsigned long t;
      int digVal;

      do
      {
        digVal = digitalRead(OUT_PIN);
        unsigned long u2 = micros();
        t = u2 > u1 ? u2 - u1 : u1 - u2;
      } while ((digVal < 1) && (t < 400000L));

      pinMode(OUT_PIN, INPUT);  
      val = analogRead(OUT_PIN);
      digitalWrite(IN_PIN, HIGH);
      int dischargeTime = (int)(t/1000L) * 5;
      delay(dischargeTime);   
      pinMode(OUT_PIN, OUTPUT);  
      digitalWrite(OUT_PIN, LOW);
      digitalWrite(IN_PIN, LOW);

      float capacitance = -(float)t/R_PULLUP
                             /log(1.0 - (float)val/(float)MAX_ADC_VALUE);

      Serial.print(F("Capacitance Value = "));
      if (capacitance > 1000.0)
      {
        Serial.print(capacitance/1000.0, 2);
        Serial.print(F(" uF"));
      }
      else
      {
        Serial.print(capacitance, 2);
        Serial.print(F(" nF"));
      }

      Serial.print(F(" ("));
      Serial.print(digVal == 1 ? F("Normal") : F("HighVal"));
      Serial.print(F(", t= "));
      Serial.print(t);
      Serial.print(F(" us, ADC= "));
      Serial.print(val);
      Serial.println(F(")"));
    }
    while (millis() % 1000 != 0)
      ;    
}
1
қосылды
-1: Бұл әдіс мұндай кішкентай сыйымдылықтарға шын мәнінде жарамайды: сіз қарсыластың үлкен қарсыласу құндылығына қажет боласыз, әйтпесе уақытты өлшеу жақсы өлшеу үшін тым қысқа болар еді. Егер сіз RC уақытты тұрақты өлшеуді орындағыңыз келсе, Дмитрий Григорьевтің жауабында сипатталған әдісті қолданыңыз.
қосылды автор Sprogz, көзі
Сіз «идея», содан кейін осы идеядан өзгеше нәрсе жасайтын код бөлігін бердіңіз. Егер сіз бұл кодты жасасаңыз, неге шын мәнінде бұл әрекетті түсіндірмейсіз? Егер жоқ болса, неліктен түпнұсқа авторға несие бермейсіз?
қосылды автор Sprogz, көзі
Ал ардуино штырмалардың жүктеме сыйымдылығы туралы не деуге болады?
қосылды автор Arperum, көзі
ATmega328 деректер парағының деректері бойынша бұл шамамен 14 фунт. Жайлылық үшін өлшеу ауқымына тым жақын. Сондай-ақ, сымдар мен Uno тақтасына және тақырыптарға байланысты кез-келген өтетін сыйымдылық.
қосылды автор Arperum, көзі
Иә сіз дұрыссыз. Бірақ мен оның дәмін татып, соншалықты дәл және дәл емес, қанағаттанарлық нәтиже беремін. Салқын досым, оған проблема шешімдерін емес, жалпыланған идеяны бердім.
қосылды автор Inky1980, көзі