Kichkina quvvatni hisobga olish

Men multimetriya yordamida tizimning imkoniyatlarini o'lchayapman va qiymati juda kichik (50pF dan 100 pF gacha o'zgarib turadi). Tizim dinamik, shuning uchun kapasitans vaqt o'tishi bilan o'zgarib turadi.

Endi bu qiymatni ba'zi matn fayllariga (masalan, CSV) kiritish kerak. Arduino bilan buni qanday qilishim mumkin? Agar u qarshilik qiladigan bo'lsa, men oddiy kuchlanishli bo'linmani qurgan bo'lar edim va ADC yordamida voltajni sezardim. Bundan tashqari, C juda kichik, men C uchun bir necha o'lchash davri qurolmadim.

5
Kapasitiv sezgirlik dasturi.
qo'shib qo'ydi muallif roetnig, manba
Qancha aniqlik talab qilinadi? Kapasitenin aniq o'lchoviga ega bo'lishingiz kerakmi yoki safar holatini aniqlash etarlicha yaxshi bo'lar edi? Arizangiz nima?
qo'shib qo'ydi muallif Arperum, manba

6 javoblar

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

Faqatgina ta'qib qilish sizning o'lchamingizni tezroq qilish kerak, Aks holda siz oqish qarshilik nisbatlarini o'lchashingiz mumkin. Mana o'lchov protokoli:

  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.

Keling, o'qish hajmidan bir xil foydalanishingiz mumkin rezistorlar bilan foydalanadigan formulani, faqat impedances (yoki oddiygina 1/S) qarshilik o'rniga:

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

Xuddi shu formuladan foydalanib, tugunni bog'langan deb hisoblash mumkin har bir kondansatörün bir plakasını o'z ichiga olgan analog kirishga ega Nolinchi aniq to'lov.

Ahamiyatga ega bo'lgan bir nechta narsa:

  • 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
qo'shib qo'ydi

RC doimiy baholash usuli bilan kichik hajmni o'lchash asosan aniq vaqtni o'lchashni talab qiladi. ATmega chipslari har bir soat aylanishini oshirish uchun programlanadigan TCNT1 taymeriga ega, ACSR ro'yxatida ACIC yordamida bittadan taqqoslash mumkin. 16 MGs gacha hisoblagichni ishga tushirish siz uchun 62,5 ns o'lchamdagi pikselni o'lchash imkonini beradi. bu yerda bu erda ishlatiladigan kod misoli o'lchov texnikasi.

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

Bunday kichik hajmni o'lchashda siz tizimni sozlashingiz kerak. Bu sizning problaringiz bilan bilan o'lchashni bajarish orqali amalga oshiriladi, lekin maqsad tizimsiz. Keyinchalik sistemangizning imkoniyatlarini faqat sizning xom o'lchovlaringizdan olishingiz mumkin (odatda 20-50 pF, siz foydalanadigan probalarga qarab).

2
qo'shib qo'ydi

PF kabi kattalik hajmi uchun RC doim sobit usuli Arduino taxta ustida iflos oqibatlarga olib keladi.

Siz "capacitance divider" devorini yaratish uchun kichik hajmdagi (Pf ning o'zi) qurilgan Arduino pimlardan foydalanishingiz mumkin va siz kuchlanishni taqsimlovchi devordagi qarshilik kabi hisoblashingiz mumkin.

See this excellent post by Nethercott for reference Arduino capacitance meter

1
qo'shib qo'ydi
Rahmat :-) Men sizning to'g'ri ekaningizni tasavvur qilaman, garchi men bu usulni o'z chegaralariga cheklash imkoniga ega bo'lmaganman. O'z tajribamdanoq, men kunlik muhitda Arduino Uno kengashi va 15 sm uzunlikdagi oddiy simlar kabellari yordamida qoniqarli natijalar ishlab chiqardim.
qo'shib qo'ydi muallif christoff, manba
Yaxshi topish, + 1! Parazitik pin xususiyatlariga asoslanib, bu usulning qanchalik aniq ekanligiga hayron bo'ldim. Menimcha, bu faqat yaxshi EMI ekranli yoki EMIsiz sharoitlarda yaxshi ishlaydi.
qo'shib qo'ydi muallif nreich, manba

