Stable Adc Reading Routine


Closed Thread
Results 1 to 28 of 28

Hybrid View

  1. #1
    Join Date
    Jul 2003
    Posts
    2,358


    Did you find this post helpful? Yes | No

    Default

    OK Adam, you asked for it... here it is... quickly thrown together for an 18F2420... (you can probably optimise it with a bit of thought, but it's a starter just to get going)...

    The variables...
    Code:
    	ADCValue var WORD			' Final ADC Result
    	CounterA var BYTE			' Just a BYTE Temporary working variable
    	DataW var WORD				' Just a WORD Temporary working variable
    	RawData var WORD [16]			' Array holding ADC Result
    Some Initialisation Set-up's for the PIC....
    Code:
    	ADCON1=%00001110			' ADC Control 1
    						' 	7=0 - 0 Unused
    						' 	6=0 - 0 Unused
    						' 	5=0 - VRef=Vss
    						' 	4=0 - VRef=Vdd
    						' 	3=1 )
    						' 	2=1 ) RA0 set to Analogue
    						' 	1=1 ) All others set to Digital
    						'	0=0 )
    	ADCON2=%10101001			' ADC Control 2
    						' 	7=1 - Right Justified - Read 10-Bits
    						' 	6=0 - 0 Unused
    						' 	5=1 )
    						' 	4=0 ) TAD
    						' 	3=1 )
    						' 	2=0 )
    						' 	1=0 ) Fosc/8
    						'	0=1 )
    Now for the real program... First TAKE your SAMPLES...
    Code:
    		'
    		'	Stuff 16 Element WORD Array full of ADC values
    		'	----------------------------------------------
    	For CounterA=0 to 15
    		ADCON0=%00000001		' Select Channel, Turn-On A/D
    						'	7=0 Unused
    						'	6=0 Unused
    						'	5=0 )
    						'	4=0 )
    						'	3=0 ) selects AN0
    						'	2=0 )
    						'	1=0 Go-done Bit
    						'	0=1 switch-On ADC Module
    		Pauseus 50			' Wait for channel to setup
    	        ADCON0.1 = 1			' Start conversion
    		While ADCON0.1=1:Wend		' Wait for conversion
    		DataW.HighByte=ADRESH		' Read variable from ADC and save
    		DataW.LowByte=ADRESL
    		RawData(CounterA)=DataW
    		Next CounterA
    Then SORT your RESULTS...
    Code:
    		'
    		'	Sort ADC Input
    		'	--------------
    	CounterA=0
    GetADCSortLoop:
    	If RawData(CounterA+1) < RawData(CounterA) then
    		DataW=RawData(CounterA)
    		RawData(CounterA)=RawData(CounterA+1)
    		RawData(CounterA+1)=DataW
    		If CounterA>0 then CounterA=CounterA-2
    		endif
    	CounterA=CounterA+1
    	If CounterA<15 then goto GetADCSortLoop
    Finally EXTRACT SOMETHING USEFUL from what you've got...
    Code:
    	'
    	'	Quanticise discarding top and bottom FOUR elements
    	'	----------------------------------------------------
    	DataW=0
    	For CounterA=4 to 11
    		DataW=DataW+RawData(CounterA)
    		Next CounterA
    	ADCValue=DataW>>3			' Divide Result by EIGHT
    Ain't so difficult when you break it down into little steps is it?

  2. #2
    Join Date
    Apr 2006
    Location
    New Hampshire USA
    Posts
    298


    Did you find this post helpful? Yes | No

    Smile my co-workers have noticed

    Hi Melanie,

    Thanks a bunch, this is really easy to understand.
    You are spot on, it is overwhelming looking at the problem. Trying to get a foothold.
    But not so bad step by step.

    Of coarse it is easy with the code as an example.

    I will study the whole thing. I learn, not just from your excellent example of how to code it. But, from the style of logic flow and layout. It is good, the way you comment lines of code that seem obvious to you but cause a noobe to pause and check. This allows us to get beyond the mechanics quickly, and see the part you are showing us.

    I have saved this example and will try to learn and build from it. You’re the greatest!

    (notice the "spot on", my co-workers have noticed my accent growing!)

    -Adam-
    Ohm it's not just a good idea... it's the LAW !

  3. #3
    Join Date
    Jul 2003
    Posts
    2,358


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Pic_User View Post
    Of coarse it is easy ... my co-workers have noticed my accent growing!
    You're getting there - but you're still a little coarse (of course!).

  4. #4
    Join Date
    Apr 2006
    Location
    New Hampshire USA
    Posts
    298


    Did you find this post helpful? Yes | No

    Smile Thanks.

    Thanks.
    Quote Originally Posted by Melanie View Post
    You're getting there - but you're still a little coarse (of course!).
    Of course, embarrassed, I now wander off in search of the “misused words” forum…..
    -Adam-
    Ohm it's not just a good idea... it's the LAW !

  5. #5
    Join Date
    Oct 2005
    Posts
    18


    Did you find this post helpful? Yes | No

    Default

    Dear All
    I replaced my own routine for ADC readings with Melanie's just to see if there would be any difference in displayed voltages.
    I found out that there was always an increase in steps of 30mV(remember that I display with a resolution of two decimal digits) instead of my previous output in short bursts of gradually increasing values by 10mV.
    So I came to the conclusion that my problem lies with the resistive divider that I use in order to be able to read voltages up to 30V.This is division by 6 and with the 0,004887 V / step(due to 5V max./1023 for 12F675) we arrive at apx. 30mV / new step which is unavoidable.
    I think that I have to use some OPamp method(differential) to read voltage without stepping down through a ressistive divider.
    I would welcome any thoughts and/or suggestions on the subject.
    I thank all of you and especially Melanie(for the exceptional/disciplined programming techniques she uses) for the time you dedicated for me.
    Also please forgive any grammar mistakes I make since I am only a native Greek .

    Bill

  6. #6
    Join Date
    Apr 2006
    Location
    New Hampshire USA
    Posts
    298


    Did you find this post helpful? Yes | No

    Smile thoughts on the subject

    Quote Originally Posted by gebillpap View Post
    Dear All
    I replaced my own routine for ADC readings with Melanie's just to see if there would be any difference in displayed voltages.
    I found out that there was always an increase in steps of 30mV(remember that I display with a resolution of two decimal digits) instead of my previous output in short bursts of gradually increasing values by 10mV.
    So I came to the conclusion that my problem lies with the resistive divider that I use in order to be able to read voltages up to 30V.This is division by 6 and with the 0,004887 V / step(due to 5V max./1023 for 12F675) we arrive at apx. 30mV / new step which is unavoidable.
    I think that I have to use some OPamp method(differential) to read voltage without stepping down through a ressistive divider.
    I would welcome any thoughts and/or suggestions on the subject.
    I thank all of you and especially Melanie(for the exceptional/disciplined programming techniques she uses) for the time you dedicated for me.
    Also please forgive any grammar mistakes I make since I am only a native Greek .

    Bill
    Hi Bill

    Take a look at this post.
    http://www.picbasic.co.uk/forum/showthread.php?t=8070

    You will have to extrapolate the Voltage up from the 12 Volt example given. Hope it helps….

    Melanie doesn’t really make fun of grammar. We have a running joke about the difference between REAL English and American English. She was just catching a goof of mine. Your English is better than mine!

    -Adam-
    Ohm it's not just a good idea... it's the LAW !

  7. #7
    Join Date
    Jul 2003
    Posts
    2,358


    Did you find this post helpful? Yes | No

    Default

    Bill

    You're pretty much at the limit of conventional measurement (using a potential divider). The best you can accomplish as you have discovered will be steps of...

    5v/1024*6 = 0.02929 (29.2mV)

    Where 6 is your Potential Divider ratio.

    Adam has suggested Zener Diodes, but beware using those, as no two Zener Diodes are the same and their tollerances are quite large.

    You can always use an external 12-bit ADC rather than the PICs internal 10-bit one. That will then give you a resolution of about 4.4mV which is inside your two decimal places.

    Trouble is I can guarantee your 5v reference probably isn't 5.0000v (and are you using 0.1% Resistors?) so we're splitting hairs about millivolt ADC tollerances anyway.

    The only software solution... which is valid for slow-moving voltages (sampling alone in the below example will probably take about 4-5mS)... just massively over-sample, but I think you're using that already... Even with older versions of PBP, you are able to take 64 samples and add them together before you spill out of a WORD.

    Code:
    		'
    		'	Sample 64 times
    		'	---------------
    	ADCValue=0
    	For CounterA=0 to 63
    		ADCON0=%00000001		' Select Channel, Turn-On A/D
    						'	7=0 Unused
    						'	6=0 Unused
    						'	5=0 )
    						'	4=0 )
    						'	3=0 ) selects AN0
    						'	2=0 )
    						'	1=0 Go-done Bit
    						'	0=1 switch-On ADC Module
    		Pauseus 50			' Wait for channel to setup
    	        ADCON0.1 = 1			' Start conversion
    		While ADCON0.1=1:Wend		' Wait for conversion
    		DataW.HighByte=ADRESH		' Read variable from ADC and save
    		DataW.LowByte=ADRESL
    		ADCValue=ADCValue+DataW
    		Next CounterA
    You now have 16-bits resolution... well, not really, but the bigger the sample the better.

    Need more? Just use PBP 2.50 where you can have more bits... but it will take much longer to sample - how much time do you have to spare?

Similar Threads

  1. Reading A Photo Resistor using ADC
    By jessey in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 25th January 2007, 09:28
  2. adc reading ac
    By Ruben Pena in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 20th December 2005, 21:57
  3. 12F675 ADC 'Issues'
    By harrisondp in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 31st March 2005, 01:55
  4. Problem reading multiple ADC ports
    By jswayze in forum mel PIC BASIC Pro
    Replies: 11
    Last Post: - 4th November 2004, 16:46
  5. Reading multiple ADC channels FAST
    By lwindridge in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 21st April 2004, 22:37

Members who have read this thread : 3

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts