Capacity Meter.....

cactusface

Senior Member
Hi,
I've been playing with the idea of building a Capacity (and inductance ) Meter, it seems that the maths will be the difficult bit, and perhaps we could do with 32bits.. to do something like 1/(PI*r*c). I know the Picaxe will only do integer, but there are ways around it. So I am looking for ideas, input or any general pointers.

If I build an osc from NAND gates using say a HC4011, and parallel CX the cap to be tested with the fixed C, there will be a change in FREQ, and I think this will be linear.

Other things to consider! should I measure FREQ or pulse width? One could make the maths easier?

Very basic schematic attached? change ext to .dch

Anything welcome..
Regards
Mel.
 

Attachments

hippy

Ex-Staff (retired)
A forum search on "capacitance meter" and similar should reveal past discussion.

As to measuring frequency or period, there may not actually be too much difference in the maths; you can rearrange and defer awkward parts such as 1/N or temporarily treat that as 10000/N. For period you'd have to measure high and low periods and combine the two but that isn't hard if it's stable.

For a PICAXE with comparators, you might not even need an external gate to create an oscillator.
 

AllyCat

Senior Member
Hi,

Most of the M2s have comparators if you don't mind using pokesfrs. Or you might make a reasonable oscillator by setting a PICaxe input (perhaps the hardware flip-flop) to Schmitt trigger mode and feed back via a charge/discharge resistor.

32 bit maths shouldn't really be necessary with proper scaling, but if you want 32 bit division look in the code snippets section. ;)

Cheers, Alan.
 

g6ejd

Senior Member
It's much easier to apply a pulse to a series RC circuit, where C is the Cx to be determined and measure the time it takes for an input to trigger a threshold or reach a particular voltage. For example if you use the expression Time-constant = R x C then regardless of applied voltage the value of voltage at 1 time constant (R x C in secs) = 63%, so this approach cancels out any voltage variations, assuming it remains largely constant during the measurement cycle (highly likely). As Hippy suggests this has been previously discussed. BTW you can apply a similar technique to an inductance.

In both cases, the maths is (relatively) easy to do with integers.
 

womai

Senior Member
Determining C and L by measuring the change in frequency of some resonant circuit is indeed one of the standard methods. Although the relationship is NOT linear:

f_osc = 1 / (2*PI*sqrt(L*C))

Unloaded (reference): L = L_ref, C = C_ref --> f_osc_ref
Loaded (parallel C_meas): L = L_ref, C = C_ref + C_meas --> f_osc_C
Loaded (series(!) L_meas): L = L_ref + L_meas, C = C_ref + C_meas --> f_osc_L

From f_osc_C (or _L) and f_osc_ref you can now calculate C_meas or L_meas.
 

cactusface

Senior Member
Hi Hippy and g6ejd,
Unless I've been very stupid (it happens) a forum search found absolutely nothing!! perhaps no one has given it a try before?? but I think that unlikely. I like the idea of using a comparator, Charging the cap to 1 or 2 time constants would be fairly simple. Not sure about poke and the SFRs, an instruction I've not made use of yet, but i understand it's working.

Thanks to all, keep them coming.
Regards
Mel.
 

Dippy

Moderator
Have you actually tried hippy's suggested seacrh term?

I did and got more hits than I could shake a stick at....

http://www.picaxeforum.co.uk/showthread.php?21126-Capacity-amp-Inductance-meter&highlight=capacitance+meter
http://www.picaxeforum.co.uk/showthread.php?13933-Coil-amp-Capacitance-Meter&highlight=capacitance+meter
http://www.picaxeforum.co.uk/showthread.php?11991-Capacitance-meter&highlight=capacitance+meter

... and so many more. I'm afraid I haven't got as much time as Eclectic but I'm sure you can find something???

I haven't read them - that's your job. I'm sure you can find something useful amonst them.
 

cactusface

Senior Member
Hi Dippy,
Sure did! but thanks, that's given me a few things to look in to and try. Some seem very simple but useful as you say, non of us have time to waste, so don't come shaking your stick at me.
Thanks and regards
Mel.
 

g6ejd

Senior Member
Thanks Dippy, I now recall the process is even easier, viz:

As the expression LN(1/(1-Vo/Vin)) is a constant if the reading always stops at 3.162V and the supply is 5V, then the equation becomes:

C = t / R and simple integer maths will give a close enough result. The LN bit equates exactly to 1 at that 3.162 volts reading, so just keep testing your ADC until that value is reached and then take the timer value. Some folks will see that the result is the time constant of an RC series network i.e. T = CR

To get a measurement, choose your inout and output pins, wire your reference R to the output pin, start a timer running, then measure the voltages using an ADC on your chosen input pin which is the junction of the R-C, until it reaches the value above and then take a time reading, then simply divide the time value by R = C all independent of supply voltage and no need to do a LN or other such complex maths.
 
