Domanda:
Registrazione di piccola capacità
Dzung Nguyen
2017-04-05 10:02:23 UTC
view on stackexchange narkive permalink

Sto misurando la capacità di un sistema utilizzando un multimetro e ho scoperto che il valore è molto piccolo (oscilla da 50pF a 100 pF). Il sistema è dinamico quindi la capacità cambia nel tempo.

Ora ho bisogno di registrare questo valore in un file di testo (csv per esempio). Come potrei farlo con Arduino? Se si tratta di resistenza, avrei potuto costruire un semplice partitore di tensione e rilevare la tensione utilizzando l'ADC. Anche C è molto piccolo, non sono stato in grado di costruire alcun circuito di misura per C.

Quanta precisione è richiesta? Hai bisogno di una misura precisa della capacità o rilevare una condizione di scatto sarebbe sufficiente? Qual è la tua applicazione?
È un'applicazione di rilevamento capacitivo.
Sei risposte:
Dmitry Grigoryev
2017-04-05 14:45:13 UTC
view on stackexchange narkive permalink

La misurazione di piccoli valori di capacità tramite la stima della costante RC richiede essenzialmente una misurazione del tempo precisa. I chip ATmega hanno un timer TCNT1 che può essere programmato per incrementare ogni ciclo di clock e può essere fermato da un comparatore utilizzando il bit ACIC in ACSR registrati. L'esecuzione di un contatore a 16 MHz darà una risoluzione di 62,5 ns sufficiente per misurazioni di capacità nella gamma di picofarad. Ecco un esempio di codice che utilizza questa tecnica di misurazione.

AnalogRead è circa 1000 volte più lento, quindi sarai limitato all'intervallo nF se lo usi.

Nota che dovresti calibrare il tuo sistema quando misuri una capacità così piccola. Questo viene fatto eseguendo una misurazione con le sonde collegate ma senza il sistema di destinazione. Sottrai quindi questo valore di capacità (tipicamente 20-50 pF, a seconda delle sonde che usi) dalle tue misurazioni grezze per ottenere la capacità del solo sistema.

TanyaV
2017-04-05 15:07:27 UTC
view on stackexchange narkive permalink

Per una capacità piccola come pF, il metodo della costante di tempo RC produce risultati sporchi su una scheda Arduino.

È possibile utilizzare i pin Arduino incorporati in una piccola capacità (che è in Pf stessa) per creare un "divisore di capacità" e calcola in modo molto simile alla resistenza di un circuito divisore di tensione.

Vedi questo eccellente post di Nethercott come riferimento misuratore di capacità Arduino

Bella scoperta, +1! Sono sorpreso di quanto questo metodo sembri preciso, considerando che si basa sulle proprietà dei pin parassiti. Anche se suppongo che funzioni bene solo con una buona schermatura EMI o in condizioni prive di EMI.
Grazie :-) Immagino tu abbia ragione, anche se non ho mai avuto la possibilità di estendere questo metodo ai suoi limiti. Dalla mia esperienza con esso, sono stato in grado di produrre risultati soddisfacenti utilizzando una scheda Arduino Uno e cavi jumper regolari lunghi 15 cm in un ambiente quotidiano.
Edgar Bonet
2017-04-05 15:41:03 UTC
view on stackexchange narkive permalink

Il modo standard per misurare una resistenza con un Arduino è costruire un divisore di tensione mettendolo in serie con una resistenza nota. Ho provato lo stesso approccio per misurare le capacità e risulta che funziona bene nella gamma 100 pF! Il circuito è così:

  ┌────────────── Uscita digitale Arduino │──┴── conosciuto──┬── cap │ ├── ─────────── Ingresso analogico Arduino │──┴── sconosciuto──┬── cap │ GND  

L'unico problema è che devi fare il misurazione relativamente veloce, altrimenti si misurerebbe il rapporto tra le resistenze di dispersione. Ecco il protocollo di misurazione:

  1. Imposta entrambi i pin su OUPUT LOW per scaricare entrambi i condensatori.
  2. Ritarda uno o due cicli della CPU per assicurarsi che siano completamente scarichi.
  3. Imposta il pin dell'ingresso analogico su INPUT modalità: questo renderà alta impedenza e isolerà il nodo ad esso collegato.
  4. Imposta l'uscita digitale su HIGH : questo caricherà i due condensatori in serie a 5 V.
  5. Ritardo per uno o due cicli della CPU affinché la tensione si stabilizzi.
  6. Effettua una lettura analogica.

Ora puoi derivare la capacità dalla lettura usando la stessa formula che useresti con le resistenze, solo con impedenze (o, semplicemente 1 / C) invece che resistenze:

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

La stessa formula può essere derivato considerando che il nodo collegato all'ingresso analogico, che include una piastra di ogni condensatore, ha una carica netta nulla.

