Induttanzimetro e Capacimetro con Arduino

Salve a tutti spero che qualcuno mi aiuti a risolvere un problema software che ho in contratto nella realizzazione di un LC meter appunto un induttanzimetro capacimetro, premetto che su internet c’è molto materiale ma quasi tutto per PIC o cmq non certo per Arduino, vi è un solo progetto con Arduino, ma che si differenzia non poco dal progetto più blasonato per PIC. La mia massima ispirazione è stato l’ottimo lavoro che potete trovare in questa pagina, ma con firmware già pronto alla scrittura, http://capasoblog.blogspot.it/2007/12/capaso-lc-meter-capacimetro.html, e cmq sempre per pic. Cioè LM311 e PIC. Io ho realizzato il medesimo schema ma utilizzando l’atmel 328p programmato con arduino, il tutto funziona egreggiamente nel senso che per la realizzazione definitiva bisogna applicare alcune formule, che data la frequenza di L1 e C1, e inseguito L1-C1-C2 è possibile ricavale L incognita oppure C incognita. Vi è un post in Inglese http://forum.arduino.cc/index.php/topic,8437.0.html dove viene realizzato un lc meter ma anche se il principio è lo stesso l’autore non fa una vera e propria calibrazione in quando nel codice addirittura inserisce, frequenza iniziale, capacita, e induttanza iniziale, e non utilizza lm311 bensi un altro comparatore. La mia domanda è questa, vi sono due librerie per leggere frequenze con arduino superiori a 100 khz una è FreqCounter Page has moved essa però non è compatibbile con gli ultimi ambienti di sviluppo arduino ma con la versione 0.22 si… Oppure FreqCount http://www.pjrc.com/teensy/td_libs_FreqMeasure.html#compare ma è divisa in due tipi che hanno una precisione differente in base alla frequenza da misurare. Sono riuscito con tutti è due i tipi a visualizzare la frequenza esatta sia con L1+C1(cioè F1) sia con L1+C1+C2(capacità di precisione quindi F2) comparato con un oscilloscopio. Il problema sorge adesso in quanto io dovrei memorizzare F2 dopo che entra in funzione un relè che mette in parallelo c2, in un certo istante, e memorizzare il valore in una variabile, è non deve essere più modificato, idem per F1 dopo aver staccato dal circuito ovviamente C2. Infatti dopo che ho memorizzato i valori di F1 e F2, posso tramite calcoli ricavarmi, Lx o Cx incognite infatti quando queste vengono messe sotto viene generata un’altra frequenza. Sono disposto a postare tutto il progetto, e il codice se qualcuno mi aiuta. In definitiva queste librerie possono essere stoppare. Il codice come lo scrivereste voi. Io vi posto il mio ora vediamo un pò… In base a queste formule :

F1=LETTA DAL MICRO IN UN DETERMINATO ISTANTE come faccio dato che la libreria parte in loop ???
F2=LETTA E MEMORIZZATA IN UN ALTRO ISTANTE QUANCO C2 E SOTTO IL CIRCUITO come faccio dato che la libreria parte in loop ??? e non c’è modo di stopparla??

APPLICARE NELLA FASE DI CALIBRAZIONE Cc=F2^/(F1^-F2^)*1015 Pf(il valore di c2) Lc=1/4?^*F1^*Cc avendo ora questi valori si può calcolare

Cx e Lx

ecco il codice----

#include <math.h>
#include <LiquidCrystal.h>
#include <FreqCounter.h> //compatibile solo con Arduino 0023 

boolean Rele = 7;//pin assegnato al relè
LiquidCrystal lcd(12, 11, 6, 4, 3, 2);
unsigned long frq;
float Cx, Lx, Cc, Lc; 


void setup() {
  Serial.begin(57600);
  lcd.begin(16, 2);//16 COLONNE e 2 RIGHE schermo LCD MODELLO HD44780
  lcd.print("Induttanzimetro");//scrivo 
  pinMode (Rele, OUTPUT);//imposto il relè come uscita
  }
  
