www.mikrocontroller.net

Forum: Digitale Signalverarbeitung / DSP Messwerte glätten

Autor: Bastian G. (Gast)
Datum: 14.05.2008 17:38

Hallo,

mein Controller liest von 10 Kanälen 16-Bit Messwerte mit ca. 10 Hz ein.
Die Messwerte sind mit ca. 4 Bit ziemlich verrauscht. Mit 3 Hz soll ein
geglätteter Messwert ausgegeben werden.
Welche Methode wäre dafür geeignet (ausreichend schnell, aber
ressourcenschonend)?
Eine long Variable pro Kanal zum aufaddieren und anschließender Division
scheint mir zu ressourcenintensiv.
Eine exponentielle Glättung ist sicher zu langsam.

Was gäbe es noch für Möglichkeiten?

Grüße,
Bastian
Autor: Karl heinz Buchegger (kbuchegg) (Moderator)
Datum: 14.05.2008 17:41

Bastian G. wrote:
> Hallo,
>
> mein Controller liest von 10 Kanälen 16-Bit Messwerte mit ca. 10 Hz ein.
> Die Messwerte sind mit ca. 4 Bit ziemlich verrauscht. Mit 3 Hz soll ein
> geglätteter Messwert ausgegeben werden.
> Welche Methode wäre dafür geeignet (ausreichend schnell, aber
> ressourcenschonend)?
> Eine long Variable pro Kanal zum aufaddieren und anschließender Division
> scheint mir zu ressourcenintensiv.

Du kriegst von Atmel kein Geld zurück, wenn sich der µC langweilt.
Bei deinen Timing Werten kann der µC zwischendurch noch ein paar
hundert teuflisch schwierige quadratische Gleichungen (tm) lösen
ehe er vor Langeweile ins Koma fällt.
Autor: AC/DC (Gast)
Datum: 14.05.2008 17:46

Rauschen vom Messsignal ausfiltern?
Autor: Gast (Gast)
Datum: 14.05.2008 17:54

Addiere einfach z.B. 16 Messwerte und mache dann ein Rechtsshift um 4
Stellen. Da kommt der Controller auch nicht in schwitzen ;)

Gruß
Autor: Michael G. (linuxgeek) Benutzerseite
Datum: 14.05.2008 19:45

Bastian G. wrote:

> Eine long Variable pro Kanal zum aufaddieren und anschließender Division
> scheint mir zu ressourcenintensiv.
> Eine exponentielle Glättung ist sicher zu langsam.

Da sieht man mal wieder was heute fuer Vorstellungen von Rechenleistung
bestehen. Unter 64Bit bei 3GHz geht garnix... ne? ;)
Autor: I_ H. (i_h)
Datum: 14.05.2008 19:53

Nimm 2^n Werte und du brauchst nur logisch zu schieben. Bei 10ksps die
der Atmel locker mitmacht kannst du pro Kanal 1024 Samples aufnehmen und
hast immernoch 10Hz.
Und wenn du den ADC Interrupt benutzt hast du sogar noch massig
Rechenzeit für andere Dinge über.

Ach ja, und die Genauigkeit wird am Ende wohl eher bei 12..14 Bit
liegen.
Autor: Wolfgang Mües (Gast)
Datum: 14.05.2008 20:16

Du könntest die Abtastrate im Eingang auf 12 Hz hochdrehen, Dann kannst
Du 4 Messwerte addieren und das Ergebnis durch 4 teilen.

Durch 4 teilt man durch Schieben um 2 bit nach rechts (in C der Operator
">>").

Wenn Du die long-Variable vermeiden willst, kannst Du auch vor dem
Addieren jeden einzelnen Messwert durch 4 teilen. Dadurch verlierst Du
Genauigkeit, aber bei 4 bit Rauschen ist das vielleicht nicht so
wichtig.
Autor: Matt (Gast)
Datum: 14.05.2008 21:27

>Eine exponentielle Glättung ist sicher zu langsam.

http://www.ibrtses.com/embedded/exponential.html
Autor: Stephan (Gast)
Datum: 15.05.2008 08:20

ich bevorzuge die gleitende Mittelwertbildung.
Wert = Wert(alt) *3 + Wert (neu)
      --------------------------
                4

danach wird Wert zu wert (alt)

Voila
Autor: Läubi Mail@laeubi.de (laeubi) Benutzerseite
Datum: 15.05.2008 08:24

man kann auch sehr schön folgendes machen bei Kontinuierlichen Sachen
die sich nicht sprunghaft ändern (geschwindigkeit, temperatur...)

WERT_neu/2 + Wert_alt1/4 + Wert_alt2/8 + Wert_alt3/8

to be continued...
Autor: Bastian G. (Gast)
Datum: 15.05.2008 08:31

Danke schonmal für eure Anregungen!

Diesmal benutze ich keinen Atmel, sondern einen Freescale MC9S12. Hätte
ich erwähnen sollen.

Die Messwerte kommen über den I2C Bus, nicht von den internen ADCs. Was
die Prozessorauslastung hochtreibt ist allerdings das kontinuierliche
Senden von Messwerten über die serielle Schnittstelle. Die Routinen dazu
sind nicht optimal (Polling statt IRQ), lassen sich jetzt aber nicht
mehr ändern.

@Matt: Danke für den Link. Ich hatte diesen schon in einem älteren
Posting gefunden und mal mit Excel durchgerechnet. Erschien mir auf den
ersten Blick aber, selbst mit N = 0,25, sehr langsam.
Autor: Bastian G. (Gast)
Datum: 15.05.2008 11:18
Dateianhang: Mittelwert.png (10,3 KB, 161 Downloads)
preview image for Mittelwert.png