(50pF dan 100 pF gacha).

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) uni KGK orqali zaryad qilish/tushirish: va vaqtni o'lchash. eng oddiy datchik sifatida katta rezistor orqali tuzilishi mumkin. chindan ham kichik hajmda samarali emas;

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

ularning har birida o'z muammolari bor.

1
qo'shib qo'ydi
CCS nima? nima?
qo'shib qo'ydi muallif nreich, manba

O'lchovni o'lchash imkoniyati 1 nF (50-100 pF) dan ancha past bo'lganligi sababli siz uning kirish kattaligi (ma'lumotlar sahifasiga ko'ra 14 pF) tufayli Arduino ADC bilan uni o'lchashga jiddiy muammolarni boshdan kechirasiz. Kablolar, sarlavhalar va Arduino kartochkasining o'zboshimchali imkoniyatlarini qo'shing va siz o'lchashga harakat qiladigan narsalar kattaligidagi (= AXLO BADING) bir xil o'lchamdagi 25 pF gacha kirish imkoniyatini osonlik bilan to'ldirasiz.

Keyin nima qilish kerak? Xo'sh, asosiy variantlar ...

Tashqi o'lchov pallasida foydalaning

Bu faol qurilmalar (op amp, komparator, taymer ...) va aniq passiv qismlarni o'z ichiga oladi. HW-ga asoslangan haqiqiy yechim.

Bu holda o'lchovlarning aniqligi tashqi devordagi dizayni (elektron topologiyasi va tarkibiy qismini tanlash) bilan to'la bo'ladi. Vaqtincha analog kuchlanishni yoki signalni chastotani Arduino tomonidan biron bir qo'shimcha xatolikka yo'l qo'ymasdan o'lchab beradigan signalni taqdim etadi.

555 taymerni ishlatadigan misol (yaxshilangan aniqlik uchun OUT va TH o'rtasida qo'shimcha 4 pF tovonlik kondansatörü kerak bo'ladi):

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.

Tashqi kontaktlarning zanglashiga "Sensor" yoki "Sensor" (o'lchash imkoniyati) uchun signal uzatish davri sifatida tasavvur qiling. Aslida siz o'lchashga harakat qilayotgan dinamik quvvati sensordan (namlik, namlikmi?) Keladi, shunday emasmi?

Kondensatorni Uno analog pinlariga to'g'ridan to'g'ri ulang va o'qishni sozlang

Bu ajoyib bo'lishi mumkin, lekin bu oddiy ish (masalan, aniqlik bilan), oddiy:

Uno as capacitance meter

Bu qanday? Dastlab biz aniqlaydigan uskuna sig'imi muammolari jiddiy adolatni susaytirishi uchun etarlicha katta bo'lsa-da, o'lchovni mutlaqo yaroqsiz holga keltirmaydi. Shunday qilib, biz ushbu ta'sirni kalibrovka qilishimiz mumkin va maqsad oralig'ida (50-100 pF) haligacha (aniqlangan aniqlik bilan) o'lchov mavjud.

Kalibrlash quyidagi Arduino eskizidagi ba'zi qattiq kodlangan standart qiymatlar orqali amalga oshiriladi (brauzer777 dan manba bu yerda ). Yaxshi aniqlik uchun ayrim kondensatorlarning o'lchovlarini ularning ma'lum bo'lgan kattaligi qiymatlari bilan taqqoslab, (kodeks) IN_STRAY_CAP_TO_GND va R_PULLUP qiymatlarini kalibrlashingiz kerak.

//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);
}
    }

