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

ADC maths... exercise in futility - SOLVED
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

ADC maths... exercise in futility - SOLVED
PostPosted: Mon Mar 04, 2013 10:26 am     Reply with quote

There is no problem with my code, it works fine.
I'm just looking for suggestions, its a long post.

I'm sure something good can come out of listening to all your opinions.


Code:

+Vref=2.5V
               
Vin (volts)   (ADC constant)   ADC Val (DEC)   ADC Val (HEX)   ADC*Adc_const    value to printf
1.55   244   635   027A   25D78   155000
1.54   244   631   0276   25990   154000
1.53   244   627   0272   255A8   153000
1.52   244   623   026E   251C0   152000
1.51   244   618   026A   24DD8   151000
1.50   244   614   0266   249F0   150000
1.49   244   610   0262   24608   149000
1.48   244   606   025E   24220   148000
1.47   244   602   025A   23E38   147000
1.46   244   598   0256   23A50   146000
1.45   244   594   0251   23668   145000
1.44   244   590   024D   23280   144000


The table above represents part of the ADC calculations I've done in Excel prior to coding my routine.

I'm trying to over sample an LM35 in an overachieving futile exercise to push precision and output stability for the glorious hell of it.
(its how i learn)


PIC: 16f88 (adc-10bit)
LM35 setup for 2C-155C

power input:
I have 12VDC input, through a diode, into 35V 556uF x 2 Electrolytic caps, into a LM7809, into a Pi filter (16V 100uf + 4R7uH +16V 100uf), into a LM7805, into 6.3V 1000uF x 4 Electrolytic caps... as a power supply....

its a _very_ smooth 5V supply... and excessive in every way i can imagine.

Further to that, my +Vref is a Voltage divider (10k+10k) with a 25V 10uf cap...

With the above setup, i get higher precision than with the Zeners Ive tried even when just using VDD as reference... obviously making my calculations on the actual voltage rather than just assuming 5V from the 7805.

my +Vref currently reads a cool solid 2.503 Volts.


I sample the ADC 68 times, eliminate high and low, average by 64.
and further to that, i put the result through a filter like this:

Code:
Out0 = (In0 + Out1 + Out1 + Out1) / 4;


The signal from the LM35 comes to the ADC via a LM358 set as unit gain and through a RC filter of 100ohm and 25V 10uf electrolytic Cap.

Yes, all this excessiveness takes a whole lot of time, and the response time is terrible...(well, its like 2-3 seconds)


I would like to keep the numeric precision of the calculations above but only use 1 decimal and keep everything in 16bit vars.

How can i optimize my calculations?
Code:
   
temperature/=64;                     // average by 16
temperature*=244;                     // multiply by ADC constant.


I know can format my decimal points with printf...

I really want to get my _math_ as precise as posible...obviously using integer maths...

I think I've implemented pretty much every trick in my book...

solid supply, narrowed the signal to reference differential, over sampled, digital low pas filter...hardware filters and buffers...


Thanks and sorry for the absurdly long post.
G.
_________________
CCS PCM 5.078 & CCS PCH 5.093


Last edited by Gabriel on Thu Mar 07, 2013 8:30 am; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19342

View user's profile Send private message

PostPosted: Mon Mar 04, 2013 1:11 pm     Reply with quote

Several comments:

First having significantly larger capacitors on the output of a regulator, than it's input, can endanger the regulator, resulting in it becoming reverse biased when you turn it off. Texas recommend a reverse biased diode across the regulator if you do this.

Then the best regulators are still an order of magnitude worse than a good voltage reference, but a zener is _not_ a good voltage reference. Look at bandgap references.

Then double check your maths. If you sample 68 times, and remove the high and low values, you still have 66 samples, not 64....

The easiest way to do this is to sum as you go:
Code:

int16 average_reading(void) {
   int32 sum=0;
   int16 low=0xFFFF;
   int16 high=0;
   int count;
   int16 val;
   for (count=0;count<66;count++) {
       val=read_adc();
       sum +=val;
       if (val>high)
           high=val;
       if (val<low)
           low=val;
       delay_us(10);
   }
   val-=high;
   val-=low;
   return (val/64);
}


Remember that to avoid accuracy loss you should always multiply _before_ division.

66 samples should still take under 1mSec. Delays longer than Tacq, gain you nothing.

Best Wishes
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Mon Mar 04, 2013 1:34 pm     Reply with quote

EDIT : Hi Ttelmah.......

