Hi Bill,
Melanie’s great idea:
http://www.picbasic.co.uk/forum/showthread.php?p=41702Originally Posted by Melanie
It would be interesting to see a “real world” working example of this technique written for a PIC’s 10 bit ADC.
-Adam-
Hi Bill,
Melanie’s great idea:
http://www.picbasic.co.uk/forum/showthread.php?p=41702Originally Posted by Melanie
It would be interesting to see a “real world” working example of this technique written for a PIC’s 10 bit ADC.
-Adam-
Ohm it's not just a good idea... it's the LAW !
One advantage to Melanie's technique is very obvious when you have a moving a/d value to read. For slow moving, if you have a quality circuit with low noise, you can usually just average. I used an a/d port to track the charging of a battery once, using 10 point averaging. I could almost get better resolution than the PIC advertised because with a steady and slow moving v-in, the readings changed very slowly... that is, on a 10-bit reading, I'd get 5 readings at, say, 480, and 5 at 481. The next time, it would be 4 at 480 and 6 at 481... then 3 & 7, etc.
If you really want a "rolling average" then you can take a reading and add it to your average, and subtract your oldest rolling number. That saves time in computation if it matters. Otherwise, just adding all of your numbers every time may be easier to read and comprehend.
Thank you for responding
I will try to describe the problem I face better in order to justify why I think that something like the stable ADC mentioned in my first post might solve it.
A 12f675 chip gets ADC readings of a battery undergoing charging with currents 0,1-4A.
The voltage is monitored and displayed every 1 second with resolution of two decimals (for example 8,17 V).
Since the battery is under charge it's voltage is climping up steadily and the display should show (at 1 sec rate ) voltages like 8,17 - 8,17 -8,17-some time -8,17 -8,17 -8,18 -8,18-some time-8,18- 8,19- some time-etc.
But what happens is that I get the voltage increase in "bursts" of three like 8,17 - 8,18 -8,19- 8,19 - 8,19 -8,19- some time-etc. every time there is a slight increase in voltage.
This is probably due to my manipulation of ADC data with adding 64 readings to achieve a 16 bit result and so on .
Í believe that with the stable adc routine ,mentioned in my first post, I can improve my display of voltages.
Anyway can anyone propose some picbasic equivelant for the stable ADC routine???
Bill
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...
Some Initialisation Set-up's for the PIC....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
Now for the real program... First TAKE your SAMPLES...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 )
Then SORT your RESULTS...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
Finally EXTRACT SOMETHING USEFUL from what you've got...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
Ain't so difficult when you break it down into little steps is it?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
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 !
Bookmarks