At 12:32 23/09/1997 +0000, you wrote: >Anybody got a good averaging algorithm? ; Offset multibytes variables MSB EQU 0 LSB16 EQU 1 LSB24 EQU 2 LSB32 EQU 3 CBLOCK 0x07 SIGNAL ; signal (input and output) AVERAGE:2 ; averaged value ENDC ORG 0x1FF MOVLW 0 ORG 0x000 ; Just for testing ... LOOP MOVLW 0x80 MOVWF SIGNAL ; input CALL AVERG MOVF SIGNAL,W ; output ; ...... GOTO LOOP ; AVERG ; First order lowpass filter ; Can be used to smooth a 8 bits signal (SIGNAL) ; Input SIGNAL ; Output SIGNAL ; AVERAGE = AVERAGE - (AVERAGE/256) + SIGNAL ; SIGNAL = AVERAGE/256 ; At the beginning you can initialise AVERAGE with the first input value : ; AVERAGE(t0) = SIGNAL(t0) * 256 ; The simplest way to averaging, but... integer arithmetic produce some ; output instabilities... for example : ; if input = constant = 0xZZ, AVERAGE converges to 0xZZ00 if previous output ; is < 0xZZ, or converges to 0xZZFF if previous output is > 0xZZ. ; If AVERAGE = 0xZZFF, and if the new input is 0xZZ+1, the output changes ; immediately to 0xZZ+1, ; If AVERAGE = 0xZZ00, and if the new input is 0xZZ-1, the output changes ; immediately to 0xZZ-1 ; To avoid this problem you need a rounding (see later)... if 0 AVERG MOVF AVERAGE+MSB,W ; AVERAGE -= AVERAGE/256 SUBWF AVERAGE+LSB16,F BTFSS STATUS,C DECF AVERAGE+MSB,F MOVF SIGNAL,W ; AVERAGE += SIGNAL ADDWF AVERAGE+LSB16,F BTFSC STATUS,C INCF AVERAGE+MSB,F MOVF AVERAGE+MSB,W ; SIGNAL = AVERAGE/256 MOVWF SIGNAL RETLW 0 else ; Average whith proper rounding... ; AVERAGE SIGNAL(out) ; 0xFE80:0xFF00 0xFF ; 0xFD80:0xFE7F 0xFE ; 0x0180:0x027F 0x02 ; 0x0080:0x017F 0x01 ; 0x0000:0x007F 0x00 AVERG MOVF AVERAGE+MSB,W ; W = AVERAGE/256 XORWF SIGNAL,W ; (W = SIGNAL) ? BTFSS STATUS,Z GOTO AVERG1 ; no ; (AVERAGE/256 = SIGNAL), ; if (AVERAGE <> 0) AND (SIGNAL <> 0xFF), (AVERAGE/256)+1 ; allows a convergence always to 0xZZ00 if input is 0xZZ MOVF AVERAGE+MSB,W IORWF AVERAGE+LSB16,W ; (AVERAGE = 0) ? BTFSC STATUS,Z ; (AVERAGE = 0x0000), don't increment (AVERAGE/256) GOTO AVERG1 INCFSZ SIGNAL,W ; if SIGNAL = 0xFF, W = 0 and skip ... GOTO AVERG2 ; else continue whith (AVERAGE/256)+1 AVERG1 XORWF SIGNAL,W ; restore AVERAGE/256 AVERG2 SUBWF AVERAGE+LSB16,F BTFSS STATUS,C DECF AVERAGE+MSB,F ; AVERAGE -= (AVERAGE/256) MOVF SIGNAL,W ; AVERAGE += SIGNAL ADDWF AVERAGE+LSB16,F BTFSC STATUS,C INCF AVERAGE+MSB,F ; rounding MOVF AVERAGE+MSB,W ; SIGNAL = (AVERAGE+128)/256 BTFSC AVERAGE+LSB16,7 INCF AVERAGE+MSB,W MOVWF SIGNAL RETLW 0 endif Jean-Louis VERN jlvern@writeme.com