I'm measuring small value capacitors (5 to 500pF) as part of a piece of test equipment using a method based on a Colpitts oscillator and controlled by a PICAXE 28X2. Three frequency measurements are made, one with the unknown value capacitor, a second with a reference capacitor of known value (in my case 220.0pF) and a third measurement with no capacitor. The value of the unkown capacitor can be calculated in terms of the reference capacitor and the three frequencies. The value of the inductor and feedback capacitors in the oscillator do not appear in the equation. The nominal frequency of the oscillator is about 5MHz but the PICAXE can't handle such a high frequency and so I divide it by 400 and use the COUNT facility with the PICAXE running with a 32MHz clock. For this equipment I use relays to switch the capacitors.

To make the calculations I use the uMFPU-V2 maths co-processor and display the result on an OLED display or send the results to EXCEL.

This method is useful for measuring small value capacitors and can be used to measure small inductors (nH to tens or hundreds of uH). It is used in the AADE LC-meter.

Richard
 

cactusface

Senior Member
That sounds workable...

Hi g6ejd,
That sounds like a good way of doing things, but I have no experience of poking!! That is I've never used the Poke instruction especially with the SFRs So just how do I set a timer to 00 then start it, stop it and recover the count. The maths seems quite easy, thanks to that constant.

@ szd51pilot,
you seem to have got it right, and a Cap-meter is perhaps most useful on small values, so any chance I can see your schematic or code that drives it?? It would give me a bit more to work on.


Just a thought but what about a small FET across CX to discharge it, when done? or take 3 readings and go for the average.

I will perhaps be using a Picaxe 20m/x2 as I have this to hand, or the 28x2 on the Shield! if I can squeeze the circuit on to a shield sized PCB.

Regards
Mel.
 
Last edited:

cactusface

Senior Member
Will this basic cct work?

Hi g6ejd,
Is this the kind of thing you have in mind?? The FET is a small 2n7000 with an on RD of about 2R max, so I thought it could be used to fully dischange CX before and/or after the reading is taken, but I can live without it.
It's not the hardware that's the problem it's the programming and the SRFs, etc. Must look up the inductance bit too.

Here's my basic idea of what I hope to do....

All advice and opions welcome.
Regards
Mel.
 

Attachments

AllyCat

Senior Member
Hi Mel,

Personally I'd leave out the FET as it potentially adds additional capacitance to the measurement (but I haven't looked at its data sheet). I think you can just use the output driver on the PICaxe pin to successfully discharge the capacitor.

Cheers, Alan.
 

g6ejd

Senior Member
Hi Mel,