float F2x(){ //ho provato con una funzione esterna ma la frequenza viene incrementata continuamente lo stesso
  digitalWrite(Rele, HIGH); //metto sotto c2
  delay(2000);
  float F2 = 0;
  F2 =frq; //immetto il valore della funzione frq in f2
  return F2;
}
  
/*float calibF2(){ //tutto questo codice idem non funziona
  float F2=0;
  digitalWrite(Rele, HIGH);
  delay(2000); //eccito il Relè per inserire c2 e misurare F2
  //lcd.print("calibrazione attendere");
  F2 = frq;
  delay(2000);
  digitalWrite(Rele, LOW); //diseccito il Relè per togliere c2 misuro F1
  return F2;
  //return F1=frq;
  //delay(1000);
  //passo al calcolo di Cc e Lc note
  //Cc=((F2*F2)/((F1*F1)-(F2*F2)))*0.000000001015;
  //Lc=(1/(39.478417*(F1*F1)*Cc));
  //Fine calibrazione
  //lcd.setCursor(0, 1);
  //lcd.print(Cc);
  //lcd.setCursor(5 , 1);
  //lcd.print(Lc);
  //delay(100);
  //lcd.print("calibrazione terminata");
}*/


void loop() {
    digitalWrite(Rele, LOW);
    delay(2000);
    
    FreqCounter::f_comp = 106;
    FreqCounter::start(1000);
    while (FreqCounter::f_ready == 0)
    frq = FreqCounter::f_freq;
   // lcd.setCursor(0, 1);
    //lcd.print(frq);

    float c;
    c = F2x();
    lcd.setCursor(0, 1);
    lcd.print(c);
    digitalWrite(Rele, LOW);
     //lcd.setCursor(5 , 1);
     //lcd.print(Lc);
    
 
 }

Che intendi per ultimi ambienti di sviluppo arduino? Io quella lib la sto usando senza problemi particolari con l'IDE 1.0.1 ed è molto valida anche se si mangia tutti i timer

Ciao,
se vuoi c'è già un progetto che stiamo portando avanti, l'Ardutester.
http://forum.arduino.cc/index.php?topic=163227.0

Fa non solo da capacimetro (L'induttanzimetro e l'ESR meter lo sto implementando) ma altro. I sorgenti sono liberi e disponibili. Buona lettura. :smiley:

Quella libreria non mi da errori di compilazione con ambienti arduino a partire da 1.0, forse è un problema del mio sistema. Cmq come posso realizzare il codice? grazie del link, ma credo che sia un altro tipo di approccio questo è esattamente questo tipo di approccio..:

http://electronics-diy.com/lc_meter.php

proprio questo manca solo il codice. Che non so se si possa realizzare con librerie esterne ad Arduino...

Dimenticavo vorrei ringraziare Banzi e tutto il suo team, per aver realizzato questa magnifica opportunità che è appunto Arduino. Comunque so che esiste pulsein come libreria per la frequenza, perché però è limitata a pochi Hz ? Certo per non rinunciare ad altre porte, perché non inserite una libreria ufficiale più performante ? Con esempi ben illustrati anche se si dovesse rinunciare a qualche pin ben venga. Continuerò a scrivere e riprovare codice spero che qualcuno mi aiuti. Non ho problemi a mettere tutto il progetto schemi compresi qui sul forum. Una volta realizzato. Solo il tempo mi manca..ma se riesco a passare questo scoglio, posto tutto. È utile un induttanzimetro di "precisione" e se fatto con arduino ancora meglio e con più soddisfazione.

Ciao andrecost.
Esiste un regolamento che ti chiedo di leggere e di rispettare:
http://forum.arduino.cc/index.php?topic=149082.0

  1. è buona creanza presentarsi in un forum PRIMA di fare una domanda.
  2. Il codice si include usando gli appositi tag. Metterlo come hai fatto tu crea solo post inutilmente lunghi e soprattutto rende il codice stesso meno leggibile.
  3. NON SI SCRIVE IN MAIUSCOLO. Equivale a urlare.