Alcune cose degne di nota:

  • ottenere la migliore risoluzione scegliendo la capacità di riferimento vicina a quella che si vuole misurare.
  • I ritardi non sono effettivamente necessari: poiché i condensatori si caricano e si scaricano molto velocemente, un singolo ciclo della CPU è di circa 24 costanti di tempo.
  • Se dovessi misurare grandi capacità (diversi nanofarad) con questa configurazione, vorresti resistori di protezione in serie con il Pin di Arduino, ma poi i ritardi diventano obbligatori. Nell'intervallo 100 pF non mi preoccuperei delle correnti di spunto.
  • Se il ritardo nel passaggio 5 è troppo lungo, la tua misurazione sarà influenzata dalla perdita dei cappucci e del pin di ingresso analogico.
  • Non devi preoccuparti del limite di 14 pF sul campione e sul circuito di tenuta: influenzerà leggermente la misurazione primissima ma, una volta caricato quel limite, la misurazione successiva non sarà influenzata a lungo poiché il limite sconosciuto non cambia molto tra misurazioni consecutive. Non è necessario calibrare la capacità parassita del pin e delle sonde.
Prayuktibid
2017-04-05 10:24:25 UTC
view on stackexchange narkive permalink

Ogni misuratore di capacità Arduino si basa su una proprietà dei circuiti dei condensatori resistivi (RC): la costante di tempo. La costante di tempo di un circuito RC è definita come il tempo necessario affinché la tensione attraverso il condensatore raggiunga il 63,2% della sua tensione quando è completamente carica. I condensatori più grandi richiedono più tempo per caricarsi e quindi creeranno costanti di tempo maggiori. La capacità in un circuito RC è correlata alla costante di tempo dall'equazione:

TC = R x C

dove TC = costante di tempo in secondi R = resistenza in ohm C = capacità in farad

Riorganizzando l'equazione per risolvere la capacità si ottiene:

C = TC / R

schematic

simula questo circuito - Schema creato utilizzando CircuitLab

Esempio: 1 megohm * 1 microfarad = 1 secondo enter image description here

Ogni misuratore di capacità ha un circuito RC con valori di resistenza noti e un valore di condensatore sconosciuto. L'Arduino misurerà la tensione sul condensatore e registrerà il tempo necessario per raggiungere il 63,2% della sua tensione quando è completamente carica (la costante di tempo). Poiché il valore di resistenza è già noto, possiamo utilizzare la formula sopra in un programma che calcolerà la capacità sconosciuta.

Poiché la tua capacità è troppo piccola nell'intervallo Pico Farad, puoi misurare direttamente la capacità attraverso il tuo analogico pin in questo modo ... Schematic Hai detto che il tuo condensatore è di natura dinamica, quindi devi prendere almeno 10 valori e fare una media per ottenere un valore accurato.

Codice per la misura Bassa capacità nel range 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_PULL = 34 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); se (val < 1000)
{pinMode (IN_PIN, OUTPUT); capacità float = (float) val * IN_CAP_TO_GND / (float) (MAX_ADC_VALUE - val); Serial.print (F ("Capacitance Value =")); Serial.print (capacità, 3); Serial.print (F ("pF (")); Serial.print (val); Serial.println (F (")")); } altro {pinMode (IN_PIN, OUTPUT); ritardo (1); pinMode (OUT_PIN, INPUT_PULLUP); unsigned long u1 = micros (); t lungo senza segno; int digVal; fare {digVal = digitalRead (OUT_PIN); lungo senza segno 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 scaricoTime = (int) (t / 1000L) * 5; ritardo (tempo di scarica); pinMode (OUT_PIN, OUTPUT); digitalWrite (OUT_PIN, LOW); digitalWrite (IN_PIN, LOW); capacità float = - (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); }  
E per quanto riguarda le capacità di carico dei pin di arduino?
Secondo il datasheet dell'ATmega328 è di circa 14 pF. Troppo vicino al campo di misura per il comfort. Più qualsiasi capacità parassita dovuta ai fili e alla scheda Uno e ai connettori.
-1: Questo metodo non è realmente adatto per capacità così piccole: avresti bisogno di un valore di resistenza follemente grande, altrimenti la costante di tempo sarebbe troppo breve per effettuare una buona misurazione. Se vuoi eseguire una misurazione della costante di tempo RC, dovresti invece usare il metodo descritto nella risposta di Dmitry Grigoryev.
Si hai ragione. Però l'ho assaggiato e mi ha dato un buon risultato non così preciso e preciso ma soddisfacente. Calmati amico, gli ho dato un'idea generalizzata non le soluzioni per il suo problema.
Hai dato "un'idea" e poi un pezzo di codice che fa qualcosa di molto diverso da quell'idea. Se sei l'autore di quel codice, perché non spieghi cosa fa effettivamente? In caso contrario, perché non dai credito all'autore originale?
dannyf
2017-04-05 15:23:54 UTC
view on stackexchange narkive permalink

(fluttua da 50pF a 100 pF).

alcuni modi per valori così piccoli -> supponendo che tu possa davvero leggerlo come un condensatore.

1) formare un serbatoio lc e misurare la sua frequenza -> più efficace nella misurazione di capacità di piccolo valore. ma necessita di induttore / calibrazione di precisione, ed è soggetto a parassiti.

