Carica e scarica di un condensatore
- Arduino partiamo da zero - n°7
Sperimentiamo con la misura del tempo, arduino carica un condensatore poi ne misura il tempo di scarica.
Come accennato nel mio precedente post "Leggendo sul web ho trovato un commento che consigliava di effettuare la
misura del tempo di scarica di un condensatore, questo approccio
completamente diverso mi sembra interessante e cercherò di documentarmi
meglio."
Ho trovato sul blog di Nicola Amatucci un post sulla misura del tempo di scarica e carica di un condensatore.
Ecco quindi il mio lavoro con la collaborazione di Adriano che ha elaborato le formule che troverete.
Cosa occorre per questo esperimento:
Arduino, una Breadboard, Pc e cavo usb.
Una resistenza da 330 ohm.
Un condensatore da 100uF
Una resistenza da 560 ohm.
I valori qui sopra possono cambiare con le opportune modifiche allo sketch.
Un condensatore da 100uF
Una resistenza da 560 ohm.
I valori qui sopra possono cambiare con le opportune modifiche allo sketch.
Realizzate questo schema:
Questa la breadboard
Tempo = (R*C*log(Vi/Vf))
Si parte da questa espressione che restituisce il tempo in secondi ( tau è la costante di tempo R*C).
Quindi Tau*log(Volt iniziali / Volt finali).
Ho tratto questa formula da un mio vecchio libro " Corso di Radiotecnica" è stata poi studiata e implementata da Adriano ricavando le formule inverse che calcolano R oppure C ed infine Vf.
Con l'idea di realizzare un ohmmetro e/o un capacimetro.
Con l'idea di realizzare un ohmmetro e/o un capacimetro.
Se volete approfondire la parte teorica con wikipedia troverete moltissime informazioni.
Sulla costante di tempo = R*C facciamo questa considerazione per ricordare come da Ohm e Farad si ottenga il tempo in secondi:
Sulla costante di tempo = R*C facciamo questa considerazione per ricordare come da Ohm e Farad si ottenga il tempo in secondi:
R = espressa in Ohm, C = espresso in Farad , Il tempo espresso in secondi.
Ohm = Volt/Ampere = Ohm = V/A
Farad = Coulomb/ Volt = F = Q/V .
Un Ampere è dato da 1 Coulomb * 1 secondo = A = Q*s
Quindi Ohm = V / A cioè V / (Q/s) così Ohm = ( Volt * s )/ Q
Ecco che abbiamo il tempo in secondi sostituendo a R*C avremo ((V*s)/Q) * ( Q/V)) = s
Ecco qui sotto lo sketch.
Il listato è ampiamente commentato, tenete conto che è un esempio ed una base di lavoro per realizzare un vostro progetto.
Le parti interessanti dello sketch sono le formule implementate da Adriano da riga 66 a riga 88.
La carica del condensatore righe ( 110 - 121)
La misura del tempo di scarica ( 123 - 136) con il controllo sul pin analogico del raggiungimento del livello di scarica desiderato immesso nella ( double Vf = 0.025 ).
Le parti interessanti dello sketch sono le formule implementate da Adriano da riga 66 a riga 88.
La carica del condensatore righe ( 110 - 121)
La misura del tempo di scarica ( 123 - 136) con il controllo sul pin analogico del raggiungimento del livello di scarica desiderato immesso nella ( double Vf = 0.025 ).
/* Sergio & Adriano Prenleloup 12 / 05 / 2013 Tempo di carica e scarica condensatore v. 2.02 Misurazione della capacità Misurazione della resistenza Un ringraziamento a Nicola Amatucci sul suo blog l'idea base ed in nucleo dello sketch. Con questo sketch s'imposta il tempo di carica nella variabilie tc e si rileva il tempo di scarica. Si leggono i tempi su monitor seriale. */ // pin digitali in uso carica e scarica condensatore int Carica = 12; int Scarica = 11; // pin analogico di controllo per verificare il raggiungimento del // livello di scarica impostato di C1 (Vedi Vf) int Control = 0; // pin analo A0 //variabili in uso unsigned long Carica_t0 = 0; //registra t0 inizio carica int Carica_t1 = 0; // progressione del tempo di carica int tc = 1000; // costante di tempo carica a cui arrivare // si sceglierà in relazione alla capacità di C1 // ed al valore della resistenza di R1 in modo di avere // la certezza di raggiungere la carica completa. unsigned long Scarica_t0 = 0; // registra il t0 inizio scarica condensatore unsigned long Scarica_t1 = 0; // contiene il tempo di scarica a partire da t0 // fino al raggiungimento della scarica completa // che viene verificata dal pin analogico A0 /* Questi valori si sono utilizzati per testare i risultati teorici confrontandoli con i risultati misurati. Se si cambiano i componenti dovranno essere aggiornati altrimenti i valori calcolati non risultano giusti. */ //parametri circuito double prec = 1E3; // costante milli double R = 560.0; //Resistenza di scarica in omm (valore misurato) double C = 110E-6; //Condensatore in Farad (100 micro-F) double Vi = 4.78; //Vo = tensione iniziale (condensatore carico) 5 volt double Vf = 0.025 ; //Vs = tensione finale (condensatore scarico) 25 millivolt // non porre a 0 questo valore altrimenti avremo errore // divisione per "0" int sogliaADC = floor(Vf * 1024 / Vi); // contiene il valore numerico // attribuito dal dac di arduino ai 25 mV. // *********************************************************************** /* formula e formule inverse qui sotto ho inserito queste formule per controlli in fase di prove di funzionamento queste funzionano solo se nelle variabili sopra indicate sono stati inseriti i valori presenti nel circuito. calolaC funziona se è fissata la R ( logicamente anche Vi e Vf ) calcolaR funziona se è fissato C (logicamente anche Vi e Vf ) *Con le opportune modifiche è possibile eliminare quelle che non interessano * */ double tempoScaricaTeorico = (R*C*log(Vi/Vf)); /* formula per stabilire il tempo di scarica teorico che confronteremo con il tempo misurato, si devono impostare R e C con valore noto. */ double calcolaC(unsigned long tf) // qui si calcola il valore del condensatore { // se C è incognito dovremo fissare R double t = tf; return (t/prec) / (R * log(Vi/Vf)); } double calcolaR(unsigned long tf) // qui si calcola il valore della resistenza // di scarica. { // se R è incognito dovremo fissare C double t = tf; return (t/prec) / (C * log(Vi/Vf)); } double calcolaV(unsigned long tf) // qui si valcola la Vf //(controllo teorico con R e C conosciuti { double t = tf; return Vi * exp(-(t/prec)/(R*C)); } void setup() { Serial.begin(9600); pinMode (Control, INPUT); pinMode (Carica, OUTPUT); //pronto per la carica pinMode (Scarica, INPUT); // (INPUT) blocca la scarica Serial.print("Soglia ADC: "); // valore scelto vicino allo zero. Serial.println( sogliaADC); Serial.print("Tempo di scarica teorico: "); Serial.println( tempoScaricaTeorico, 3); } double Rcalc = 0.0; double Ccalc = 0.0; double Vcalc = 0.0; double Tcalc = 0.0; void loop() { //inizio carica pinMode (Carica, OUTPUT); //abilita il pin alla carica Carica_t0 = millis(); // si registra il tempo di partenza digitalWrite (Carica, HIGH); // si avvia la carica delay (tc); // tempo di carica (tc) Carica_t1 = ( millis()- Carica_t0 ); //si conteggia il tempo di // carica digitalWrite (Carica, LOW); pinMode (Carica, INPUT); // con questa si blocca l'eventuale scarica // anche da questo pin. //fine carica ******************************************** // inizio scarica pinMode (Scarica, OUTPUT); // si abilita alla scarica Scarica_t0 = millis(); // si registra il tempo inizio scarica digitalWrite( Scarica, LOW); // inizia la scarica while ( analogRead (Control) > sogliaADC){} /* attende fino a quando il pin A0 non raggiuge il valore scelto di scarica ( Vf)*/ Scarica_t1 = ( millis () - Scarica_t0); // conteggia il tempo di scarica pinMode (Scarica, INPUT); //blocca la scarica // fine scarica ******************************************* Rcalc = calcolaR(Scarica_t1); // si fanno i calcoli Ccalc = calcolaC(Scarica_t1); Vcalc = calcolaV(Scarica_t1); // stampa i dati lettura sul monitor Serial.println(" "); Serial.print("Tempo Carica secondi: "); Serial.println( (Carica_t1/prec), 3); Serial.println(" "); Serial.print("Tempo Scarica secondi: "); Serial.println(( Scarica_t1/prec), 3); Serial.print("Resistenza calcolata omm : "); Serial.println( Rcalc, 1); Serial.print("Capacita' calcolata F : "); Serial.println( Ccalc, 6); Serial.print("Tensione (finale) calcolata Volt : "); Serial.println( Vcalc, 3); delay (2000); //attesa //ripristino le variabili Carica_t0 = 0; Carica_t1 = 0; Scarica_t0 = 0; Scarica_t1 = 0; } //end
Altre osservazioni:
Anche in questo lavoro i dati si visualizzano con il monitor seriale. Per utilizzarlo leggete il post precedente.Lo sketch presentato è servito per fare prove e verifiche per vedere le differenze fra teoria e pratica.
Effettivamente la misura del tempo corrisponde con quanto teoricamente calcolato, anche altri valori non differiscono molto da quanto aspettato.
Praticamente con questa base si potrebbe realizzare un capacimetro.
Magari utilizzando resistenze di scarica diverse per le varie portate ed eventualmente un commutatore per cambiare la portata.
E' tutto da studiare e provare ma la premessa che possa funzionare bene c'è.
Attendo vostri commenti.
Ecco un esempio di schermata
Scarica qui lo sketch
Sono graditi Vostri commenti.
Un saluto a tutti.
Sergio
mi domandavo perchè le due resistenze hanno valori diversi? È importante o possono anche essere uguali?
RispondiEliminaI valori possono essere uguali, ho scelto quei valori per prove con il condensatore utilizzato, con altri condensatori possono risultare migliori altri valori.
EliminaTutto il post è solo un esempio di come si può procedere non è definito per un uso specifico.
Se guardi bene nelle parti commentate trovi varie possibilità per calcolare capacità sconosciuta con resistenza conosciuta ed altre prove che ho indicato.
Il valore di R1 è stato scelto ed abbinato alla costante tc per avere una sicura carica completa del condensatore (vedi commento inserito nel listato)
int tc = 1000; // costante di tempo carica a cui arrivare
// si sceglierà in relazione alla capacità di C1
// ed al valore della resistenza di R1 in modo di avere
// la certezza di raggiungere la carica completa.
Controlla e rileggi tutti i commenti inseriti nello sketch e ti sarà tutto più chiaro.
Rimango comunque disponibile per qualsiasi domanda.
Ti ringrazio del commento e della lettura.
Cordiali saluti
Sergio.