At 16:51 1998-11-04 +0100, Stefan Sczekalla-Waldschmidt wrote: -snip- >>Essentially you want to create a median filter that >> averages too. In other words, you wish to collect a series of N samples, >> sort them, throw away the extremes, and then compute the average with >> what's remaing. Is that correct? > >Simply YES :-) - -snip- OK - I recognize that! Here is a filter that at each call sorts a 2-byte unsigned value into a 16 position array. If the new value gets injected below the middle all positions above are shifted up, and the highest is trashed. If the new value gets injected above the middle all positions below are shifted down, and the lowest is trashed. It then creates the average from the eight median posisitons. That way noise peak values are trashed, and i also get much better value. (the A/D is not very noiseless in PIC14000...) Another nice thing is that for a clean change in input values, the output is ramped, which is very nice since that value after more processing feed a motor speed controller. The routine is fully tested, but i will convert it to be variable controlled, and probably assymmetric, as the PIC14000 A/D when disturbed latches count prematurely, generating more values below median so i want to trash more low readings. And maybe change other characteristics. If somebody make theese or other variants i would be grateful to test them Below it is, directly pulled from the working application :) This filter was the differenece betveen the machine working or not Commented in swedish, of course... Short explanation: Tx are temp registers FWF macro copies a register File -> W -> File STL SToreLiteral literal -> W -> file cc Clear Carry ifcs IF Carry is Set (ececute next instruction) COP8-style ifzc IF Zero is Clear IFR1HGO R1,R2,label If R1 is higher (than R2) GOTO ... Input: tyngd_inH:tyngd_inL Activate: Call FilA Output: tyngd_utH:tyngd_utL Filter storage: viktfilter:32 Execution: Pretty fast Sorry I don«t have time to translate or explain more. "The rest is left as an exercise" ;) enjoy /Morgan FilA: call FilAscan ;Sortera in i filtret, Jobba pŒ, hejohŒ :) FilAaverage: STL viktfilter+8, FSR ;Summera mittre 8 vŠrdena... movlw 8 call Sum16 ;FilAdiv8: STL 3,T1 ;Och dividera resultatet med 8... FilAdiv8loop: cc rrf T4,F rrf T3,F rrf T2,F decfsz T1,F goto FilAdiv8loop ;resultatet nu i T3:T2 ;FilAaverageend: FWF T2,tyngd_utL FWF T3,tyngd_utH return ;--------------------------------------------------------------------------- ---- FilAscan: FWF tyngd_inL,T2 ;RESTEN AV RUTINEN HANTERAR INV€RDET SOM T3:T2 FWF tyngd_inH,T3 STL viktfilter+31, FSR ;Peka pŒ H…GSTA vŠrdet i l istan, H…Gbyten FilAscanH: ;Sšk vŠrden som Šr lŠgre Šn ADCAPH:ADCAPL... IFR1HGO INDF,T3,FilAscanHnext ;JŠmfšr nŠsta hšgbytes! IFR1LGO INDF,T3,FilAfoundH ;Hittat! (Saken Šr biff om h6gbyten Šr lŠgre Šn ADCAPH) FilAscanL: ;Hšgbytes Šr lika. decf FSR,F ;JŠmfšr lŒgbyten... IFR1HGO INDF,T2,FilAscanLnext ;Hittat! goto FilAfoundL ;Om detta filtervŠrde var hšgre elle r samma sŒ jŠmfšr med nŠsta FilAscanHnext: ;Testa nŠsta (hopp hit om endast testat hšgbyten och den var hšgre) decf FSR,F FilAscanLnext: ;Testa nŠsta (hopp hit om testat bŒda bytes) decf FSR,F IFRLGO FSR,viktfilter,FilAunder goto FilAscanH FilAunder: ;ev sŠtta styrbit fšr flyttrutinerna hŠr? FilAfoundH: decf FSR,F FilAfoundL: ; FSR pekar nu pŒ lŒgbyten i den fšrsta filterposition uppifrŒn rŠknat, ; som var lŠgre eller samma som invŠrdet. ; ; Om lŠgre Šn lŠgsta minnescellen sŒ pekar den under filtret ; ; Om hšgre Šn hšgsta minnescellen sŒ pekar den pŒ den ; => nerskiftrutinen skall skifta allt i filtret nedŒt, sedan lŠg ga in pŒ utpekad adress. ; ; VŠlj nu skifta upp eller ned: ; ; Om FSR pekar …VER mitten av filtret sŒ skall alla positioner dŠrifrŒn och NEDT skiftas ett steg NEDT, ; och nya vŠrdet in pŒ utpekad adress. ; Annars ška pekaren ett steg ; (eftersom ; 1. den annars ofta sorterar in dem i oording, (ett steg fel, om de inte har exakt samma vŠrde) ; 2. den kan peka under filtret annars ) ; och skifta alla positioner dŠrifrŒn och uppŒt ett steg uppŒt, ; och nya vŠrdet in pŒ utpekad adress. ;V€LJ: FWF FSR,T1 ;spara pekaren IFRHGO FSR,viktfilter+15,FilAmovedn incf T1,F incf T1,F FilAmoveup: ;Flytta vŠrden uppŒt fšr att ge plats Œt nya vŠrdet ;antal flyttningar= ( #(viktfilter+30) - pekare ) / 2 movf T1,W sublw (viktfilter+30) movwf T4 cc rrf T4,F ;antal flyttningar nu klart STL (viktfilter + 28), FSR ;Peka pŒ nŠst hšgsta vŠrdet i li stan, LGbyten FilAmoveuploop: movf INDF,W ;HŠmta LGbyten incf FSR,F ;och spara den incf FSR,F ;tvŒ positioner movwf INDF ;lŠngre UPP. decf FSR,F movf INDF,W ;HŠmta H…Gbyten incf FSR,F ;och spara den incf FSR,F ;tvŒ positioner movwf INDF ;lŠngre UPP. movlw -5 ;Femte byten NEDANfšr Šr addwf FSR,F ;nŠsta LGbyte att hŠmta. decfsz T4,F goto FilAmoveuploop goto FilAstore FilAmovedn: ;Flytta vŠrden nedŒt fšr att ge plats Œt nya vŠrdet ;antal flyttningar= ( pekare - #viktfilter) / 2 movlw viktfilter subwf T1,W movwf T4 cc rrf T4,F ;antal flyttningar nu klart STL (viktfilter + 3), FSR ;Peka pŒ nŠst lŠgsta vŠrdet i li stan, hšgbyten FilAmovednloop: movf INDF,W ;HŠmta hšgbyten decf FSR,F ;och spara den decf FSR,F ;tvŒ positioner movwf INDF ;lŠngre ner. incf FSR,F movf INDF,W ;HŠmta lŒgbyten decf FSR,F ;och spara den decf FSR,F ;tvŒ positioner movwf INDF ;lŠngre ner. movlw 5 ;Femte byten ovanfšr Šr addwf FSR,F ;nŠsta hšgbyte att hŠmta. decfsz T4,F goto FilAmovednloop FilAstore: FWF T1,FSR FWF T2,INDF incf FSR,F FWF T3,INDF ; Hepp! Filtret Šr nu uppdaterat! :) return ;--------------------------------------------------------------------------- ---- Sum16: ;Summerar ett intervall av 2-bytetal H:L till ett 3-bytetal i T4:T3:T2 ;Bšrjar pŒ lŒgbyten i FSR, och gŒr uppŒt. ;Ange totalt antal 2bytetal i W. movwf T1 ;antal 2-byte vi skall summera, rŠknar ner T1 clrf T2 ;Nolla utgŒngsvŠrdena clrf T3 clrf T4 Sum16loop: movf INDF,W ;HŠmta lŒgbyte addwf T2,F ;Addera till lŒgbyte ut ifcs ;Om carry, incf T3,F ; sŒ ška mellanbyte ut ifzs ;Om detta gav ZERO, (incf sŠtter Z, ej C !!) incf T4,F ; sŒ ška hšgbyte ut. incf FSR,F ;Peka pŒ hšgbyten, movf INDF,W ; och hŠmta den addwf T3,F ;Addera till mellanbyte ut ifcs ;Om carry, incf T4,F ; sŒ ška hšgbyte ut incf FSR,F ;Peka pŒ nŠsta tals lŒgbyte decfsz T1,F ;RŠkna ner talrŠknaren, och om det Šr tal kvar goto Sum16loop ; sŒ kšr igen return Morgan Olsson ph +46(0)414 70741 MORGANS REGLERTEKNIK fax +46(0)414 70331 H€LLEKS (in A-Z letters: "HALLEKAS") SE-277 35 KIVIK, SWEDEN mrt@iname.com ___________________________________________________________