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

ADC fluctuation PIC16F88
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
skoberlink



Joined: 27 May 2010
Posts: 52

View user's profile Send private message

ADC fluctuation PIC16F88
PostPosted: Thu Jul 22, 2010 9:51 am     Reply with quote

I'm using a PIC16F88 to read an analog signal and move a motor to a percent of it's range based on that analog signal. I wrote my own function for handling the conversion to avoid using the CCS built-ins. It reads almost properly.

The problem is my motor goes to the right place but then twitches back and forth. If I average several reads and put in a tolerance value for movement (i.e. only move if it has to move at least a certain distance) then the twitching goes away but this significantly reduces my precision. The signal into the PIC is rock solid at exactly the values it's supposed to be.

Any ideas on what might be happening and how to fix it? Here's my read function in case you guys can spot anything:

Code:
unsigned long analog_in(unsigned char channel){
   unsigned long result = 0;
   channel &= 0b00000111; // truncate channel to 3 bits
   ADCON1 = 0x80;
   ADCON0 = 0b11000000; //clear channel
   ADCON0 |= (channel<<3); // apply new channel select
   ADON = 1; //turn it on
   delay_us(30); //let it settle
   ADGO = 1; //initiate conversion
   while (ADGO) continue; // wait for result
   result = (ADRESH<<8);
   result |= ADRESL;
   return result; // return 10 bit result
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jul 22, 2010 11:17 am     Reply with quote

What's your compiler version ?
SherpaDoug



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

PostPosted: Thu Jul 22, 2010 11:24 am     Reply with quote

Look at the numbers coming out of the A/D. How much do they vary? If it is +/- 1 count, that is the best you can do. Is it mostly +/- 1 count with occasional bad values? If so look for something else in the system that happens when the bad value occurs that might be causing it. Also search for "Olympic averaging". It is computationally cheap and good at removing occasional bad values. At the cost of a few more clock cycles and RAM you can also do a "median filter".

On the hardware end make sure your A/D reference is as clean as your signal. One is useless without the other. Double check your grounding.

I will leave your code to others to inspect. It looks OK to me, but I don't use the internal A/Ds much.
_________________
The search for better is endless. Instead simply find very good and get the job done.
skoberlink



Joined: 27 May 2010
Posts: 52

View user's profile Send private message

PostPosted: Fri Jul 23, 2010 8:21 am     Reply with quote

@PCM Programmer
Compiler version is CCS 4.106

@SherpaDoug
I haven't checked the A/D output but it occurred to me while reading your response that this might be the issue. It's a stepper motor and I've been using steps as my tolerance value but the number of steps in one percentage point would change depending on the range of motion given to the motor.

But I'm just thinking "out loud" now. If I'm still having an issue those averages you mentioned looked useful. Also all signals including the reference are clean.

I'm guessing that checking the percent for tolerance instead of the number of steps will fix it. It seems kind of obvious and stupid now...lol
skoberlink



Joined: 27 May 2010
Posts: 52

View user's profile Send private message

PostPosted: Fri Jul 23, 2010 8:56 am     Reply with quote

Well that did not solve it. It was an issue that needed to be fixed but I still get the twitching in the motor. I'll try some of the other average methods mentioned but I'm still open to other suggestions if you guys have any.

EDIT: btw I tried several tolerance values. The ADC reads are +/- at least 10 probably significantly more.
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Fri Jul 23, 2010 10:01 am     Reply with quote

It is well worth triple checking how 'rock solid' the input values really are.
A scope for example, will see a signal as 'flat line', that can easily have 10 steps when read with the ADC. Simple DVM's also tend to integrate values, and will not see high frequency noise. If you are using the PIC supply as your 'ref', this _will_ have HF noise on it. The Vref really needs to be from a separate source, and well decoupled, if this is not to be a problem...

Best Wishes
skoberlink



Joined: 27 May 2010
Posts: 52

View user's profile Send private message

PostPosted: Fri Jul 23, 2010 10:06 am     Reply with quote

Ttelmah wrote:
It is well worth triple checking how 'rock solid' the input values really are.
A scope for example, will see a signal as 'flat line', that can easily have 10 steps when read with the ADC. Simple DVM's also tend to integrate values, and will not see high frequency noise. If you are using the PIC supply as your 'ref', this _will_ have HF noise on it. The Vref really needs to be from a separate source, and well decoupled, if this is not to be a problem...

Best Wishes


hmmm...I am using the pic's power supply as reference. I hadn't considered noise on that between entering the PIC and being used for ADC.

I've tried reading the values using an oscilloscope and a DVM. Neither showed noise. If they are unreliable for this measurement, what can I use?

Based on what I know so far, I would guess you are correct. The problem is using Vdd as my Vref. Unfortunately I don't have the pins free to use a separate Vref. Do you have any suggestions?
newguy



Joined: 24 Jun 2004
Posts: 1908

View user's profile Send private message

PostPosted: Fri Jul 23, 2010 11:07 am     Reply with quote

skoberlink wrote:
Based on what I know so far, I would guess you are correct. The problem is using Vdd as my Vref. Unfortunately I don't have the pins free to use a separate Vref. Do you have any suggestions?


This is a multi-faceted issue with many possible remedies. For instance, higher capacitance/lower ESR capacitors on your power supply rail, with a 0.1uF cap placed very close (physically) to each PIC Vdd pin. If you don't have a ground plane, you need one. Power supply filtering, EMI filtering on each line that is prone to noise won't hurt either. A simple RC low pass filter on the problem analog line will help immensely too.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jul 23, 2010 11:37 am     Reply with quote

Quote:
ADCON0 = 0b11000000

Also because you didn't use CCS functions, it's not immediately clear
if you have problems in your ADC setup. This morning I looked more
closely at your setup and I noticed you're using the Internal ADC
oscillator. That's a big no-no for accuracy except under certain
conditions, per the 16F88 data sheet:
Quote:

2: When the device frequencies are greater than 1 MHz, the RC A/D
conversion clock source is only recommended for SLEEP operation.

The A/D clock divisor should be selected according to the table in
the PIC data sheet, based on your oscillator frequency.
SherpaDoug



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

PostPosted: Fri Jul 23, 2010 11:56 am     Reply with quote

It would still be good to know if the A/D values are a wide Gaussian profile (random scatter), or if they are mostly OK with occasional bad readings throw in. If it's the latter, are the bad readings all high or all low? Is there any clear "frequency" to the noise.

Also why did you decide to roll your own A/D code?

As for noise measurement, you may be able to put your scope on AC coupling and then push the gain way up to see small noise signals.
_________________
The search for better is endless. Instead simply find very good and get the job done.
skoberlink



Joined: 27 May 2010
Posts: 52

View user's profile Send private message

PostPosted: Mon Jul 26, 2010 8:47 am     Reply with quote

@newguy
I'm planning to put a .1uF cap on the Vdd line. Do you think that would fix it? I do have a ground plane. I'll look into some of that other stuff.

@PCM programmer
I had missed that line from the data sheet. That could be the problem. Unfortunately I don't have the pins for an external clock. I might be able to turn down the clock speed and see if that helps at all.

@SherpaDoug
I chose to write my own function on the advice of someone more experienced than I. I was having a problem using the built-ins where the voltage coming in to the analog in was at 100% but the motor would only move to 80% of it's range. It had something to do with the math involved in the built-ins. I talked to a friend who has had more experience and he advised me to write my own function. Then I would know exactly what was going on and it was potentially more efficient.

The A/D values seem to be random. I can't see any clear frequency. It all seems completely random.

Thanks for the help so far guys!
skoberlink



Joined: 27 May 2010
Posts: 52

View user's profile Send private message

PostPosted: Mon Jul 26, 2010 10:03 am     Reply with quote

Well slowing it down helped some. I've also discussed it with the guy working on a similar project and we got it down to an acceptable tolerance value. Haven't tried any of the other suggestions yet and probably won't have time to get to it now since it's a little superfluous. Thanks for the help though! All useful info.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jul 26, 2010 10:46 am     Reply with quote

Quote:
Unfortunately I don't have the pins for an external clock

That's not what I'm talking about. Post the oscillator frequency of
your PIC. I don't care if you're using a crystal or the Internal oscillator.
But post the frequency.
skoberlink



Joined: 27 May 2010
Posts: 52

View user's profile Send private message

PostPosted: Mon Jul 26, 2010 10:47 am     Reply with quote

PCM programmer wrote:
Quote:
Unfortunately I don't have the pins for an external clock

That's not what I'm talking about. Post the oscillator frequency of
your PIC. I don't care if you're using a crystal or the Internal oscillator.
But post the frequency.


Ok, the frequency I was running at was 4MHz. I turned it down to 1MHz and it seemed to help but it could have been a placebo effect.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jul 26, 2010 10:55 am     Reply with quote

The 16F88.h file lists these options for the A/D clock, to be used in the
setup_adc() function:
Code:

#define ADC_CLOCK_DIV_2   0x10000
#define ADC_CLOCK_DIV_4    0x4000
#define ADC_CLOCK_DIV_8    0x0040
#define ADC_CLOCK_DIV_16   0x4040
#define ADC_CLOCK_DIV_32   0x0080
#define ADC_CLOCK_DIV_64   0x4080
#define ADC_CLOCK_INTERNAL 0x00c0 

Download the 16F88 data sheet:
http://ww1.microchip.com/downloads/en/DeviceDoc/30487c.pdf
Look at this table on page 118 (pg 120 in the Acrobat reader):
Quote:
TABLE 12- 1: TAD vs. MAXIMUM DEVICE OPERATING FREQUENCIES – STANDARD DEVICES (C)

It says that for a 4 MHz oscillator, you should use this divisor:
Code:

ADC_CLOCK_DIV_4


For a 1 MHz oscillator frequency, you should use this one:
Code:
ADC_CLOCK_DIV_2


The problem is that you don't want to use CCS functions, so it's more
difficult to modify your code. You'll have to go look up the register
settings and choose the bits carefully to select the correct divisor.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2, 3  Next
Page 1 of 3

 
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