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 support@ccsinfo.com

Initial CVD library for PIC 12LF1552

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

Initial CVD library for PIC 12LF1552
PostPosted: Sun Feb 09, 2014 4:50 am     Reply with quote

This is a basic library to use the hardware CVD functions on this chip.
Doesn't allow all options, but single or double sampling, with or without guard output(s).

Simple 'main' function to show it, and the include file with the driver:
Code:

//main
#include <12LF1552.h>
#device ADC=10

#FUSES NOWDT                   //Watch Dog Timer disabled
#FUSES NOBROWNOUT        //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#fuses NOMCLR                   //MCLR for I/O

#use delay(internal=16000000)
#include <caplib.c> //library

void main()
{
   //demonstration of using the caplib library to sense capacitance on A0
   int16 reading;
   //Now configure the capacitor sense system
   setup_guard(GUARD_BOTH); //double pins enabled
   setup_sense(PIN_A0, ADC_CLOCK_DIV_16, CAPS4PF, DOUBLE_SAMPLE);
   //reading PIN_A0 - double sampled, 4pF extra internal capacitance
   
   port_a_pullups(0b00001000); //anabling pull-up on A3 only   
   delay_us(10); //ensure MCLR pin has settled.

   while (TRUE)
   {
       delay_ms(20); //50 reading per second approximately.
       reading=cap_sense();
       //reading drops with extra capacitance
       //do what you want with the value here....
   }
}


Now the actual drive code 'caplib.c'.
Code:

//code for using the hardware cvd, on PIC12LF1552

//Configuration defines
#define GUARD_OFF 0  //guard disabled
#define GUARD_A5 1  //Single fuard from pin A5
#define GUARD_BOTH 2  //Twin guard, second inverted
//Guard ring control

//These cover the three most likely configurations....
#define PRECHARGE 10 //Times for precharge and acquire - adjust as required
#define ACQUIRE 10 //In instruction cycles 0 to 127
//Times

#define CAPS0PF 0
#define CAPS4PF 1
#define CAPS8PF 2
#define CAPS12PF 3
#define CAPS16PF 4
#define CAPS20PD 5
#define CAPS24PF 6
#define CAPS128PF 7 //Valsue to select extra internal capacitance
//Capacitances

#define AD_OUT 16
#define AD_OUT_OVERRIDE 8
//enable the ADOUT pin, and override
#define POLARITY_HIGH 64
#define POLARITY_LOW 0
//select the charging polarity - only supporting internal pre-charge
#define SINGLE_SAMPLE 0
#define DOUBLE_SAMPLE 1
//select between performing single sample, and automatic double sample
//Default this to inverted polarity
//several options ignored here since not needed for typical application...

//register definitions
#byte aadcon0=getenv("SFR:AADCON0")
#byte aadcon1=getenv("SFR:AADCON1")
#byte aadcon2=getenv("SFR:AADCON2")
#byte aadcon3=getenv("SFR:AADCON3")
#byte aadstat=getenv("SFR:AADSTAT")
#byte aadpre=getenv("SFR:AADPRE")
#byte aadacq=getenv("SFR:AADACQ")
#byte aadgrd=getenv("SFR:AADGRD")
#byte aadcap=getenv("SFR:AADCAP")
#byte aadres0l=getenv("SFR:AADRES0L")
#byte aadres0h=getenv("SFR:AADRES0h")
#byte aadres1l=getenv("SFR:AADRES1L")
#byte aadres1h=getenv("SFR:AADRES1h")
//now bits
#bit ADON=aadcon0.0
#bit GO=aadcon0.1

void setup_guard(int8 rings)
{
   //routine to setup the guard rings
   switch (rings)
   {
   case GUARD_OFF:
      //disable guard rings
      aadgrd=0;
      output_float(PIN_A5);
      output_float(PIN_A4);
      break;
   case GUARD_A5:
      //single ring driven by A5 only - normally for single sampling
      aadgrd=0b10000000;
      output_float(PIN_A4);
      output_drive(PIN_A5);
      break;
   case GUARD_BOTH:
      //both rings enabled, - normal for double sampling
      aadgrd=0b11000000;
      output_drive(PIN_A4);
      output_drive(PIN_A5);
      break;
   default:
      //disable rings as default
      aadgrd=0;
      output_float(PIN_A5);
      output_float(PIN_A4);
      break;
   }
}