Yes, but as Alan suggests, just leave out the FET and R2, then after the measurement completes set the output low (assuming you don't want to repeatably read the value at speed) and let the 100K discharge the Cx.

David
 

cactusface

Senior Member
This seems just too simple, but then!

Hi Ally & Dave,
Yes I forgot about the fet's gate capacity, quite low I would think but could be significant with small values (but could be nulled out?). Pulling the output pin low would provide a discharge path back thro' R1.
I still need a guide to setting the timer via pokesfrs.As the expression LN(1/(1-Vo/Vin)) is a constant if the reading always stops at 3.162V and the supply is 5V, then the equation becomes:

As the expression LN(1/(1-Vo/Vin)) is a constant if the reading always stops at 3.162V and the supply is 5V, then the equation becomes:

C = t / R and simple integer maths will give a close enough result. The LN bit equates exactly to 1 at that 3.162 volts reading, so just keep testing your ADC until that value is reached and then take the timer value. Some folks will see that the result is the time constant of an RC series network i.e. T = CR

To get a measurement, choose your inout and output pins, wire your reference R to the output pin, start a timer running, then measure the voltages using an ADC on your chosen input pin which is the junction of the R-C, until it reaches the value above and then take a time reading, then simply divide the time value by R = C all independent of supply voltage and no need to do a LN or other such complex maths.
This method seems so simple really, and I want to give it a try! but I'm stuck on setting the internal timer, which is what I assume we're talking about, could really do with a bit of coding advice or a lead in the right direction. Wonder if I could do something similar for inductance??

Thanks again, regards
Mel.
 
Hi g6ejd,
That sounds like a good way of doing things, but I have no experience of poking!! That is I've never used the Poke instruction especially with the SFRs So just how do I set a timer to 00 then start it, stop it and recover the count. The maths seems quite easy, thanks to that constant.

@ szd51pilot,
you seem to have got it right, and a Cap-meter is perhaps most useful on small values, so any chance I can see your schematic or code that drives it?? It would give me a bit more to work on.


Just a thought but what about a small FET across CX to discharge it, when done? or take 3 readings and go for the average.

I will perhaps be using a Picaxe 20m/x2 as I have this to hand, or the 28x2 on the Shield! if I can squeeze the circuit on to a shield sized PCB.

Regards
Mel.
Mel,

The method to use depends on the range of values that you expect to measure. For small values of capacitance and inductance, e.g. picofards and micro-henries, the oscillator method that I use works very well but requires a lot of additional circuitry. For larger values of capacitance the time constant method should work well enough and will be a lot simpler. The calculations are much more complex for the oscillator method, requiring the ratios of the squares of the measured frequencies to be calculated but this is not a problem if the uM-FPU floating point processor is used.

Richard
 

g6ejd

Senior Member
Short of time tonight to code this properly, but the basic logic is:

1. Set Port High ; to start the measurement
2. Settimer count 65535 ; settimer to count mode, counting down or up I can't remember? Check manual
3. :loop
4. READADC input port, reading
5. If reading < 41444 then goto loop ; (value derived from 65535 * 3.162/5) assumes 5V supply, an ADC value that is 65535 at 5V and 0 at 0V.
6. Cx_relative_value = 65535 - timer ; 'timer' is an internal variable name that gives timer value
7. Cx = Cx_relative_value / R ;value will be directly in Farads, so the result will need to be scaled.
7. Set Port Low
7. Done
 

mrburnette

Senior Member

cactusface

Senior Member
Hi g6ejd,
Thanks for the coding idea, but how can I get an ADC value of 65535 at 5v, with only 10 bits=1023, using readadc10.
I am going to give it another try tomorrow, but my eyes hurt.. too much PC. A little more please, someone!
Regards
Mel.
 

g6ejd

Senior Member
Sorry my mistake, it's 1024 not 65535
5. If reading <647 then goto loop ; (value derived from 1024 * 3.162/5) assumes 5V supply, an ADC value that is 1024 at 5V and 0 at 0V.
6. Cx_relative_value = 65535 - timer ; 'timer' is an internal variable name that gives timer value
 

cactusface

Senior Member
Hi g6ejd,
I thought that was'ent quite right! I'll give it another go soon, but I often get only 0 or 1 from the timer value, think I should get more? perhaps the 65535 on settimer needs setting lower? so it rolls over quicker, or is 65535 quicker?
It seems after reading the manual a few times, that settimer count sets the counter for an external count on a pin! but settimer 65535 is what I need? But I still can't get anything that makes sence!!

The adc reading always comes back at 800+ despite checking for <647 and the timer value is about 21 at most.

Here's my code..

Code:
; *******************************
;    Filename:	Capmeter-3 		
;    Date: 		26/07/2012	
;    File Version: 	
;    Written by:	MS 		
;    Function:		
;    Last Revision:
;    Target PICAXE:20X2	
; ******************************* 

#rem
Short of time tonight to code this properly, but the basic logic is:

1. Set Port High ; to start the measurement
2. Settimer count 65535 ; settimer to count mode, counting down or up I can't remember? Check manual
3. :loop
4. READADC input port, reading
5. If reading < 41444 then goto loop ; (value derived from 65535 * 3.162/5) assumes 5V supply, an ADC value that is 65535 at 5V and 0 at 0V.
6. Cx_relative_value = 65535 - timer ; 'timer' is an internal variable name that gives timer value
7. Cx = Cx_relative_value / R ;value will be directly in Farads, so the result will need to be scaled.
7. Set Port Low
7. Done 


    Sorry my mistake, it's 1024 not 65535
    5. If reading <647 then goto loop ; (value derived from 1024 * 3.162/5) assumes 5V supply, an ADC value that is 1024 at 5V and 0 at 0V.
    6. Cx_relative_value = 65535 - timer ; 'timer' is an internal variable name that gives timer value 


#endrem


#picaxe 20x2
;setfreq m16

dirsC=%10000000

start:

pause 500
serout C.0,t2400,(254,128,1)		'clear LCD
pause 100
serout C.0,t2400,(254,192,1)		'clear LCD
pause 100

let pinC.7=1				'start charging CapX

settimer 65531

do 
readadc10 c.1,w1				'read adc until 63% charge
loop while w1 <647 

serout C.0,t2400,(254,128,#w1,"    ",#timer)

calc:
w10=65535-timer
w11=w10/10000				'Charging R = 10K
w12=w11*1000

serout C.0,t2400,(254,192,#w10,"  ",#w11,"  ",w12)
pause 50
let pinC.7=0
pause 200

Regards
Mel.
 
Last edited:

g6ejd

Senior Member
What value R and C are you using, select something that enables easy testing and you have to do the Mathis to check what the result should be. For example 1K and 1uF is 1ms, so at 16mhz, check what time is one timer count value. For trial purpose slow things down to get it all working, leave out 16mhz option for example. Make sure your c is discharged before the reading.
 
Top