2) caricarlo / scaricarlo tramite un CCS: e misurare il tempo. più semplice come un CC può essere formato tramite un grande resistore. non efficace con capacità veramente piccole;

3) trasferimento di carica: utilizzando la capacità dell'adc. molto efficace contro piccole capacità: < 10x di capacità adc. necessita di calibrazione.

ognuno ha i suoi problemi.

Cos'è * CCS * ??
Enric Blanco
2017-04-05 16:26:21 UTC
view on stackexchange narkive permalink

Poiché la capacità da misurare è ben al di sotto di 1 nF (50-100 pF), incontrerai seri problemi nel provare a misurarla con l'ADC di Arduino a causa della sua capacità di ingresso (14 pF secondo la scheda tecnica). Aggiungi le capacità parassite di fili, connettori e la stessa scheda Arduino e ti ritroverai facilmente con una capacità di ingresso di 25 pF, che è nello stesso ordine di grandezza di quello che stai cercando di misurare (= UNA COSA MOLTO CATTIVA).

Cosa fare allora? Bene, le opzioni principali sono queste ...

Usa un circuito di misura esterno

Ciò significherebbe includere dispositivi attivi (amplificatori operazionali, comparatore, timer ...) e componenti passivi di precisione . Una vera soluzione basata su HW.

La precisione della misura in questo caso dipenderà interamente dal progetto (topologia del circuito e selezione dei componenti) del circuito esterno. Il circuito fornirebbe una tensione analogica o un segnale la cui frequenza potrebbe essere misurata da Arduino senza introdurre ulteriori errori significativi.

Un esempio che utilizza un timer 555 (è necessario un condensatore di compensazione aggiuntivo da 4 pF tra OUT e TH per una maggiore precisione):

555 timer capacitance meter

Frequency vs capacitance

Fonte: Usa tecniche analogiche per misurare la capacità nei sensori capacitivi, un articolo di Martin Tomasz pubblicato su Electronic Design.

Pensa al circuito esterno come a un "sensore" "o come circuito di condizionamento del segnale per un" sensore "(la capacità da misurare). In effetti, la capacità dinamica che stai cercando di misurare proviene probabilmente da un sensore (umidità, umidità?), No?

Collega il condensatore direttamente ai pin analogici di Uno e calibra le letture

Può sembrare incredibile, ma qualcosa di così semplice funziona (a scapito della precisione, ovviamente):

Uno as capacitance meter

Che ne dici? Perché il problema di capacità di ingresso che abbiamo rilevato all'inizio è abbastanza grande da compromettere seriamente l'accuratezza, ma non rende la misurazione completamente irrealizzabile. Pertanto, possiamo calibrare quell'effetto e avere ancora una misurazione valida (anche se con una precisione ridotta) nell'intervallo target (50-100 pF).

La calibrazione viene eseguita tramite alcuni valori predefiniti codificati di seguito Schizzo di Arduino (fonte qui da braulio777). Per una migliore precisione dovresti calibrare i valori di IN_STRAY_CAP_TO_GND e R_PULLUP nello schizzo confrontando le misurazioni di alcuni condensatori con i loro valori di capacità già noti (ammesso che tu possa farlo).

  // Misuratore di capacità digitale // Misure da 0.000pF a 1000uF # includono <LiquidCrystal.h>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); capacità float = (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); // per la migliore precisione lcd.print ("pF"); } altro {pinMode (IN_PIN, OUTPUT); ritardo (1); pinMode (OUT_PIN, INPUT_PULLUP); unsigned long u1 = micros (); t lungo senza segno; int digVal; fare {digVal = digitalRead (OUT_PIN); lungo senza segno 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 scaricoTime = (int) (t / 1000L) * 5; ritardo (tempo di scarica); pinMode (OUT_PIN, OUTPUT); digitalWrite (OUT_PIN, LOW); digitalWrite (IN_PIN, LOW); capacità float = - (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 (capacità / 1000.0, 2); lcd.print ("uF"); } else {lcd.setCursor (0,1); lcd.print (""); lcd.setCursor (0,1); lcd.print (capacità, 2); lcd.print ("nF"); } while (millis ()% 1000! = 0);}}  

Il codice di esempio sopra mostra i valori misurati su un display LCD. Per l'applicazione prevista, l'opzione migliore è probabilmente scrivere i dati su una scheda SD esterna.

Divulgazione: non ho testato il codice sopra di me.



Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 3.0 con cui è distribuito.
Loading...