Pardon se sono stato inappropriato, leggero il regolamento.

Cmq mi presento mi chiamo Andrea ho 31 anni, lavoro nella manutenzione, sono un semplice operaio cmq, ho un diploma di istituto tecnico, elettronica e telecomunicazione. Che dire purtroppo la scuola non mi ha insegnato molto, non sono mai stato bocciato, ma nel mio istituto, che ricordo io solo formule, le mani in pasta non ce le hanno mai fatte mettere, da qualche anno da autodidatta grazie ad Arduino, ho iniziato a sperimentare da solo, e devo dire con qualche piccola soddisfazione. Cmq…
Continuo a sbattere la testa con il codice, ho provato ad utilizzare un semplice while ma niente da fare posto il codice, non riesco a fissare F1 e F2 in quanto il codice viene sempre e continuamente ripetuto. Aiuto come fare… Chiedo a chi ne sa più di me… Ho un libro sul C, ben fatto. Ma è per il compilatore Windows, so che i micro per certi versi sono diversi, e questo while lo dimostra cmq il codice viene ripetutamente rielaborato, è come se alla fine del while esso si resetti e ricominci da capo. Per fissare due valori in due tempi T differenti su una porta del micro che li elabora continuamente con questo tipo di libreria come devo fare?
Posto il codice, grazie per le vostre eventuali risposte. :astonished:

#include <math.h>
#include <WProgram.h>
//#include <EEPROM/EEPROM.h>
#include <LiquidCrystal.h>
#include <FreqCounter.h>

boolean Rele = 7;
//const float C2 = 1000 * 1e-12; //teorico di 1000pF
//const float L1 = 100 * 1e-6; //teorico di 100uH
LiquidCrystal lcd(12, 11, 6, 4, 3, 2);
unsigned long frq;
float Cx, Lx, Cc, Lc, F1,F2; 
int i;

void setup() {
  Serial.begin(57600);
  lcd.begin(16, 2);//16 COLONNE e 2 RIGHE schermo LCD MODELLO HD44780
  lcd.print("Induttanzimetro");//scrivo 
  pinMode (Rele, OUTPUT);//imposto il relè come uscita
  }
  

void loop() {
    digitalWrite(Rele, LOW);
    delay(2000);
    FreqCounter::f_comp = 106;
    FreqCounter::start(1000);
    while (FreqCounter::f_ready == 0)
    frq = FreqCounter::f_freq;
    
    
    i=1;
    while(i<=3){
    lcd.clear();
    lcd.print("Calibrazione");
    F1=frq;   //frequenza 508 khz
    delay(1000);
    digitalWrite(Rele, HIGH);//eccito il relè per misurare F2
    delay(1000);
    F2=frq;  //frequenza 308 khz
    delay(1000);
    //fine calibrazione
    i++;
    }
    lcd.clear();
    lcd.print("fine calibrazione");
    
    digitalWrite(Rele, LOW);
    
    
    
    lcd.setCursor(0, 1);
    lcd.print(F2); //provo a visualizzare F2 per prova niente da fare il codice  non funziona
    
    
    lcd.setCursor(9, 1);
    lcd.print(frq);//
 }

ciao e benvenuto,
spesso qui faccio la parte del cattivo, non me la risparmio se credo che possa fare bene,
leggendo le tue considerazioni credo che sia meglio tu parta da progetti piu' semplici, affronta gli esempi dell'IDE a partire dai piu' semplici e studiati il reference.
Non puoi portare avanti questo progetto se chiedi ancora come stoppare le librerie :slight_smile:

spero non te la prenda
Ciao

