Searching \ for 'Average reading of a fluctuating A/D signal?' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/io/atod.htm?key=a%2Fd
Search entire site for: 'Average reading of a fluctuating A/D signal?'.

Truncated match.
PICList Thread
'Average reading of a fluctuating A/D signal?'
2000\05\19@082250 by Quentin

flavicon
face
My A/D input signal is such that I will always have a +/- 10 fluctuation
in my register value. Can somebody tell me how to get an average reading
over say 5 A/D samples?

Thanks
Quentin

2000\05\19@082716 by Martin Hill

picon face
How about adding four readings together and then doing two right
shifts?  Or a low pass filter on the input.

Martin

> My A/D input signal is such that I will always have a +/- 10 fluctuation
> in my register value. Can somebody tell me how to get an average reading
> over say 5 A/D samples?
>
> Thanks
> Quentin

2000\05\19@105914 by Spehro Pefhany

picon face
At 02:01 PM 5/19/00 +0200, Quentin wrote:
>My A/D input signal is such that I will always have a +/- 10 fluctuation
>in my register value. Can somebody tell me how to get an average reading
>over say 5 A/D samples?

If your readings are periodic, one method is to pick a constant 'a'

and do  value = (1-a) * value + a*reading

(you might also use a flag to preload value=reading the first time.

This forms a low pass filter, and more recent values have a higher weight
than previous values. It has the advantage that it only uses one ram
location and you get a value every A/D conversion.

If you just want to take a bunch of readings in succession and average
them, just add n values together and then divide by n. Obviously you
need to avoid overflow during the add, so you might use 16 bit math
for an 8/10/12 bit A/D reading with 256/64/16 values or less being
averaged.

Best regards,


=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Spehro Pefhany --"it's the network..."            "The Journey is the reward"
spam_OUTspeffTakeThisOuTspaminterlog.com             Info for manufacturers: http://www.trexon.com
Embedded software/hardware/analog  Info for designers:  http://www.speff.com
Contributions invited->The AVR-gcc FAQ is at: http://www.bluecollarlinux.com
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

2000\05\19@110913 by Scott Dattalo

face
flavicon
face
On Fri, 19 May 2000, Spehro Pefhany wrote:

{Quote hidden}

I guess this is a record for repeated thread frequency. Quentin, look at the
archives from just a few days back when we were talking about this exact issue
and proposed the exact solutions you've seen posted today.

Scott

2000\05\19@111536 by Kbek Tony

flavicon
face
Hi,
see my posting from last week 'Digital filtering on PIC's'
and the excellent replies it generated, other techniqes than
mentioned below.

Very simple and easy to implement is an recursive moving average
filter. First, accumulate N-number of samples ( preferably N should
power of two factor 2,4,8 etc as there is division involved ).

For each sample: add it in an circular buffer of the same size as N,
where X(0) is first sample X(N-1) is last sample.

Then calulate the first filtered value like:
( the adding could be done while collecting them )

Y(0) =  [ X(0) + X(1) + ... + X(N-1)] / N

Then the next ( and consecutive ) filtered value/s can be calculated
for each new sample( where the first would be X(N) ) by using:

Y(1) = Y(0) + [ X(N) - X(0)]/N

And first the next:

Y(2) = Y(1) + [ X(N+1) - X(1)]/N

Take care though for possible negative numbers when calculating
the difference between latest and oldest sample and dividing it :-).

And also to elliminate roundoff errors one could always add one to the
value to divide before the latest division by 2.

If you need buffer routines or example code, please request to
me personally.


/Tony




Tony KŸbek, Flintab AB            
ÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓ
E-mail: .....tony.kubekKILLspamspam@spam@flintab.com
ÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓ

2000\05\19@221933 by Dan Mulally

flavicon
face
Quentin,

If you add five 8-bit samples and use two 8 bit registers for the result
(16bits) you can then do a right shift five times on the 16 bit result to
obtain an average. You need to take into account the carry from the lo byte
to the high byte.

Dan

----- Original Message -----
From: "Quentin" <qscspamKILLspamICON.CO.ZA>
To: <.....PICLISTKILLspamspam.....MITVMA.MIT.EDU>
Sent: Friday, May 19, 2000 6:01 AM
Subject: Average reading of a fluctuating A/D signal?


> My A/D input signal is such that I will always have a +/- 10 fluctuation
> in my register value. Can somebody tell me how to get an average reading
> over say 5 A/D samples?
>
> Thanks
> Quentin

2000\05\19@235320 by Spehro Pefhany

picon face
At 08:18 PM 5/19/00 -0600, you wrote:
>Quentin,
>
>If you add five 8-bit samples and use two 8 bit registers for the result
>(16bits) you can then do a right shift five times on the 16 bit result to
>obtain an average. You need to take into account the carry from the lo byte
>to the high byte.
>
>Dan

Unh, no. Right shifting 5 x divides by 32 (2^5).
You can add 4 numbers and right-shift twice, 8 and right shift 3 x etc.

Note that if the numbers are signed you have to do an arithmetic not logical
shift (on a 2's complement number, the leftmost bit is retained, rather than
a zero being shifted in).

Best regards,


=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Spehro Pefhany --"it's the network..."            "The Journey is the reward"
EraseMEspeffspam_OUTspamTakeThisOuTinterlog.com             Info for manufacturers: http://www.trexon.com
Embedded software/hardware/analog  Info for designers:  http://www.speff.com
Contributions invited->The AVR-gcc FAQ is at: http://www.bluecollarlinux.com
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