void setup_sense(int16 pin, int8 clock, int8 caps, int8 mode)
{
   int8 temp_int;
   //routine to setup to sample the input capacitance. Requires:
   //pin number, ADC clock selection (CCS defines), extra capacitance,
   //and settings for the mode to use (defined above).
   //typical: setup_sense(PIN_A0, ADC_CLOCK_DIV_16, CAPS4PF, DOUBLE_SAMPLE);
   //first ensure pin TRIS is 0
   output_low(pin);
   //then setup the ADC
   temp_int=(pin & 7)*4; //generates the selection value needed in AADCON0
   aadcon0=temp_int; //enable the adc pin
   setup_adc(clock); //and select clock
   //now set the timings and capacaitance
   aadpre=PRECHARGE;
   aadacq=ACQUIRE;
   aadcap=caps;
   //now configure the actual sampling.
   //allowing single or double sampling, ADOUT enabled or disabled, and
   //control of it's polarity. However setting some other things 'automatically'
   aadcon2=0; //no triggers enabled
   temp_int=mode | 2; //invert second sample if double conversion used.
   aadcon3=temp_int;
}

int16 cap_sense(void)
{
   //routine to read the ADC value returned by the capacitance on selected pin
   signed int16 first,second;
   signed int16 delta; //offset to ensure result is +ve
   GO=TRUE; //enable the ADC
   do ;
   while (GO==TRUE);
   //here a conversion has completed
   first=make16(aadres0h,aadres0l); //always OK
   second=make16(aadres1h,aadres1l); //only valid if double conversion enabled
   if (bit_set(aadcon3.0))
   {
      //here double conversion is enabled
      //The second reading is counting down from 1023, the first up from zero
      delta=first;
      delta+=1023-second;
      //delta now could be 0 to +2046
      return delta/2; //return the two values averaged.
   }
   return first; //return the single reading is single sampling
}


Currently using this with a about 25mm sensor ring, surrounded by a guard ring (twin resistor feed off the two guard outputs), and then surrounded by an earth plane, to detect fluid inside a PTFE pipe. With an exponential moving average, and very slow automatic drift compensation, seems to be running well... Smile

Hope somebody who wants to use this hardware CVD, finds it useful.

Best Wishes
dyeatman



Joined: 06 Sep 2003
Posts: 1910
Location: Norman, OK

View user's profile Send private message

PostPosted: Sun Feb 09, 2014 9:14 am     Reply with quote

Great contribution! Looking at using this for a fountain level sensor I have in the works.

Thank You!
_________________
Google and Forum Search are some of your best tools!!!!
acm45



Joined: 29 Dec 2008
Posts: 18
Location: Italy

View user's profile Send private message

PostPosted: Mon Oct 03, 2016 5:06 am     Reply with quote

Hi all,

I'm using the CVD library and it works nicely, as the reading is a little bit noisy I used an exponential moving average that solved the problem.
Now I'm facing another issue related to the cap_sense() reading, it drifts with the time so I can't set a fixed threshold.
I don't understand why the reading is changing even if the sensor is in a steady condition (glued in the back of a ABS panel).
Any advice?

Thank you

Regards
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Tue Oct 04, 2016 1:15 am     Reply with quote

I've used an approach on another system, where the lowest reading recorded over a long time, is automatically used to update the calibration point. So if this goes below the recorded point, it updates straight away, while if over an hour it never drops below a particular value, the calibration is drifted up towards this new level.

You do need something like this, or a user calibration, otherwise 'long term', drifts in dirt on the keypad, humidity, and temperature all cause drift.
Remember also that the system is always measuring the relative capacitance, and the level it is relative 'to', includes the capacitance of the traces to the sensor, the PCB, the pins etc. I've had significant problems with FR4 PCB's having really bad long term drift (actually made hugely worse by modern production techniques involving water cleaning).

Some glues do shift noticeably in capacitance over a long time.
mutthunaveen



Joined: 08 Apr 2009
Posts: 100
Location: Chennai, India

View user's profile Send private message

what is CVD??
PostPosted: Tue Oct 04, 2016 2:05 am     Reply with quote

Can some one explain what is CVD??
acm45



Joined: 29 Dec 2008
Posts: 18
Location: Italy

View user's profile Send private message

PostPosted: Tue Oct 04, 2016 4:33 am     Reply with quote

Thank you Ttelmah,
your answers are always clear, I will study and implement an adapatative threshold as you suggested me.

Best Regards
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

Re: what is CVD??
PostPosted: Wed Oct 05, 2016 4:03 am     Reply with quote

mutthunaveen wrote:
Can some one explain what is CVD??


Stands for 'Capacitive Voltage Divider'.
In this context, it's a way of measuring relative capacitances using an ADC. So allows for things like touch pads.

There are two different PIC hardware modules to do such measurements, the CTMU, and the CVD. CCS supplies code for the CTMU module, but not for the CVD. The code here is for chips with the CVD. The CTMU is more accurate, using 'time' to do the basic measurement.

You can also implement CVD measurements just using software.
mutthunaveen



Joined: 08 Apr 2009
Posts: 100
Location: Chennai, India

View user's profile Send private message

Thank you
PostPosted: Wed Oct 05, 2016 9:57 pm     Reply with quote

Thank you for your kind explanation Ttelmah.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library 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