Tranquillo non me la prendo. Ho realizzato progetti più semplici come il voltometro e amperometro di un alimentatore stabilizzato ad esempio. Tramite Arduino ecc, ovvio che devo imparare ancora molto, ma non mi sembra un progetto fantascientifico, diciamo che se avessi utilizzato qualche altro ambiente di sviluppo avrei utilizzato qualche Timer, io chiedo solo; data una libreria che acquisisce continuamente un valore su un pin. Come possa memorizzare in un dato istante, un valore in una variabile, quest'ultima non più modificabile, cosi che anche se la libreria scritta da terzi continua a immagazzinare un dato, io mi possa calcolare con le formule che so, le varie incognite, aggiungendo il valore della frequenza letta in quel dato momento, che corrisponde ad un nuovo componente o una capacità o una induttanza.. Guarda il circuito è bello che fatto, tramite la libreria riesco a leggere la frequenza esatta dei componenti, manca l'ultimo tassello di programmazione. Memorizzare la frequenza in un dato momento, il resto lo so scrivere..

La libreria FreqCounter effettua una sola lettura ad ogni ciclo di loop, ed impiega 1 secondo; se vuoi ottenere più letture all'interno del tuo loop, a mio modesto parere la devi spostare in una void e richiamarla ogni volta che ti serve. Così com'è tu effettui una sola lettura con frq = FreqCounter::f_freq; ed il valore di frq ti rimane quello finché non riparte il loop, peraltro dopo svariati secondi visto che hai inserito una marea di delay.

Ti ringrazio Michele per la tua dritta, un mare di delay è vero quando vai in palla, :). Potrebbe essere un idea, metterla in una funzione esterna e richiamarla quando serve, il contrario di quello che sto facendo ora, praticamente. Provo e ti faccio sapere, non ho neanche provato a farlo prima, perché negli esempi della stessa e da un progetto che avevo intravisto viene sempre inserita nel loop, tu consigli una void ma non dovrebbe essa stessa restituire un valore forse un float? Comunque ancora grazie, non tutti ti danno consigli, e comunque cercano di dare agli altri, io nel mio piccolo cercherò di dare quello che so. Ancora grazie.

Figurati :slight_smile: questo Forum è pieno di gente prodiga di consigli, poi bisogna vedere l’argomento. Io sto lavorando con quella lib da novembre ed ormai sono alla fine, ecco perché so come funziona, è vero che la funzione è nel loop ma è altrettanto vero che viene eseguita una sola volta per ogni ciclo di loop, quindi dopo la lettura della frequenza (che dura 1 secondo) nel tuo loop c’è tanta altra roba che viene eseguita e finché non finisce non c’è una nuova lettura, per cui se vuoi fare più letture nello stesso ciclo o replichi l’intero comando o meglio ancora metti le tre righe in una funzione/void per farti restituire il valore della lettura ogni volta che ti serve.
Io sto realizzando un frequenzimetro professionale e quindi ho fatto l’opposto: ho lasciato i soli comandi di lettura di frequenza in loop e spostato tutto il resto in diverse void, però nel mio caso (che mi pare differente dal tuo) io devo leggere costantemente la frequenza applicata in ingresso e quindi eseguo una lettura al secondo, ma non uso delay perché ritardano visivamente i cicli di lettura.

se ho capito il frequenzimetro di andrecost ad ogni misura, tramite il rele', prima misura una frequenza nota, e poi scambia i contatti e inserisce nel circuito il componente di test, e rimisura la frequenza.
Dalla differenza di questi valore ricava il valore del componente
quindi effettivamente la cosa migliore e' creare una procedura a parte che ti parte solo alla pressione di un pulsante.
Nel loop ti rimane solo il monitoraggio del pulsante

Ho solo detto con parole diverse quello che ha gia' detto Michele :slight_smile:

lui per la seconda lettura pilota un relé, nel quale si deve premurare di mettere prima il componente, è anche vero che questo relé ticchettirebbe in continuazione ed inutilmente, se così fosse, quindi l'idea di un pulsante che avvi la procedura una volta sola non è male, o meglio almeno un ciclo di tre volte, per come funziona la lib una sola lettura facilmente è imprecisa ed anche la seconda potrebbe sballare, meglio attentere la terza.