2000\05\20@032049 by paulb

flavicon
face
Martin Hill wrote:

> How about adding four readings together and then doing two right
> shifts?

 Major error in that procedure!  Should be: add four readings together,
*add two* and then do two right shifts.
--
 Cheers,
       Paul B.

2000\05\20@033721 by Quentin

flavicon
face
Scott Dattalo wrote:

> I guess this is a record for repeated thread frequency. Quentin, look at the
> archives from just a few days back when we were talking about this exact issue
> and proposed the exact solutions you've seen posted today.
>
> Scott

I thought it was the unsubscribe thread? :)
I did have a quick look, but did not use the correct terminology.

Thanks to all that replied.

Quentin

2000\05\21@190527 by Tony Nixon

flavicon
picon face
Quentin wrote:
>
> My A/D input signal is such that I will always have a +/- 10 fluctuation
> in my register value. Can somebody tell me how to get an average reading
> over say 5 A/D samples?
>
> Thanks
> Quentin


Heres a simple setup using the FSR. Averages for 8 readings though.


       CBLOCK
Average: 8h
tempH
tempL
       ENDC

       movlw Average   ; initialise FSR
       movwf FSR

       ...
;
; PLACE A2D RESULTS INTO A ROTATING BUFFER
;
       movf ADRES,W
       movwf INDF
       incf FSR
       movlw Average + 8h
       xorwf FSR,W
       btfss STATUS,Z
       goto NFSR

       movlw Average
       movwf FSR

NFSR    ...

;
; AVERAGE OUT THE 8 STORED VALUES WHEN A RESULT IS NEEDED
;
       movlw Average
       movwf FSR
       clrf tempH
       clrf tempL

avLoop  movf INDF,W             ; add up 8 word values
       addwf tempL
       btfsc STATUS,C
       incf tempH

       incf FSR
       movlw Average + 10h
       xorwf FSR,W
       btfss STATUS,Z
       goto avLoop

       movlw Average
       movwf FSR
       bcf STATUS,C            ; div result by 8
       rrf tempH
       rrf tempL
       bcf STATUS,C
       rrf tempH
       rrf tempL
       bcf STATUS,C
       rrf tempH
       rrf tempL

       ....

--
Best regards

Tony

http://www.picnpoke.com
salesspamspam_OUTpicnpoke.com

2000\05\21@194131 by Tony Nixon

flavicon
picon face
"Paul B. Webster VK2BZC" wrote:
>
> Hello Tony.
>
> > Heres a simple setup using the FSR. Averages for 8 readings though.
>
>   Can't see the add 4 to temp before the divide by 8.  Did you forget
> it?
> --
>   Cheers,
>         Paul B.


Not sure??? It's Monday morning :-)

but I did muck this up. (It was originally for 8 x 16 bit values.)

avLoop  movf INDF,W             ; add up 8 byte values
       addwf tempL
       btfsc STATUS,C
       incf tempH

       incf FSR
       movlw Average +8h
>>>(wrong)>>>    movlw Average + 10h
       xorwf FSR,W
       btfss STATUS,Z
       goto avLoop

--
Best regards

Tony

http://www.picnpoke.com
@spam@salesKILLspamspampicnpoke.com

2000\05\21@221149 by Scott Dattalo

face
flavicon
face
On Mon, 22 May 2000, Tony Nixon wrote:

{Quote hidden}

If you have only 8 samples, and you were willing to align the array on a mod 8
boundary, then advancing the pointer could be done easily:

  incf   fsr,w
  andlw  7
  addlw  Average
  movwf  fsr


if you don't wish to align the array, then try this instead:

  incf   fsr,w
  addlw  -Average
  andlw  7
  addlw  Average
  movwf  fsr


{Quote hidden}

Again, I think the best way to maintain a running average is by subtracting the
oldest value and adding in the newest. Here's something I'll whip out as fast as
I can type it - which means there's a good chance for a thinko.

; avg_lo:avg_hi - 16bit cumulative sum of last 8 samples
; samples - a circular array that holds the last 8 samples
; assume that samples and avg_lo:avg_hi are initialized to zero
;
; FSR is initialized to the start of samples
;
; W = newest sample

AVERAGE:

   addwf  avg_lo,f    ;add newest sample to the average
   skpnc
    incf  avg_hi,f

   xorwf  indf,f      ; swap oldest and newest samples
   xorwf  indf,w
   xorwf  indf,f

   subwf  avg_lo,f    ;remove the oldest sample from the average
   skpc
    decf  avg_hi,f

   incf   fsr,w       ;advance the sample pointer
   addlw  -sample
   andlw  7
   addlw  sample
   movwf  fsr

   return

There - no more looping through all of the data after every sample is acquired.

Now, I'm assuming that the division is not needed at every iteration. I tend to
put off the difficult stuff as long as possible - often times, the intermediate
calculations are more than sufficient.

But, if you want, then this is how I'd do it:

   rrf   avg_hi,w
   movwf temp_hi
   rrf   avg_lo,w
   movwf temp_lo
   rrf   temp_hi,f
   rrf   temp_lo,f
   rrf   temp_hi,f
   rrf   temp_lo,w

and if you wanted rounding:

   skpnc
    addlw 1

(You don't need to worry about clearing the carry because the average is
guranteed to be less than or equal to 255.)

Scott

More... (looser matching)
- Last day of these posts
- In 2000 , 2001 only
- Today
- New search...