Уваход невялікі ёмістасці

Я вымярэнне ёмістасці сістэмы з дапамогай універсальнага вымяральнага прыбора, і выявіў, што велічыня вельмі малая (вагацца ад 50пФа да 100 пФов). Сістэма з'яўляецца дынамічнай, так што ёмістасць змяняецца з цягам часу.

Цяпер мне павінны ўвайсці ў гэта значэнне ў нейкай тэкставы файл CSV (напрыклад). Як я магу зрабіць гэта з Arduino? Калі гэты супраціў, я мог бы пабудаваць просты дзельнік напругі і пачуццё напругі з дапамогай АЛП. Акрамя таго, З з'яўляецца вельмі маленькім, я не змог пабудаваць некаторую вымяральную схему для 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.

Цяпер вы можаце атрымаць ёмістасць ад чытання з выкарыстаннем таго ж формула вы будзеце выкарыстоўваць рэзістары, толькі з імпеданс (ці проста 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 таймер, які можа быць запраграмаваны для павелічэння кожнага тактавага цыклу, і можа быць спынены кампаратар, выкарыстоўваючы біт ACIC у ACSR рэгістры. Запуск лічыльніка на 16 МГц дасць вам дазвол 62,5 НС, якое дастаткова для вымярэння магутнасці ў дыяпазоне пф. Тут 's прыклад кода, які выкарыстоўвае гэты методыка вымярэнняў.

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

Звярніце ўвагу, што вы павінны адкалібраваць сістэму пры вымярэнні такой невялікай ёмістасці. Гэта робіцца шляхам запуску вымярэння <�моцны> з вашымі зондамі падлучаны , але без мэтавай сістэмы. Вы затым адняць гэта значэнне ёмістасці (звычайна 20-50 пф, у залежнасці ад датчыкаў, якія вы карыстаецеся) з сырых вымярэнняў, каб атрымаць ёмістасць вашай сістэмы ў адзіночку.

2
дададзена

Для ёмістасці, як малая, як пф, час RC пастаяннай метад дае брудныя вынікі на плаце Arduino.

Вы можаце выкарыстоўваць кантакты Arduino, пабудаваныя ў малой ёмістасці (якая знаходзіцца ў самым Pf), каб стварыць «ёмістасць дзельніка» схему і разлічыць гэтак жа, як вы б супраціў ланцуга дзельніка напругі.

See this excellent post by Nethercott for reference Arduino capacitance meter

1
дададзена
Дзякуй :-) Я думаю, вы маеце рацыю, хоць я ніколі не меў шанец расцягнуць гэты метад на мяжы сваіх магчымасцяў. З майго досведу працы з ім, я быў у стане вырабляць здавальняючыя вынікі, выкарыстоўваючы дошку Arduino Uno & 15cm доўгія рэгулярныя драты скакуна ў асяроддзі з дня ў дзень.
дададзена аўтар christoff, крыніца
Добрая знаходка, + 1! Я здзіўлены, наколькі дакладна гэты метад, здаецца, мяркуючы, што гэта заснавана на паразітычных уласцівасцях штыфтоў. Хоць я мяркую, што гэта добра працуе толькі з добрай абаронай ад электрамагнітных перашкод або EMI-свабодных умовах.
дададзена аўтар nreich, крыніца
<�Р> (вагацца ад 50пФ да 100 пф). </Р>

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) зарадкі/разрадкі яго праз CCS: і вымераць час. Найпростыя, як вуха можа быць сфармавана з дапамогай вялікага рэзістара. ня эфектыўна з вельмі малой ёмістасці;

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 пф), вы будзеце сутыкацца з сур'ёзнымі праблемамі, спрабуючы вымераць яго з дапамогай АЛП Arduino з-за яго ўваходныя ёмістасць (14 пф паводле спецыфікацыі). Дадаць паразітных ёмістных правадоў, загалоўкаў і самой платы Arduino, і вы лёгка ў канчатковым выніку з 25 пф ўваходнай ёмістасці, якая знаходзіцца ў тым жа парадку велічыні, што вы спрабуеце вымераць (= вельмі дрэнна).

Што рабіць? Ну, асноўныя варыянты іх ...

