Hallo Leute,
ich habe da gerade ein kleines Problem bei dem ich Hilfe bräuchte. Ich
überwache einen Absolutwert. Der Geber ist auf einer Schiene angebracht
und ich versuche herauszufinden, wann er sich in die eine, die andere
Richtung bewegt, bzw. wann Stillstand ist.
Das Problem ist, daß der Geber durch kleinste äußere Einflüsse im
Stillstand schon zwischen zwei Werten springt. Ich mache das momentan
so, daß ich einen Old-Wert aufnehme und danach einen New-Wert und die
Differenz bilde. Wäre diese 0 würde ich mich nicht bewegen. Allerdings
verfälscht die springerei des Messwerts das Ergebnis.
Hat jemand einen Tip wie mann das am besten machen kann ? Ich glaube
nicht, daß ein Toleranzband die beste Idee ist.
Danke
Peter der Kleine schrieb:> Hat jemand einen Tip wie mann das am besten machen kann ? Ich glaube> nicht, daß ein Toleranzband die beste Idee ist.
Letzten Endes wirst du aber keine andere Wahl haben.
Ein Filter könnte Abhilfe schaffen.
IIR Filter ... Kalman Filter ...
Ein AD-Wandler hat immer etwas rauschen mit dabei ... dazu noch den
Quantisierungsfehler ... ist halt so.
Auch ein Tiefpass am Eingang kann da Verbesserung aber kaum absolute
Abhilfe schaffen.
mehrmals Sampeln und den Mittelwert bilden, hilft aber auch nur
beschränkt. Ein Toleranzband brauchst du vermutlich eh und dann noch
eine Betrachtung der letzten paar Bewegungen, also du erwartest den
neuen Messwert irgendwo anhand der letzten Positionen.
"Glauben" ist in technischen Angelegenheiten nicht angebracht.
Spätestens seit Voltaire sollten wir uns bemühen zu wissen. ;-)
Was ist das für ein Geber? Nach welchem Prinzip funktioniert er?
Was für Bewegungen, mit welcher Geschwindigkeit und Beschleunigungen
willst Du erkennen? Vor allem: Was sind die Minima?
Ein Toleranz, ein gewisser Bereich in dem Bewegungen ignoriert werden
macht Sinn. Evtl. in Zusammmenhang mit der Zeit. In Erweiterung ein
Mittelwert oder ein höherwertiger Filter.
Hallo,
das mit den Tiefpässen oder Filtern ist zwar prinzipiell eine gute Idee.
Leider ist die Sachlage aber so:
An der Hardware wird definitiv nichts geändert. In meinem C-Code kommen
also einfach die Werte in ein Array und werden dort je zyklus
aktualisiert.
Würdet ihr das wirklich so machen:
Ist-Wert Aufnahme (Old-wert)
Ist-Wert Aufnahme (New-wert)
Differenz bilden
Wenn Differenz <= Positive Toleranzgrenze && Differenz >= Negative
Toleranzgrenze
Dann
Stillstand
>das mit den Tiefpässen oder Filtern ist zwar prinzipiell eine gute Idee.>Leider ist die Sachlage aber so:>An der Hardware wird definitiv nichts geändert.
Öh.
Das ist doch kein Widerspruch. Man kan filter auch in SW implementieren.
>Würdet ihr das wirklich so machen...
Ja. Genau. So oder anders.
Sagst Du mal was zu Deinen Vorkenntnissen und dem Kontext des Problems?
Du musst uns erklären was Du vorhast.
Das was Du hier skizzierst geht manchmal super, versagt aber ein anderes
mal kläglich.
ein Auto würde z.B. ganz langsam und unbemerkt den Berg runterfahren.
Das ist ein Problem, das relativ häufig auftritt, wenn man versucht, mit
kurzer Zykluszeit eine Geschwindigkeit durch Ableitung eines
Inkrementalgebers zu messen.
Du musst erst mal eine Geschwindigkeit als Grenzwert festlegen. In der
Regel ist diese langsamer als 1 Inkrement/Zyklus; dadurch spricht dann
die Überwachung jedesmal an, wenn sich der Geber um ein Inkrement
bewegt.
Die Ist-Geschwindigkeit muss deshalb gefiltert werden, z.B. durch einen
PT1-Tiefpass oder durch Mittelwertbildung über mehrere Zyklen hinweg. Je
nach Grenzwert muss die Filterzeitkonstante bzw. das Intervall für die
Mittelwertbildung sinnvoll gewählt werden.
Ich nehme zyklisch die Werte des Gebers entgegen.
1. Zyklus einen Wert (Old-Wert)
2. Zyklus einen Wert (New-Wert)
Noch im 2. Zyklus die Differenzbildung
Noch im 2. Zyklus schreibe ich auf den alten Wert (Old-Wert) den
New-Wert um keinen weiteren Zyklus zu verlieren
Dann beginnt das Spiel von vorne. Ab dem zweiten Zyklus bilde ich also
ständig die Differenz.
Wie schon gesagt:
Im Stillstand (rein optisch) kann es trotzdem vorkommen, daß die Werte
um 0 Herumspringen.
PS:
Daß man einen Filter auch in SW realisieren kann ist mir klar. Jedoch
steigt der Aufwand damit ungeheuer an. Hier geht es nicht um eine ganz
exakte Nullposition. Wenn ich um ca. 2 Millimeter schwanke macht das
nichts, aber die Schwankung sollte eben tolleriert werden.
wieso krasser Aufwand?
Mittelwert über 256 Werte geht so: Array aus 256 Plätzen bilden. Da wird
der Reihe nach immer reingeschrieben. Zusätzlich in einer anderen
Variable die Summe über alle Werte speichern. Wenn ein neuer Wert
ankommt, und du an der Stelle 134 bist, von der Summe den 134. Arraywert
abziehen, den neuen Wert addieren und den neuen Wert an Stelle 134 im
Array speichern. Dann zum Ausgang die Summe 8 Stellen nach rechts
schieben. Macht so ~10 Taktzyklen.
sorry,
aber das hab ich jetzt nicht ganz verstanden.
Angenommen mein Schlitten bleibt stehen (das kann ich ja detektieren)
und schwingt um 0, dann würdet ihr also über einige Zylken den
Mittelwert der Gebersignale aufnehmen. Dieser steht dann auf irgendeinem
(kleinen) Wert. Wenn dieser Wert kleiner ist als eine bestimmte Grenze,
dann würdet ihr sagen daß ich stehe ?
Mittelwert ist ein ganz schlechter Filter für Messwerte und auch
allgemein. Warum meinen immer leute den verwenden zu müssen? Er
verbessert das Messsignal in keinster Weise, er verwischt es nur. Was du
suchst ist der Zentralwert (Median).
Wie wär's mit einer mitlaufenden Hysterese? Dazu brauchst Du eine untere
Grenze, eine obere Grenze, einen Eingangswert und einen Ausgangswert. So
würde man das programmieren:
1. Oberen Grenzwert, unteren Grenzwert und Ausgangswert auf Null setzen.
2. Eingangswert einlesen
3. Wenn Eingangswert > obere Grenze, dann
3.1 Obere Grenze auf Eingangswert setzen
3.2 Untere Grenze auf Eingangswert minus Hysterese setzen
3.3 Ausgangswert auf den Durchschnitt der Grenzwerte setzen
4. Wenn Eingangswert < untere Grenze, dann
4.1 Untere Grenze auf Eingangswert setzen
4.2 Obere Grenze auf Eingangswert plus Hysterese setzen
4.3 Ausgangswert auf den Durchschnitt der Grenzwerte setzen
5. Zurück zu 2
Damit bekommst Du ein absolut rauschfreies Signal (sofern die Hysterese
größer als das Rauschen ist), die Geschwindigkeit bleibt gleich und das
Signal ist auch nicht "verwischt". Der einzige Nachteil ist, dass der
Ausgangswert nicht ganz an das Minimum und das Maximum des
Eingangswertes rankommt (auf 1/2 der Hysterese).
Gruß
Jonathan
Herzlichen Dank an euch alle für die Antworten.
Insbesondere an Kevin K. und Johannes E.
Aus euren Antworten konnte ich noch notwendige Erweiterungen ableiten
(die zu implementieren zwar nicht ganz einfach sind) aber sehr zur
Stabilität der Überwachung beitragen könnten.
Übrigens auch vielen Dank an Jonathan für deine sehr ausführliche Idee,
auch wenn ich es wohl doch letzenendes anders machen werde sind solche
Denkanstöße es oft wert sich zu notieren um vielleicht später einmal
darauf zurückgreifen zu könnnen.
Peter der Kleine schrieb:> Ich nehme zyklisch die Werte des Gebers entgegen.>> 1. Zyklus einen Wert (Old-Wert)> 2. Zyklus einen Wert (New-Wert)> Noch im 2. Zyklus die Differenzbildung> Noch im 2. Zyklus schreibe ich auf den alten Wert (Old-Wert) den> New-Wert um keinen weiteren Zyklus zu verlieren>> Dann beginnt das Spiel von vorne. Ab dem zweiten Zyklus bilde ich also> ständig die Differenz.
Ja, genau so. Die Differenz ist dann die Geschwindigkeit.
Diese muss dann noch gefiltert werden, am einfachsten nach diesem
Schema:
v_filter_neu = v_filter_alt + (diff - v_filter_alt) * k
k ist eine Zahl im Bereich 0..1. Wenn die Filterzeitkonstant z.B. 100
Zyklen betragen soll, muss k den Wert 0.01 haben.
Jonathan Strobl schrieb:> Wie wär's mit einer mitlaufenden Hysterese? Dazu brauchst Du eine untere> Grenze, eine obere Grenze, einen Eingangswert und einen Ausgangswert...
Das ist eigentlich nur dann sinnvoll, wenn man ein echtes Rauschen hat.
Bei einer Stillstandsüberwachung kommt das Problem eher durch die
Quantisierung.
Beispiel:
Motor hat einen Geber mit 2048 Strichen, also 8192 Inkremente pro
Umdrehung.
Grenzdrehzahl für Stillstandsüberwachung ist 1 U/min
Zykluszeit ist 1 ms
Der Grenzwert sind also ca. 136 Inkremente/s = 0,136 Inkremente/Zyklus
Man muss also eine Geschwindigkeit auflösen, die weniger als ein
Inkrement/Zyklus ist. Durch die Hysterese-Auswertung gewinnt man aber
keine Auflösung.
EQVVS OCTOBER schrieb:> Mittelwert ist ein ganz schlechter Filter für Messwerte und auch> allgemein. Warum meinen immer leute den verwenden zu müssen? Er> verbessert das Messsignal in keinster Weise, er verwischt es nur. Was du> suchst ist der Zentralwert (Median).
Diese Aussage ist so nicht richtig. Je nach Anwendung hat auch ein
Mittelwertfilter seine Berechtigung.
Im Prinzip ist ein Mittelwertfilter die einfachste Art eines
FIR-Filters, bei dem alle Koeffizienten =1 sind. Er hat also eine
lineare Phase und Nullstellen bei allen ganzzahligen Vielfachen der
Filterzeit.
Wenn man z.B. ein Signal hat, das durch PWM-Modulation erzeugt wird
(also mit fester Frequenz), kann man mit Mittelwertbildung über eine
PWM-Periode sehr elegant die Grundwelle und alle Oberwellen der PWM
herausfiltern.
Für eine Geschwindigkeitsmessung ist Mittelwertbildung allerdings nicht
so optimal, da ist ein PT1-Tiefpass sinnvoller.
Leute Leute,
da raucht die Birne. Ich habe gerade einen Kurzschluß an der Stelle, an
der die physikalischen Dinge ins Spiel kommen.
Möglicherweise (und zwar ziemlich sicher) wird mein Schlitten bei sehr
langsamer Fahrt keinen neuen Wert erreichen bevor der nächste Zyklus
wieder durchläuft und den Wert aufnimmt. Nun wäre also der neu
aufgenommene und der alte der selbe Zahlenwert und ich würde als
Bewegung den Stillstand detektieren.
Nun möchte ich das so machen, daß ich zwar in jedem Zyklus eine Bewegung
ermittle, diese aber nur unter Array_Vorlaeufige_Bewegung und in jedem
weiteren Zyklus nachschaue, ob das ermittelte Ergebnis immer noch mit
Array_Vorlaeufige_Bewegung uebereinstimmt.
Erst wenn diese Ermittlung sagen wir mal 10mal durchlaufen wurde, dann
schreibe ich auf Array_endgueltige_Bewegung einen Zahlenwert, der
entweder rauf-runter bzw. Stillstand entspricht.
Gibts da draußen irgendjemanden der das anders machenw würde ?
Für Tips bin ich sehr dankbar
Peter der Kleine schrieb:> schreibe ich auf Array_endgueltige_Bewegung einen Zahlenwert, der> entweder rauf-runter bzw. Stillstand entspricht.
benötigst du nur die boolsche Information "Bewegung in die eine
Richtung" bzw. "Bewegung in die andere Richtung" bzw. "Stillstand" oder
brauchst bei den Bewegungen auch die Größe der Bewegung?
> Gibts da draußen irgendjemanden der das anders machenw würde ?
Von der Idee her würde ich das auch so machen. Also dass Stillstand erst
dann gilt, wenn er n mal hintereinander festgestellt wurde.
Nur implementieren würde ich das anders.
Ich hätte einfach einen Zähler, der mit jedem mal Stillstand detektieren
um 1 erhöht wird. Kommt dein Messverfahren zum Schluss: kein Stillstand,
dann wird der Zähler wieder auf 0 zurückgesetzt. Erreicht der Zähler
tatsächlich irgendwann mal den Wert n, dann wurde folgerichtig n mal
hintereinander Stillstand festgestellt und ich melde meinem Benutzer:
wir stehen!
Für rauf/runter würde ich das genau gleich machen, WENN die Größe der
Bewegung nicht gebraucht wird.
Im Prinzip mache ich das genauso wie du auch gesagt hast.
Da gibts noch eine Frage zu der Sache mit dem inkrementieren des
Zählers.
Von einem inkrement zum anderen dauert es ja genau einen Zyklus. Kann
man das eigentlich so sagen ?
Denn prinzipiell könnte ich auch mit der Zykluszeit arbeiten (dafür habe
ich eine Funktion, die mir diese zurückgibt) allerdings bräuchte ich
dann einen festen Zeitwert, der vergehen darf bis ich endgueltige
Positionen zurueckgebe.
wenn man nun an der Maschine steht und im experiment einen Zahlenwert zu
finden hat, bei dem die Ausgaben zur Bewegung passen, finde ich es
einfacher die Ausgabe der tatsächlichen Bewegung über die ZyklenANZAHL
und nicht über eine ZEITBASIS zu realisieren. Ich müßte halt nur den
Zählwert erhöhen (sofern man wirklcih sagen kann, daß zwischen den
inkrementen genau ein Zyklus vergeht...was aber halt eigentlich genau so
sein MUSS...wenn ich mich nciht irre )
Peter der Kleine schrieb:> Möglicherweise (und zwar ziemlich sicher) wird mein Schlitten bei sehr> langsamer Fahrt keinen neuen Wert erreichen bevor der nächste Zyklus> wieder durchläuft und den Wert aufnimmt. Nun wäre also der neu> aufgenommene und der alte der selbe Zahlenwert und ich würde als> Bewegung den Stillstand detektieren.
Ja, du hast entweder eine Änderung um ein Inkrement oder keine Änderung.
Du brauchst also in irgendeiner Form eine Mittelung über mehrere Zyklen.
Peter der Kleine schrieb:> Erst wenn diese Ermittlung sagen wir mal 10mal durchlaufen wurde, dann> schreibe ich auf Array_endgueltige_Bewegung einen Zahlenwert, der> entweder rauf-runter bzw. Stillstand entspricht.
Du könntest genau so gut nur in jedem zehnten Zyklus die Differenz
berechnen (die Differenz zum 10. Zyklus davor).
Mach es mit einem Filter, so wie ich's oben beschrieben habe. Das
funktioniert wirklich gut, ich hab das schon oft gemacht.
Wenn du noch nie einen Filter programmiert hast, dann ist das jetzt eine
gute Gelegenheit. Es sieht komplizierter aus als es ist.
Karl Heinz Buchegger schrieb:> Ich hätte einfach einen Zähler, der mit jedem mal Stillstand detektieren> um 1 erhöht wird. Kommt dein Messverfahren zum Schluss: kein Stillstand,> dann wird der Zähler wieder auf 0 zurückgesetzt.
Dann hat man aber das Problem, wenn der Geber genau zwischen zwei
Inkrementen steht und zwischen diesen beiden Positionen dauernd hin- und
herspringt.
Johannes E. schrieb:>> Ich hätte einfach einen Zähler, der mit jedem mal Stillstand detektieren>> um 1 erhöht wird. Kommt dein Messverfahren zum Schluss: kein Stillstand,>> dann wird der Zähler wieder auf 0 zurückgesetzt.>> Dann hat man aber das Problem, wenn der Geber genau zwischen zwei> Inkrementen steht und zwischen diesen beiden Positionen dauernd hin- und> herspringt.
Moment.
Ich dachte die 'Filterung' sei jetzt schon gegessen?
Zu einer Zeit als Mauspositionen sich noch ein wenig veränderten, selbst
wenn die Maus völlig ruhig am Tisch lag, haben wir das so gemacht, dass
wir eine Mausbewegung erst dann akzeptierten, wenn sie sich von der
letzten als Stillstand anerkannten Mausposition mindestens 5 Pixel in X
bzw. Y wegbewegt hat. Zumindest bei der Maus hat das ganz gut
funktioniert.
Karl Heinz Buchegger schrieb:> Zu einer Zeit als Mauspositionen sich noch ein wenig veränderten, selbst> wenn die Maus völlig ruhig am Tisch lag, haben wir das so gemacht, dass> wir eine Mausbewegung erst dann akzeptierten, wenn sie sich von der> letzten als Stillstand anerkannten Mausposition mindestens 5 Pixel in X> bzw. Y wegbewegt hat. Zumindest bei der Maus hat das ganz gut> funktioniert.
Das kommt natürlich auch drauf an, wie man Stillstand definiert. Das ist
nämlich gar nicht so eindeutig, wie es sich vielleicht anhört:
Man kann festlegen, dass bei einer Geschwindigkeit unterhalb eines
bestimmten Grenzwerts Stillstand gemeldet werden soll. In diesem Fall
wäre ein ganz langsames wegdriften also auch noch erlaubt. Das ist z.B.
dann sinnvoll, wenn man nach dem Abbremsen einer Fräßspindel die
Schutztüre öffnen will. Hier ist es nicht wichtig, dass die Spindel
genau auf einer bestimmten Position stehen bleibt.
Oder man definiert, dass sich die Position von einem bestimmten Punkt
aus nicht über eine bestimmte Distanz entfernen darf. In diesem Fall
wäre eine Bewegung innerhalb dieses Bereichs erlaubt (sogar eine relativ
schnelle Bewegung). Das ist dann also eine Positions- und keine
Geschwindigkeitsüberwachung.
Man kann natürlich auch beides miteinander kombinieren.
Erst nachdem man festgelegt hat, was für eine Überwachung benötigt wird,
sollte man sich den genauen Lösungsansatz überlegen.
Hallo Johannes E.
Daß es eine gute Gelegenheit wäre, sich mit dem Programmieren eines
Filters auseinander zu setzen stimmt in der Tat.
Allerdings verstehe ich es irgendwie nicht so ganz was mit deiner Formel
hier passiert.
Johannes E. schrieb:> Peter der Kleine schrieb:>> Ich nehme zyklisch die Werte des Gebers entgegen.>>>> 1. Zyklus einen Wert (Old-Wert)>> 2. Zyklus einen Wert (New-Wert)>> Noch im 2. Zyklus die Differenzbildung>> Noch im 2. Zyklus schreibe ich auf den alten Wert (Old-Wert) den>> New-Wert um keinen weiteren Zyklus zu verlieren>>>> Dann beginnt das Spiel von vorne. Ab dem zweiten Zyklus bilde ich also>> ständig die Differenz.>> Ja, genau so. Die Differenz ist dann die Geschwindigkeit.>> Diese muss dann noch gefiltert werden, am einfachsten nach diesem> Schema:>> v_filter_neu = v_filter_alt + (diff - v_filter_alt) * k>> k ist eine Zahl im Bereich 0..1. Wenn die Filterzeitkonstant z.B. 100> Zyklen betragen soll, muss k den Wert 0.01 haben.
Als erstes sollte man Festhalten, daß meine Differenz keine
Geschwindigkeit ist, weil ich die Zykluszeit nicht mit verwende. Meine
Differenz ist also eigentlich nur eine Positionsdifferenz, also ein Weg.
Weg_neu = Weg_alt + (diff - Weg_alt) * k
Irgendwie steh ich gerade auf der Leitung, aber ich komme nicht drauf,
was hier tatsächlich gefiltert wird.
Es wäre sehr nett von Dir wenn du Dir nochmals Zeit nehmen könntest um
das zu erklären.
Herzlichen Dank
Peter der Kleine schrieb:> Als erstes sollte man Festhalten, daß meine Differenz keine> Geschwindigkeit ist, weil ich die Zykluszeit nicht mit verwende. Meine> Differenz ist also eigentlich nur eine Positionsdifferenz, also ein Weg.
Das ist trotzdem eine Geschwindigkeit, allerding nicht in der Einheit
Weg/s sondern Weg/Zyklus. Da der Zyklus einem Zeitintervall entspricht,
kann man das als Zeit betrachten.
Peter der Kleine schrieb:> Es wäre sehr nett von Dir wenn du Dir nochmals Zeit nehmen könntest um> das zu erklären.
Ich versuchs mal; zuerst einige Definitionen:
x_act: Aktuelle Position
x_old: Position aus dem letzten Zyklus
v_act: aktuelle, ungefilterte Geschwindigkeit, also v_act = x_act -
x_old
v_filter_act: gefilterte Geschwindigkeit
v_filter_old: gefilterte Geschwindigkeit aus dem letzten Zyklus
Dann kann man den Filter folgendermaßen Berechnen:
v_filter = v_filter_old + (v_act - v_filter_old) * k
Der Ausdruck "v_act - v_filter_old" ist die Differenz zwischen der
aktuell gemessenen Geschwindigkeit und dem gefilterten (gemittelten)
Wert.
Von dieser Differenz wird ein kleiner Anteil (je nach k) auf den
gefilterten Wert draufaddiert. Wenn v_act und v_filter gleich groß sind,
wird nichts draufaddiert, der Filter ist dann eingeschwungen.
Die Filterzeitkonstante kann für kleine Werte von k relativ einfach als
1/k angenähert werden. Das stimmt zwar nicht ganz exakt, ist aber nicht
so wichtig.
Wenn man z.B. eine Filter-Zeitkonstante von 20 Zyklen haben möchte, muss
k=0.05 sein.
Diese Betrachtung war jetzt für Fließkomma-Zahlen. Wenn du einen µC mit
Integer-Zahlen hast, berechnet man das am besten mit
Festkomma-Arithmetik.
Dazu muss man die gefilterte Geschwindigkeit normieren, z.B. mit 8
binären Nachkommastellen.
Die Formel ist dann folgendermaßen:
v_filter = v_filter_old + (v_act - ((v_filter_old + 128) >> 8) * k
mit k = 0 .. 256 entspricht 0.0 .. 1.0
Beachte den Ausdruck (+ 128), der ist dazu da, dass korrekt gerundet
wird. Wenn man eine andere Normierung haben möchte, muss das auch
angepasst werden.
Die Variable v_filter ist damit um den Faktor 256 größer als v_act, die
hinteren 8 Bit sind die Nachkommastellen.
Beispiel mit Zahlen:
k = 8, entspricht also 0.03125, die Zeitkonstante ist damit 32 Zyklen
Startwert: v_filter = 0
v_act ist abwechselnd 0 und 1
1. Zyklus: v_act = 0 -> v_filter = 0
2. Zyklus: v_act = 1 -> v_filter = 8 (entspricht 0,03125)
3. Zyklus: v_act = 0 -> v_filter = 8 (entspricht 0,03125)
4. Zyklus: v_act = 1 -> v_filter = 16 (entspricht 0,0625)
5. Zyklus: v_act = 0 -> v_filter = 16 (entspricht 0,0625)
6. Zyklus: v_act = 1 -> v_filter = 32 (entspricht 0,09375)
7. Zyklus: v_act = 0 -> v_filter = 32 (entspricht 0,09375)
8. Zyklus: v_act = 1 -> v_filter = 64 (entspricht 0,125)
9. Zyklus: v_act = 0 -> v_filter = 64 (entspricht 0,125)
...
v_filter = 128:
v_act = 1 -> v_filter = 128 (entspricht 0,500)
v_act = 0 -> v_filter = 127 (entspricht 0,496)
v_act = 1 -> v_filter = 128 (entspricht 0,500)
v_act = 0 -> v_filter = 127 (entspricht 0,496)
...
Der Wert v_filter pendelt sich also bei 128 ein, das ist eine
Geschwindigkeit von 0,5 Inkrementen/Zyklus. Man bekommt also aus der
Abfolge von abwechselnd 0 und 1 einen Mittelwert.
Wenn v_act weniger oft ungleich 0 wäre, würde sich der Filter bei einem
kleineren Wert einpendeln.
Ich hoffe, das hilft dir weiter.
Hallo Johannes,
recht herzlichen Dank für deine sehr ausführliche Antwort. Es sieht sehr
interessant und professionell aus.
Ich habe in der Zwischenzeit etwas anderes programmiert. Was hältst du
eigentlich davon.
Ich nehme jeden Wert den mir der Geber liefert und berechne immer die
Differenz. Diese Differenz untersuche ich ganz simpel ob > 0 oder <0.
Der Stillstand ist ein extra Programmteil. Jetzt mal nur auf oder ab.
Wenn ich >0 bin, dann schreibe ich eine 1 in einen Ringpuffer. Das mache
ich über eine (einstellbare) zyklusanzahl von z.B. 10 Zyklen. Nach 10
zyklen multipliziere ich die Elemente meiens Ringpuffers. Erst wenn nach
der Multiplikation 1 rauskommt gehe ich davon aus, daß er tatsächlich
nach oben fährt.
Das selbe mache ich bei der Stillstandsdetektion (allerdings innerhalb
definierter Grenzen um 0).
Solange ich mich also innerhalb diesen Grenzen befinde schreibe ich eine
1 in einen Ringpuffer. Schwinge ich über, steht an einer Stelle eine 0
und das Produkt des Ringpuffers ergibt 0.
Das Problem ist, daß ich sehr wenig Zeit habe um den Code zu
implementieren. Erst mal brauch ich was lauffähiges. Verbessern kann ich
das dann nach und nach.
Was hältst du von meinem Vorschlag ?
Peter der Kleine schrieb:> Was hältst du von meinem Vorschlag ?
Das hört sich ziemlich kompliziert an, man muss da Zyklen mitzählen und
mehrere Ringpuffer verwalten und dann auch noch viele Werte
multiplizieren.
Es könnte schon funktionieren, ist aber im Vergleich zu einem einfachen
Filter sicherlich nicht weniger Aufwand.
> Wenn ich >0 bin, dann schreibe ich eine 1 in einen Ringpuffer. Das mache> ich über eine (einstellbare) zyklusanzahl von z.B. 10 Zyklen. Nach 10> zyklen multipliziere ich die Elemente meiens Ringpuffers. Erst wenn nach> der Multiplikation 1 rauskommt gehe ich davon aus, daß er tatsächlich> nach oben fährt.
Das heist, du detektierst auf eine Mindestdrehzahl von 1
Inkrement/Zyklus. Falls das zufällig zur Vorgabe passt, kann man das
theoretisch so machen. Es ist sehr unflexibel, falls du mal eine andere
Grenzdrahzahl haben möchtest.
> Das selbe mache ich bei der Stillstandsdetektion (allerdings innerhalb> definierter Grenzen um 0).>> Solange ich mich also innerhalb diesen Grenzen befinde schreibe ich eine> 1 in einen Ringpuffer. Schwinge ich über, steht an einer Stelle eine 0> und das Produkt des Ringpuffers ergibt 0.
Wie ist denn jetzt die Anforderung an die Stillstandsüberwachung? Es
kann schon sein, dass es funktionier, aber das Risiko ist groß, dass es
sich dann doch nicht so verhält wie man sich das vorgestellt hat.
Auserdem ist es nicht sehr schon, wenn man für eine andere Filterzeit
die Array-Größe (Länge des Ringpuffers) ändern muss. Bei der Variante
mit dem Filter kann man die Filter-Zeitkonstante sehr einfach zur
Laufzeit ändern.
Hallo,
ohne genauere Angaben isses wirklich schwierig, dir passend zu helfen.
Du hast momentan eine schlechte Version des Vorschlags aus dem Beitrag
Beitrag "Re: Gedankenanstoß Messwertauswertung" implementiert.
Bedenke: Wenn du einen Ringpuffer auf Nullen überprüfst, machst du
nichts anderes, als vorrauszusetzen, dass X mal hintereinander deine
Bedingung erfüllt sein muss. Das lässt sich einfacher durch einen Zähler
realisieren, den man auf 0 setzt und bei Erfüllung deiner Bedingung
inkrementiert. Wird die Bedingung nicht erfüllt, wir der Zähler wieder
auf null gesetzt.
Wenn der Zähler einen gewissen Wert X erreicht hat, dann gilt das
Ereignis als sicher.
Hallo,
jetzt habe ich einiges nochmals überdacht und da stellen sich schon
einige Fragen.
Aufgrund der Trägheit der Mechanik (die ist echt protzig) macht es
eigentlich gar keine Sinn in jedem Zyklus eine Bewegungsänderung zu
machen.
Deshalb nehme ich jetzt im ersten Zyklus alle "Alt" Werte auf, jedoch
die Neuwerte erst nach einer einstellbaren Anzahl an Zyklen.
Die Berechnung der Position erfolgt somit nicht mehr in jedem Zyklus
sondern sagen wir mal nach 20 Zyklen. Langsame Fahrten großer Massen
kann ich also so zuverlässiger feststellen.
Jetzt stellt sich nur die Frage ob der Ringpuffer in den ich die
Bewegungen schreibe und erst dann als solche ausgebe wenn mehrere
Ergebnisse das selbe Resultat liefern überhaupt noch nötig ist.
Was meint Ihr ? Theoretisch verbessert der Ringpuffer das Ergebnis ja
schon, weil ich nicht einem ermittelten Wert vertraue, sondern erst eine
Ausgabe mache, wenn ich mehrmals das selbe Resultat erhalten habe,
jedoch sind die Schwankungen, welche auftreten könnten wenn ich Zyklus
für Zyklus eine Berechnung mache ja dadurch schon erschlagen, daß ich
das jetzt nur alle n-Zyklen mache.
Wie seht ihr das mit dem Ringpuffer bei einer Messwertaufnahme alle n
Zyklen ?