CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Capactor meter

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
pekka1234



Joined: 28 May 2017
Posts: 91

View user's profile Send private message

Capactor meter
PostPosted: Tue Apr 29, 2025 10:22 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Apr 30, 2025 1:30 am     Reply with quote

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

View user's profile Send private message

Capaitor meter
PostPosted: Wed Apr 30, 2025 1:32 am     Reply with quote

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]
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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