Ero indeciso se postare in hardware oppure in software, spostatelo dove ritenete sia meglio metterlo se non và bene quà in generale.
Ho provato le librerie FreqCounter e FreqMeasure con scarsi risultati, ho provato il metodo con pulseIn() alto o basso, sempre con risultati inattendibili.
Una volta che si conosce la frequenza, in un circuito LC o RLC parallelo o in serie, è possibile conoscere anche l'induttanza, tenendo fisso il condensatore.
In particolare a mè interessava leggere la reale induttanza di alcuni induttori che avevo costruito (per un metal detector) considerando il diametro del filo, il numero di spire, diametro induttore e la lunghezza totale e vedere se corrispondevano alle formule matematiche.
Online si trovano vari progetti per costruire un induttometro, ad esempio questo che fà anche una buona descrizione del funzionamento :
e che si basa poi nella misurazione del comando pulseIn()
In genere si basano sugli IC comparatori LM311 o LM 339, io ho ottenuto risultati migliori con LM311.
E qua metto un'immagine di LTSpice in cui si vedono il segnale in arrivo da Arduino, la sinusoidale generata dal circuito LC e il risultato all'uscita del comparatore.
Potete anche vedere i componenti utilizzati.
In blù il segnale di partenza proveniente da Arduino, in rosso la sinusoidale che si genera dal circuito LC e in azzurro il segnale che esce dal comparatore.
Come potete vedere, sin che il segnale della sinusoidale è sopra i 0 volt(non ho capito di quanto) il comparatore emette un segnale di onda quadra che facilita il nostro Arduino nella lettura di quanti segnali vengono emessi e a capire la distanza tra un segnale e il successivo.
Ma girando e leggendo le lamentele rispetto alle 2 librerie inizialmente menzionate, ho trovato una semplice soluzione che utilizza gli interrupt del Pin 2 e questa ha dato risultati decisamente migliori.
Bisogna prestare però molta attezione a quando cominciare la lettura di questi segnali, perchè il nostro LM311 amplifica anche i segnali di quando sale il segnale proveniente da Arduino e non solo quando scende, per cui il totale degli impulsi risulterebbe sbagliato.
Ho visto che attendendo 440 millisecondi dopo che il segnale proveniente da Arduino viene messo in off si ottiene una lettura precisa anche confrontandola con 2 oscilloscopi.
Se il circuito non fosse un circuito LC ma un oscillatore di Colpitts la cosa sarebbe più semplice, perchè basterebbe collegarlo ad una alimentazione fissa e lui continuerebbe a oscillare con la stessa intensità (non sarebbe una sinusoidale che và a zero una volta scaricato il condensatore), per cui utilizzando il timer potremmo capire quante oscillazioni esegue in un dato periodo, e più tempo dedichiamo al timer e più precisa sarebbe la lettura.
Ma il circuito di Colpitt richiede maggiore attenzione nei componenti utilizzati nella costruzione.
Purtroppo ho potuto verificare il funzionamento solo con induttori che vanno da 1000 uH a 3500 uH, non sò come si comporti con induttori minori o superiori a questi valori
Considerando che la tensione e la corrente vengono molto amplificate in un circuito LC (ho misurato anche 700 Volt non in questo circuito ma in uno per metal detector che partiva da un'alimentazione di 12 V e 40A partendo da 2A) ho scelto come condensatore un 1uF 250V che misurato mi dava 1.04uF.
Non ho messo una resistenza in uscita da Arduino per non impoverire la sinusoidale, ma cmq c'è un diodo prima di entrare nel circuito tank LC (che abbassa cmq la tensione di 0,5V e limita le oscillazioni avanti e indietro del circuito LC) e poi ho messo un diodo Zener per limitare l'eventuale uscita dal comparatore.
Ma se proprio volete stare sul sicuro potete usare un optoisolatore e inviare + tensione al circuito tank proveniente da una batteria ad esempio, per ottenere una sinusoidale + lunga nel tempo.
Se avete a disposizione induttori di cui conoscete la misura, postate pure i risultati quà.
E buon divertimento a tutti
// Connettere l'uscita del comparatore al pin 2 di Arduino (digital pin 2 on an Arduino Uno/Nano)
// per il segnale di start io ho utilizzato il Pin 10 che potete vedere in digitalWrite(10, HIGH); e in digitalWrite(10, LOW);
volatile unsigned long firstPulseTime;
volatile unsigned long lastPulseTime;
volatile unsigned long numPulses;
float inductance;
float capacitance = 0.00000104; //Farad del condensatore utilizzato 1.04uF
void isr() {
unsigned long now = micros();
if (numPulses == 0) {
firstPulseTime = now;
} else {
lastPulseTime = now;
}
++numPulses;
}
void setup() {
Serial.begin(115200);
pinMode(10, OUTPUT);
}
// Measure the frequency over the specified sample time in milliseconds, returning the frequency in Hz
unsigned int readFrequency(unsigned int sampleTime) {
numPulses = 0; // prime the system to start a new reading
attachInterrupt(0, isr, RISING); // enable the interrupt
delay(sampleTime);
detachInterrupt(0);
return (numPulses < 2) ? 0 : (1000000UL * (numPulses - 1)) / (lastPulseTime - firstPulseTime);
}
void loop() {
digitalWrite(10, HIGH);
delay(5); // carico il condensatore
digitalWrite(10, LOW);
delayMicroseconds(440);// <<<<<<< importante altrimenti vengoono conteggiati anche quando l'impulso sale
unsigned int freq = readFrequency(1000);
inductance = 1.0 / (capacitance * freq * freq * 4.0 * 3.14159 * 3.14159);// Farad
inductance *= 1000000L;// uF
Serial.print(freq);
Serial.print(" Hz Durata >> ");
Serial.print((lastPulseTime - firstPulseTime));
Serial.print(" Numero Impulsi >> ");
Serial.print(numPulses);
Serial.print(" Singolo Impulso >> ");
Serial.print(((lastPulseTime - firstPulseTime) / (numPulses-1)));
Serial.print(" uS Induttanza L >> ");
Serial.print(inductance,2);
Serial.println(" uH");
delay(1000);
}