Выкарыстоўвайце знешнюю схему вымярэння

Гэта будзе азначаць, у тым ліку актыўных прылад (ОУ, кампаратар, таймер ...) і дакладнасці пасіўных кампанентаў. Праўдзівы HW-рашэнне.

Дакладнасць вымярэння ў гэтым выпадку будзе цалкам да дызайну (тапалогіі схемы і выбару кампанентаў) вонкавага контуру. Схема будзе забяспечваць альбо аналагавае напружанне або сігнал, частата якога можа быць вымераная з дапамогай Arduino без увядзення якіх-небудзь дадатковых істотных памылак.

Прыклад з выкарыстаннем таймера 555 (дадатковы 4 пф кандэнсатар кампенсацыі неабходна паміж OUT і TH для павышэння дакладнасці):

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

Як гэта? Паколькі праблема ўваходнай ёмістасці, якія мы знайшлі ў пачатку досыць вялікая, каб сур'ёзна пагоршыць дакладнасць, але не робіць вымярэнне цалкам няздзейсна. Такім чынам, мы можам адкалібраваць гэты эфект, і да гэтага часу дзеючы (хоць і з меншай дакладнасцю) measument ў мэтавым дыяпазоне (50-100 пф).

Каліброўка выконваецца праз некалькі закадаваныя значэнняў па змаўчанні ў наступным Arduino эскіз (крыніца тут ад braulio777). Для большай дакладнасці варта адкалібраваць значэння 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);
}
    }

Прыклад кода вышэй выхадаў вымераных значэнняў на ВК-дысплеі. Для вашага меркаванага прымянення, лепшы варыянт, верагодна, для запісу дадзеных на знешнюю SD карту.

Disclosure: I have not tested the code above myself.

1
дададзена

Кожны вымяральнік ёмістасці Arduino абапіраецца на ўласцівасці рэзістара кандэнсатара (RC) circuits- сталая часу. Сталая часу RC схемы вызначаецца як час, неабходнае для напругі на кандэнсатары дасягне 63,2% ад яго напружання пры поўнай зарадцы. Вялікія кандэнсатары заняць больш часу для зарадкі, і, такім чынам, будзе ствараць вялікія пастаянныя часу. Ёмістасці ў ланцугі RC звязаная з сталай часу па раўнанні:

<�Ет> Тс = К х С

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

Пераўтвараючы раўнанне вырашыць для ёмістасці дае:

З = МС/Р

schematic

simulate this circuit – Schematic created using CircuitLab

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

Кожны вымяральнік ёмістасці мае схему RC з вядомымі значэннямі рэзістараў і невядомай велічынёй кандэнсатара. Arduino будзе вымяраць напружанне на кандэнсатары і запісаць час, неабходнае для дасягнення 63,2% гэтага напружання пры поўнай зарадцы (пастаянны час). Бо велічыня супраціву ўжо вядомая, мы можам выкарыстоўваць формулу вышэй у праграме, якая будзе вылічаць невядомую ёмістасць.

Як ваша ёмістасць занадта малая Піка Фарадей Range, так што вы можаце непасрэдна вымяраць ёмістасці праз аналагавы ўваход, як такім чынам ... вы сказалі, што ваш кандэнсатар ў дынамічным характары, так што вы павінны прыняць па меншай меры 10 значэнняў і асерадніць, каб атрымаць дакладнае значэнне.

Код для вымярэння нізкай ёмістасці ў дыяпазоне пф

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, крыніца
А як наконт нагрузкі ёмістасцяў Arduino шпількі?
дададзена аўтар Arperum, крыніца
Паводле спецыфікацыі ATmega328 гэта каля 14 пф. Занадта блізка да дыяпазону вымярэння для камфорту. Плюс любой паразітная ёмістасць з-за драты і да плаце і загалоўках Uno.
дададзена аўтар Arperum, крыніца
Так, вы маеце рацыю. Але я паспрабаваў яго і даць мне добры вынік не гэтак дакладны і дакладны, але здавальняючы. Астудзіць чувак Я даў яму абагульненае ўяўленне не рашэння для яго праблемы.
дададзена аўтар Inky1980, крыніца