 |
 |
View previous topic :: View next topic |
Author |
Message |
pekka1234
Joined: 28 May 2017 Posts: 91
|
Capactor meter |
Posted: Tue Apr 29, 2025 10:22 am |
|
|
Hey, I am doing a capacitor meter with PIC16F886 with internal oscillator (8MHz). I am using v5.119 compiler with a serial meter. Now I use 90uF capacitor between A0 and gnd. I have a 100k charge resistor from A1 to A0
I tried ti use comparator in A0 and A1 , but the comparator doen't go to high. It gives a similar value all the time." time: 15611 tiks (62.44 ms)". I have put the timer1 to zero. Is my comparator wrong values or what is the reason?[code]
#include <16F886.h>
#device ADC=10
#include <stdlib.h>
#FUSES NOWDT, INTRC_IO, NOPROTECT, NOBROWNOUT, NOPUT, NOCPD
#FUSES NODEBUG, NOLVP, NOWRT, NOFCMEN, NOMCLR, BORV21
#use delay(internal=8MHz)
#use rs232(baud=9600, parity=N, xmit=PIN_C6, rcv=PIN_C7, bits=8, invert, errors)
#define CHARGE_PIN PIN_A1 // Chargepin (RA1)
#define SENSE_PIN PIN_A0 // Measuring pin (RA0, AN0 ADC:lle)
#byte CMCON0 = 0x9C
void main() {
unsigned int16 time;
float capacitance;
setup_oscillator(OSC_8MHZ);
while (TRUE) {
//discharge
output_low(CHARGE_PIN);
output_low(SENSE_PIN);
set_tris_a(0); // A0 ja A1 output
delay_ms(500);
// set A0 input
set_tris_a(0xFF); //all input
output_high(CHARGE_PIN); // start charge
// set comparator off
CMCON0 = 0x07; //
setup_vref(VREF_HIGH | 22); // set Vref about 3.4V (22/32 * 5V)
// set comparaattor to use: A0 on (+), Vref on (-)
CMCON0 = 0x03; // use comparator A0 and Vref
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8); // 1 tiks = 4 µs
set_timer1(0);
// until A0 > Vref (comparaator OUT = 1)
while (!bit_test(CMCON0, 6)) //comparaato rOUT-bit = 1 untill A0 > Vref
printf("time: %lu tiks (%.2f ms)\r\n", time, time * 4.0 / 1000.0);// this doen't update
time = get_timer1(); // 4 µs per tikki
printf("Time: %lu tiks (%.2f ms)\r\n", time, time * 4.0 / 1000.0);
// count capacity (t = R * C ? C = t / R)
capacitance = ((float)time * 4e-6) / 100000.0; // C = t / R
capacitance *= 1e6; // µF
printf("capacitance: %.2f uF\r\n", capacitance);
delay_ms(2000);
}
} [code]
[/code] |
|
 |
Ttelmah
Joined: 11 Mar 2010 Posts: 19803
|
|
Posted: Wed Apr 30, 2025 1:30 am |
|
|
First thing the comparator Vref only has 16 levels in each range. The range
is controlled by bit 6 in the setup. You are turning this on with VREF_HIGH,
but can then only OR this with 0-15, not 22 as you are using. Currently
this will be selecting (With Vladdder set to Vdd), about 2.2v, not the 3.4
you say.
Basically the two ranges are (for 5v)
(0..15)/25 * 5 -> gives 0 to 3v
or
1.25 + (0..15 * 0.15625)
Now in your case, the top bit of what you give will be ignored, so you are
inputting '6', so 0.9375+1.25v = 2.1875v
14 will give just over 3.4v (3.4375nominal).
Then consider using the CCS functions rather than going DIY. Where did you
get the address for CMCON?????
Address 0x9C, is ECCPAS. I suspect you have copied code written for
a different chip, and are writing to completely the wrong register. Hence
it does not work..... This may explain the Vref setup value as well. |
|
 |
pekka1234
Joined: 28 May 2017 Posts: 91
|
Capaitor meter |
Posted: Wed Apr 30, 2025 1:32 am |
|
|
I continue that capacitance meter.
I got it working with interrupt (Timer1())
Here is a serial output from 1nF capacitor
Calib Cap ,. : 0.0010162 uF
Also I got LCD output
T:15244 uS
C:0.001016292 nF
Here is the code
[/code]
#include <16F886.h>
#device ADC=10
#include <stdlib.h>
#include <float.h>
#FUSES NOWDT, INTRC_IO, NOPROTECT, NOBROWNOUT, NOPUT, NOCPD
#FUSES NODEBUG, NOLVP, NOWRT, NOFCMEN, NOMCLR, BORV21
#use delay(internal=8MHz)
#use rs232(baud=9600, parity=N, xmit=PIN_C6, rcv=PIN_C7, bits=8, invert, errors)
#define calibrate 15.0
#include "Flex.c"
#include <float.h>
#define SENSE_PIN PIN_A0 // cap other end
#define CHARGE_PIN PIN_A1 // res 100kO A1 -> cap
#byte CMCON0 = 0x9C
unsigned int16 update=0; // update 65536 pulses
#int_timer1
void timerinterrupt ()
{
update++;
}
void main() {
unsigned int32 t,sec;
float C_uF;
lcd_init();
printf("Measuring starts...\r");
printf(lcd_putc,"\fCap meter");
printf(lcd_putc,"\nTime 0s" ) ;
enable_interrupts(INT_TIMER1 ) ;
enable_interrupts( GLOBAL);
while (TRUE) {
// discharge
output_low(CHARGE_PIN);
output_low(SENSE_PIN);
set_tris_a(0x00); // all outouts
delay_ms(1000);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8); // 4us/ticks
set_tris_a(0x01); // A0 input
output_high(CHARGE_PIN); // charge starts
set_timer1(0);
update=0;
while (!input(SENSE_PIN) ) // wait trigger
if( get_timer1() <100){
sec= calibrate*65536;
printf(lcd_putc,"\fTime %lus", sec*4) ;
}
t =(unsigned int32) get_timer1()+update*65536 ;
printf("Timer1: %lu ticks\r\n", t);
// count capacitanse (µF) when R=100kO ja 1 ticks = 4 µs
C_uF = ((float)t * 4.0) / 1000000.0;
printf("Cap: %.7f uF update %lu T=%lu\r\n", C_uF,update,t*4 );
printf("Calib Cap ,. : %.7f uF\r\n", C_uF /calibrate);
printf( lcd_putc,"\fT:%luus",t*4 );
printf( lcd_putc,"\nC:%.7fnF",C_uF /calibrate);
delay_ms(3000);
}
} [code] |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|