(my bad... sorry about that... i glanced at your name but read my version number on my footer at the same time and it say PCM... and ... you see where im going)...



i meant 66 times... sorry for that.. typo.

Thanks for the information on the reverse bias...ill implement that immediatly...


Quote:
Remember that to avoid accuracy loss you should always multiply _before_ division.


the code you posted is EXACTLY the same as the one im using (exept for the delay_us(10))

so, i understand it would be better to multiply the sum of the 64 values by the ADC constant and then devide by 64?


Quote:
66 samples should still take under 1mSec. Delays longer than Tacq, gain you nothing.

i did not understand this... could you please explain more?
i think that what you mean is that im reading the ADC faster than the ADC time constant and thus not gaining any presicion and thats why you have included a 10us delay in you posted code?

Thanks!
G-
_________________
CCS PCM 5.078 & CCS PCH 5.093
Ttelmah



Joined: 11 Mar 2010
Posts: 19342

View user's profile Send private message

PostPosted: Mon Mar 04, 2013 1:47 pm     Reply with quote

The ADC functions internally as a capacitor fed by a resistor.
The resistor is a combination of internal resistances in the multiplexor, and the other circuitry. The capacitor is what is used to hold the voltage to be read, while the ADC is disconnected from the external source. The ADC is disconnected while the reading is made, and takes time to recharge. The time needed to re-acquire, is Tacq. Now this depends on the chip you are using, but is typically 10uSec on the commonest chips, dropping to just a couple of uSec on some of the newer chips. Assuming a reasonably fast clock rate, the comparisons, loop and sum, will only take a couple of uSec, which then means the capacitor _won't_ have properly recharged.

Several questions apply:
Chip?.
What clock rate?.
What clock rate are you using for the ADC?.

You talk about taking 2 to 3 seconds, but 66 readings done (say) 15uSec apart, will only take 990uSec, so what are you doing that takes so long?....

Best Wishes
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Mon Mar 04, 2013 1:58 pm     Reply with quote

I got it.
I'll add the delay.

I'm using a 16F88 @ 8MHz, using div_16 adc clock as per the datasheet on the TAD table.


EDIT remember i put everything through a lowpass filter (see OP)....
it take 2-3 secs for the value to stabilize in the terminal... 2-3 seconds is the time i think it takes... i see values changing immediately on the screen when i touch the sensor but because of the filter it takes a little bit to reach the final value.


Thanks for your help i really appreciate it.

G.
_________________
CCS PCM 5.078 & CCS PCH 5.093
Ttelmah



Joined: 11 Mar 2010
Posts: 19342

View user's profile Send private message

PostPosted: Mon Mar 04, 2013 3:51 pm     Reply with quote

Probably 80% of the delay is the time it takes the chip to actually heat/cool. Remember the sensor is the IC right inside the chip...

Best Wishes
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Mon Mar 04, 2013 6:59 pm     Reply with quote

I did a work for hire a while back - incubator stage heater system for approx human body temp center point with an LM34 - not the 35 -
even though the output is presented in cent degrees -
the servo code does not care.

I used an LM385-1.25 ref diode with 5uf on the ref input of the pic
and an 18F2423 - and it was very successful, stable and accurate.

I did use TWO LM34s and combined the data, but that is another story.

Now, does anybody care to tell me why i used:

** 1.25v ref,
** the pic that i did and the
** LM34 instead of the LM35 ??

Very Happy Very Happy Very Happy Very Happy
Ttelmah



Joined: 11 Mar 2010
Posts: 19342

View user's profile Send private message

PostPosted: Tue Mar 05, 2013 1:29 am     Reply with quote

You missed one thing that would be degrading your result. Parameter A20 in the data sheet. Smile

Best Wishes
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Tue Mar 05, 2013 2:35 am     Reply with quote

Quote:
power input:
I have 12VDC input, through a diode, into 35V 556uF x 2 Electrolytic caps, into a LM7809, into a Pi filter (16V 100uf + 4R7uH +16V 100uf), into a LM7805, into 6.3V 1000uF x 4 Electrolytic caps... as a power supply....
Perhaps you left them out to keep your description readable, but I'm missing the high frequency caps.
With caps it isn't always 'bigger is better'; the electrolytic caps have a relatively large internal resistance making them unsuitable to filter the high frequency noise. That's why you often see a 0.1uF tantalum or 0.33uf aluminium capacitor next to one of the larger electrolytic caps; the combination of both works more like the 'perfect' theoretical cap we always assume they are.