Im Anhang ein kleiner Vergleich verschiedener Methoden.
Sehr gut, da schnelle Reaktion auf Änderungen, gefällt mir die Variante
von Läubi. Allerdings müssen pro Kanal 4 Werte gespeichert werden. Bei
10 Kanälen ist das nicht wenig.
Autor: Kai Giebeler (runtimeterror)
Datum: 15.05.2008 11:36

>Allerdings müssen pro Kanal 4 Werte gespeichert werden. Bei
>10 Kanälen ist das nicht wenig.

Irgendwo wirst du wohl Prioritäten setzen müssen. Qualität vs.
Speicherbedarf vs. Rechenaufwand.

Ich bevorzuge Stephans Methode. Ist schnell implementiert und liefert
gute Resultate. Bei deinen Messwerten reicht ggf. schon folgende
Glättung:

Wert = Wert(alt) + Wert (neu)
      --------------------------
                2

Das reagiert noch einen Ticken schneller und braucht kaum Speicher.
Autor: eProfi (Gast)
Datum: 15.05.2008 17:41

@Stephan und Kai:

ich verwende eine ähnliche, aber bessere Methode:

Aver = Aver + ADC - (Aver >> x);

Das hat zur Folge, dass Aver auf den 2^x-fachen Wert von ADC ansteigt.

Entweder ich rechne gleich mit Aver weiter, oder teile ihn durch 2^x
(und runde) in dem Augenblick, in dem ich ihn brauche (was in der Regel
seltener als die Abtastrate ist).

Wenn ADC 16 Bit hat, bleibt nichts anderes als für Aver 24 oder 32 bit
zu verwenden.

Oder wie Wolfgang schrieb, kannst Du es auch so machen:

Aver = Aver + (ADC >> y) - (Aver >> x);

Aver ist dann im Bereich  ADC * (2^(x-y))

Bei z.B. x = y = 2   reichen dann auch für Aver 16 Bit aus.

Da war ich auch schonmal versucht, sowas zu schreiben, um einen Shift zu
sparen:

Aver = Aver + ((ADC - Aver) >> x);

Aber der Effekt ist nicht wie erwünscht, Aver ist dann immer einen Tick
zu klein.


Eine andere Methode wäre ein echter Digitalfilter (Tiefpass FIR oder
IIR) ala Bessel, Butterworth, Tschebyscheff....
Der reagiert schnell auf Änderungen und filtert trotzdem gut.

Ansonsten empfehle ich immer, die Ursache zu suchen und weniger an den
Symptomen zu doktern:
Vermutlich hast Du eine Gnd-Schleife oder ähnliches, also ein
Analog-Problem. Auch die digitalen Signale (SDA und SCL) können die
Wandlung beeinflussen. Da würde ich mal jeweils auf der Treiberseite
einen Dämpfungswiderstand (10-82 Ohm) einfügen.

Welche Sprache?
Um welche Signale handelt es sich?
Welche Wandler verwendest Du?
Habe mit der ADS125x-Familie (24 Bit Delta-Sigma) sehr gute Erfahrung
gemacht (mit erhöhtem externen Aufwand 18 echte Bits bei 100 Hz).
Autor: Gast (Gast)
Datum: 15.05.2008 17:52

Hallo,
die Form

xk+1 = (a*uk+1 + b*xk)/(a+b)

ist die zeitdiskrete Form eines Tiefpassfilters erster Ordnung.

xk+1 = a*uk+1 + (1-a)*xk

mit 0<=a<=1 als "Filterzeitkonstante". Wenn a=1 kein Filter, wenn a=0
alles gefiltert (alles tot). Man kann also mit a spielen und so das
Filter anpassen.
Autor: Läubi Mail@laeubi.de (laeubi) Benutzerseite
Datum: 15.05.2008 18:06

Bastian G. wrote:
> Im Anhang ein kleiner Vergleich verschiedener Methoden.
> Sehr gut, da schnelle Reaktion auf Änderungen, gefällt mir die Variante
> von Läubi. Allerdings müssen pro Kanal 4 Werte gespeichert werden. Bei
> 10 Kanälen ist das nicht wenig.
Ich benutz das um die Digitalanzeige meines Tachos vorm "zittern" zu
bewahren, klappt ganz gut, allerdings noch mit einer Stufe mehr.
Und 40Werte a 16bit sind gerade mal 80bytes Ram das ist auch noch nicht
soooo viel.
Autor: H_S (Gast)
Datum: 18.05.2008 10:58

Wie wäre es mit einem FIR Filter?
Autor: eProfi (Gast)
Datum: 20.05.2008 17:47

Ich habe nochmal nachgerechnet, auch das Filter von

Autor: Stephan (Gast)
Datum: 15.05.2008 08:20
ich bevorzuge die gleitende Mittelwertbildung.
        Wert(alt) *3 + Wert (neu)
Wert = ---------------------------
                4
danach wird Wert zu wert (alt)


erreicht übrigens auch nie den Eingangswert.



Das ganze hatten wir übrigens erst vor kurzem:
Beitrag "Digitales Filter"

Antwort schreiben

Die Angabe einer Email-Adresse ist freiwillig. Wenn Sie automatisch per Email über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
  • Aussagekräftigen Betreff wählen
  • Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
  • JPEG-Dateien (.jpg) nur für Fotos und Scans verwenden
  • Schaltpläne, Screenshots usw. als PNG oder GIF anhängen

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel






webmaster@mikrocontroller.netImpressumWerbung auf Mikrocontroller.net