Yuqoridagi misol kodi LCD ekranga o'lchangan qiymatlarni chiqaradi. Sizning maqsadli dasturingiz uchun eng yaxshi variant, ehtimol, tashqi SD-kartaga ma'lumot yozishdir.

Disclosure: I have not tested the code above myself.

1
qo'shib qo'ydi

Har bir Arduino quvvati o'lchaganini ko'radi qarshilik kondansatörü (RC) davrlari xususiyatiga tayanadi - vaqt sobit. RC tizimining vaqt simi kondansatördeki voltajın to'liq zaryad olayotgan paytda kuchlanish% 63.2 ga erishish vaqti sifatida belgilanadi. Keyinchalik katta kondansatörler zaryad qilish uchun uzoq davom etadi va shuning uchun katta vaqt sabitlerini yaratadi. RC tizimidagi sig'im vaqt tenglamasi bilan bog'liq:

TC = R x C

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

Kapasitans uchun hal qilish uchun tenglamani qayta tuzish:

C = TC/R

schematic

simulate this circuit – Schematic created using CircuitLab

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

Har bir quvvat o'lchaganini ko'radi ma'lum bo'lgan qarshilik qiymatlari va noma'lum kondansatör qiymati bilan bir RC davriga ega. Arduino quvvati kondansatördeki kuchlanishni o'lchaydi va to'liq zaryad olayotgan vaqtda (vaqt sobit) uning kuchlanishining 63,2% ga erishish uchun qancha vaqt ketishini yozib beradi. Qarshilik qiymati allaqachon ma'lum bo'lganligi sababli, yuqoridagi formulani noma'lum sig'imlarni hisoblaydigan dasturda foydalanishimiz mumkin.

Capacitance sizning Pico Farad oralig'ida juda kichik bo'lgani bois, siz analog pin orqali bu imkoniyatni to'g'ridan-to'g'ri o'lchashingiz mumkin ... Sizning konnektatoringiz tabiatan dinamik bo'lib, shuning uchun siz eng yuqori qiymatni qo'lga kiritishingiz va aniq qiymatni olish uchun uni o'rtacha hisoblashingiz kerakligini aytishgan.

O'lchov kodi PF oralig'idagi past quvvatlilik

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
qo'shib qo'ydi
-1: Bu usul, bunday kichik imkoniyatlar uchun juda mos emas: siz juda katta qarshilik qiymatiga muhtoj bo'lasiz, aks holda vaqt o'lchami yaxshi o'lchash uchun juda qisqa bo'ladi. RC vaqtini doimiy o'lchashni xohlasangiz, Dmitriy Grigoryevning javobida bayon qilingan usuldan foydalaning.
qo'shib qo'ydi muallif Sprogz, manba
Siz "g'oyani" bergansiz, keyin esa bu g'oyadan juda farq qiladigan kodning bir qismini berdingiz. Agar siz ushbu kodni yozsangiz, nima uchun u aslida nimani tushuntirmayapsiz? Agar bo'lmasa, nega asl muallifga kredit bermaysiz?
qo'shib qo'ydi muallif Sprogz, manba
Arduino pinlerinin yuk hajmi haqida nima deyish mumkin?
qo'shib qo'ydi muallif Arperum, manba
ATmega328 ma'lumotlar sahifasiga ko'ra, u 14 pF atrofida. Konfor uchun o'lchov oralig'iga juda yaqin. Bundan tashqari, kabellar va UNO kartochkasi va sarlavhalari tufayli har qanday noma'qul sig'im.
qo'shib qo'ydi muallif Arperum, manba
Ha, sen haqsan. Lekin men uni tatib ko'rdim va menga yaxshi natija bermadi, shuning uchun ham aniq va aniq, lekin qoniqarli. Do'stimni sovutib, uning muammolarini hal qilmasligini unga umumiy fikr berdim.
qo'shib qo'ydi muallif Inky1980, manba