Note that the LM78xx regulators are known to be very good oscillators. To prevent this from happening you need the smaller capacitors: 0.33uf on the high voltage side and 0.1uf on the output side. See Fairchild data sheet typical application examples.
Ttelmah



Joined: 11 Mar 2010
Posts: 19342

View user's profile Send private message

PostPosted: Tue Mar 05, 2013 4:20 am     Reply with quote

Yes, that is one I normally 'PIC up'.....

Best Wishes
miro



Joined: 15 Jan 2011
Posts: 62

View user's profile Send private message

PostPosted: Tue Mar 05, 2013 5:57 am     Reply with quote

Quote:
Then the best regulators are still an order of magnitude worse than a good voltage reference, but a zener is _not_ a good voltage reference. Look at bandgap references.

Not sure that this would be a good hint for this application. My hands-on experience shows you may get best results with oversampling and digital filtering only with dithering. The usage of a noise-free precise voltage reference causes the resulting values will be of a "better precision" only at the moments with input voltages near the transition levels between the "adc bit levels". Dithering helps you with creating improved precision within the adc "step levels" as well.
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Tue Mar 05, 2013 7:10 am     Reply with quote

Hey guys thanks for all the good info.

The small caps are onboard however, i have them closer to the PIC/Chips so i didn't include them in the description of the power source.

Ttelmah, you referenced parameter A20, which by my understanding requires a minimum +Vref of 2V.... I'm using 2.5V so i "should" be Ok... feel free to correct me.

anyways, last night i tested some code and sadly i found that although I'm getting "acceptable" results (mean values)... my LM35s have become fabulous oscilators....in the kHz range...
They are connected to the board via a ~1meter cable... its 4 wire+1 bare conductor, aluminum foil shielded cable...unused wires are tied to GND on both ends.

I checked my 5V line on board and on the LM35 with my O-scope and it was smooth as a baby's bottom... so its definitely the LM35 oscilating... probably due to capacitance on the cable...sigh.

I ended up deleting all my code and using:
Code:
int16 average_reading(void) {
   int32 sum=0;
   int16 low=0xFFFF;
   int16 high=0;
   int count;
   int16 val;
   for (count=0;count<66;count++) {
       val=read_adc();
       sum +=val;
       if (val>high)
           high=val;
       if (val<low)
           low=val;
       delay_us(10);
   }
   val-=high;
   val-=low;
   return (val/64);
}


which doesn't work by the way...

it should be:
Code:

   sum-=high;
   sum-=low;
   return (sum/64);



I've been reading the datasheet on the LM35 to control the oscillations but i don't like the presented solutions as they required alot of additional components.. but alas.. i guess I'll have to try them... (i need the sensors on long cables).


G...
_________________
CCS PCM 5.078 & CCS PCH 5.093
temtronic



Joined: 01 Jul 2010
Posts: 9163
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Mar 05, 2013 8:04 am     Reply with quote

Yes the LM34/35 are good oscillators if not wired up according to the datasheets! Used them for 20+ years for remote energy control systems.
I used 1/2 an LM358(IIRC) as a buffer at the sensor end along with some power supply decoupling(22r/10mfd).Ran simple 'quad' about 150' without any problems.
A one 'chip' solution may be the DS18B20 if you don't mind the 1 second response time for max resolution.
Yes it costs more,but weighed against an LM34/opamp/passives/Vref/pcb/etc. it probably comes out cheaper and/or easier to use.

hth
jay
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Tue Mar 05, 2013 8:29 am     Reply with quote

@temptronic:

Jejejeje i just finished drawing up the art work for a small pcb to place at the sensor end with a LM358 for x2 amplification and buffering!

hahaha... almost exactly what you posted..


i think im going to take out the x2 amplification to save on the Resistors and extra soldering work... what do you think?

Edit: and also to avoid having MORE error introduced by resistor inacuracies... IE not exactly x2 amplification but x2.17...

G.
_________________
CCS PCM 5.078 & CCS PCH 5.093
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Tue Mar 05, 2013 9:10 am     Reply with quote

Gabriel wrote:
Ttelmah, you referenced parameter A20, which by my understanding requires a minimum +Vref of 2V.... I'm using 2.5V so i "should" be Ok... feel free to correct me.
My guess is that the remark was meant for Asmboy. His 1.25Vref is out of spec (the 18F2423 requires 3V minimum).
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  Next
Page 1 of 2

 
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