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):
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):
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.