pekka1234
Joined: 28 May 2017 Posts: 97
|
A capacitor meter solved |
Posted: Sat Jun 21, 2025 3:09 pm |
|
|
This is my code:
Code: |
/*
Capacitance meter from 0 pF to 3300 uF (or over, but I have not bigger)
It has an inverted serial output with 115200 baud. Also available an LCD 1/2 row
It measures with an internal comparator module's time, when PIN_A1 exceeds the reference voltage.
The measured capacitor is placed between PIN_A0 and GND,
The R_PULL resistor is selected before measuring.
Code: Pekka Ritamaki, Tampere. Finland. oh3gdo@gmail.com
The voltage is 5V. No pull-up resistor is needed.
*/
#include <18F2620.h>
#fuses INTRC_IO, NOWDT, NOMCLR, NOLVP
#use delay(internal=8MHz)
#use rs232(baud=115200, xmit=PIN_C6, rcv=PIN_C7, invert)
#define LN_FACTOR 0.875f // LN_FACTOR = ln(Vcc/Vref)
float OFFSET =0.000034 ; // 32pF This removes internal resitance
#define CMCON (*(volatile unsigned char*)0xFB4)// These are found Microchip PI18F2620 pages 241 and 64
#define CVRCON (*(volatile unsigned char*)0xFB5) // Set refence voltage to compator
unsigned int32 overflows,// this measure whem timer1 overflows 65536
first, // This measure time after when the voltage starts to rise, it is near 0
second ; // This is the stop time after the voltage is over the reference voltage
//#define CALIBRATE 1.0 not needed anymore
// This interrupt counts us after timer1 overflows -> 65536
#INT_TIMER1
void timer1_isr() { overflows++; }
// The main code
void main() {
float t_us, C_uF;
setup_adc(ADC_OFF);
set_tris_a(0xFF); // Put all the A pins to an input mode
CMCON = 0b00000010; // C1+: RA0, C1-: RA1 Inportant compartor mode read page 241
//set the Timer1
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
enable_interrupts(INT_TIMER1); // enable the timer2 interrupt
enable_interrupts(GLOBAL); // enable all interrupts
setup_comparator (A0_VR_A1_VR); // set compator mode. important
CVRCON =0b10001011;// page 241 PIC18F3620 set vref voltage to 3,75V
while(1){
printf("Start\r");
// …discahege and timer1 reset
// Set the measured capacitor to zero voltage
output_low(PIN_A0);
delay_ms(500); // a small time to discharge big capacitors
overflows = 0; // reset INT_TIMER1 interrupt output time
output_float(PIN_A0); // Leave the measure pin as floating
set_timer1(0); // Reset time measuring output
first = get_timer1() + ((unsigned int32)overflows << 16);// save timer1 ouput
while (CMCON & 0x40); // this is very important, it keeps the capacitance charging to Vref
// save charge time + interruot times
second = get_timer1() + ((unsigned int32)overflows << 16);
printf("First %lu\r", first); // show how much is the starting time
printf("Second %lu\r", second); // show how much is the stopping time
printf("LN_FACTOR %f \r",LN_FACTOR); // how mich is LN_FACTOR
t_us =(float) (second - first) * 4.0f; // calculate the time difference
printf("Diffrence %f us\r", t_us);
// Calculate how big the measured capacitor is as uF
C_uF = (t_us * 1e-6f) / (R_PULL * LN_FACTOR) * 1e6f;
// Show the serial code what the result is
printf("t=%.0f us, C=%.3f uF\r\n", t_us, C_uF);
}
} |
|
|