Forum: Digitale Signalverarbeitung / DSP / Machine Learning Vorgehensweise Encoder digital auslesen, Geschwindigkeit etc eines Motors berechnen


von :-) (Gast)


Lesenswert?

Hallo =)

Ich möchte - nun als praktische Anwendung der Regelungstechnik + 
Digitaler Signalverarbeitung - eine Motorsteuerung bauen. Es geht hier 
erst einmal um das Berechnen/Anzeigen der Winkelposition und der 
Geschwindigkeit.

Ich habe sowohl Digisiv, Nachrichtentechnik und Steuerungs- und 
Regelungstechnik in der Uni gehört, die theoretischen Grundlagen sollten 
da sein. Aber die praktische Umsetzung natürlich nicht -.-

Los gehts:

An der Motorwelle ist ein Inkrementalencoder befestigt, mit 5000 
Steps/Umdrehung. Der Encoder hat einen Quadraturausgang, der über einen 
Pegelwandler mit einem STM32 verbunden ist. Der uC besitzt in Hardware 
einen Encodereingang. Da der STM32 4-fach Abtastet ergeben sich 20000 
Counts/Umdrehung. Das Counter Reset Register habe ich auch auf 20000 
eingestellt, weil ich damit dann genau detekieren kann, wie viele 
Umdrehungen stattgefunden haben (oder würdet ihr den Wert höher 
ansetzen, das Register ist 16 Bit breit).
Nun wird mit 100Hz dieses Register abgetastet, in einen Puffer 
geschrieben und per UART rausgeschickt. Per Matlab greife ich auf die 
serielle Schnittstelle zu und baue aus den Hex Werten meine Zahlen 
zusammen.

Weil nach einer Umdrehung der Überlauf kommt, ist die Kurve natürlich 
unstetig. Ich habe versucht, mir die Kurve stetig fortzusetzen, indem 
ich die Sprungstellen detektiere (ganz primitiv):
1
n=1
2
for i=1:ende
3
if((angle(i) > 1.8e4 && angle(i+1) < 0.05e4)) 
4
    sprung_hoch(n)=i
5
    n++
6
end
Die Grenzen sind erstmal willkürlich gesetzt. Wenn es da vernünftige 
Vorschläge gibt, wie ich die berechnen kann, immer her damit ;)

Das ganze für sprung_runter analog.

Dann addiere bzw subtrahiere ich ab den jeweiligen Sprungstellen 20000. 
Die Kurve sieht dann auch schön fortgesetzt aus.

Von den "kontinuierlichen" Winkeldaten möchte ich dann die 
Geschwindigkeit berechnen, also Differenzenquotient von je zwei 
benachbarten Werten. Da geht die Sache natürlich schon los, es wird sehr 
zackelig. Diese Werte habe ich mit einem moving average Filter 
(einfacher FIR, mit den 16 Koeffizienten 1/16). Sieht besser aus (halt 
geglättet), aber in einem anderen Thread wurde bereits angemerkt, dass 
dies nicht der richtige Weg sein könnte.

Soweit der Stand der Dinge.

Jetzt habe ich einige Fragen (es geht momentan um die Nachbearbeitung 
einer Messkurve in Matlab. Es geht noch nicht um die Regelung!)

- Die Abtastfrequenz sollte mehr als doppelt so hoch sein, wie die 
Grenzfrequenz/Signalfrequenz des Signals. Aber wie ist die 
Grenzfrequenz? Da ich noch gar keinen Filter angewendet habe wird das 
Signal ja kaum bandbegrenzt sein.
- Was ist überhaupt die "Signalfrequenz"? Die Drehfrequenz des Winkels? 
Die kann ja u.U. ziemlich groß werden ;) Ich nehme daher mal 
3000u/min=50u/s an. Pro Umdrehung gibts 4*5000 Steps -> 1e6 steps/s. 
Krass :D. Wenn ich zweimal abtasten möchte bei dem Register, das bei 
20000 überläuft muss ich mit 100Hz abtasten: 1e6 
steps/s/20000steps=50/s. Doppelt soviel -> >100Hz. Stimmt das?
- Muss ich das aufgezeichnete Winkelsignal jetzt fortsetzen, wie oben 
beschrieben, oder ist es sinniger das als eine Art Sägezahn Signal 
aufzufassen? Fortgesetzt wirkt es halt realistisch, gibt den echten 
Winkel an.
- Wenn ich langsamer als mit 3000u/min drehe habe ich mehr Abtastpunkte 
pro Umdrehung. Da könnten z.B. auch Ausreißer drin sein, wie glätte ich 
die?
- Sollte man mit den Abtastpunkten weiter rechnen (und durch Ausreißer 
heftige Sprünge in Kauf nehmen), oder sollte man versuchen das Signal zu 
interpolieren und damit wieder quasi Analog machen (splines?)?
- Sollte ich ein (möglichst ideales) Eingangsfilter (TP) mit 50Hz 
ansetzen? Dadurch bekäme ich jedoch höhere Umdrehungen nicht mit, oder 
gingen die eh im Alias unter?
- Matlab bietet ja diverse Filter an, die einen besseren Frequenzgang 
haben, als der einfache Differenzenquotent : v(n)=(q(n+1)-q(n))/T, der 
eher Hochpass als Tiefpasscharakteristik aufweist. Aber wenn ich die 
anwende, erhalte ich dann überhaupt noch die Geschwindigkeit? Wenn ich 
eine höhere Ordnung wähle könnte doch auch schon die Beschleunigung 
rauskommen?
- Wie glätte ich am besten meine zackeligen Kurven ohne relevante 
Informationen zu verlieren?

In der Theorie gabs nämlich immer eine wunderschöne gerade, stetige 
Kurve eines Motors, da musste nix mehr geglättet werden, sowas haben wir 
einfach nicht gelernt :/

Und je nachdem, wie groß der Aufwand oben wird (z.B. mit 
Eingangsfilter), wie soll man denn sowas in dem uC in Echtzeit zur 
Regelung verwenden? Geht doch garnicht? Ich kann doch nur aus den paar 
Werten, die ich gerade habe eine Geschwindigkeit berechnen. Wenn die 
schon zackelig sind, wie soll die Regelung da vernünftig klar kommen?


Ihr seht, Fragen über Fragen. Ich bedanke mich ganz herzliche bei 
denjenigen, die sich das Spektakel hier durchgelesen haben.

Wenn noch was unklar ist, fragt nach ich Antworte zeitnah ;)

Danke und schöne Grüße!

von Berater (Gast)


Lesenswert?

:-) schrieb:
> Digisiv
watt is datt denn für 'n Fach?

von Chris (Gast)


Lesenswert?

:-) schrieb:
> Die Abtastfrequenz sollte mehr als doppelt so hoch sein, wie die
> Grenzfrequenz/Signalfrequenz des Signals.

Du willst das Signal ja nicht mehr rekonstruieren daher musst du nicht 
mit der doppelten Frequez abtasten.

von russenbaer (Gast)


Lesenswert?

Chris schrieb:
> Du willst das Signal ja nicht mehr rekonstruieren daher musst du nicht
> mit der doppelten Frequez abtasten.

Das ist meines Erachtens ein Blödsinn, woher soll man dann wissen ob der 
Motor zwischen zwei Abtastpunkten 1,2 oder 100 Umdrehungen gemacht hat?

Du kannst mit Deinem Winkelgeber eine ganze Umdrehung auflösen 
(Genauigkeit = Anzahl der Schritte ist für diese Überlegung egal).
Damit Du nun JEDE Umdrehung in Deinen Messergebnissen siehst musst Du 
den Winkelgeber mindestens doppelt so häufig auslesen als der Motor 
maximal drehen kann (darf).
Das heißt mit einer Abtastrate von 100Hz (=Ausleserate aus dem Register) 
darf der Motor nur mit 50Hz (50 Umdrehungen pro Sekunde) laufen.
Die Abtastzeitpunkte müssen natürlich EXAKT 1/100s auseinander liegen.

Die Auflösung (Anzahl der Schritte für eine vollständige Umdrehung) ist 
egal für die Berechnung der Abtastrate. Die Auflösung der Winkel 
(=Anzahl der Schritte für eine Umdrehung) entspricht der Quantisierung 
Deines Eingangssignals und hat nichts mit dem Shannontheorem zu tun.
Selbst wenn Du nur mit z.B. 4 Schritten Deine Umdrehung auflöst, d.h. 
pro pi/2 einen Wert, musst Du mit einer Rate Abtasten die mindestens 
doppelt so hoch ist wie Deine maximale Umdrehungen/s.

Zitat:
> - Wie glätte ich am besten meine zackeligen Kurven ohne relevante
> Informationen zu verlieren?

Wie genau willst Du eigentlich die Geschwindigkeit Deines Motors messen? 
Gemittelt, sagen wir über eine (mehrere) vollständige Umdrehungen, oder 
instantan während einer Umdrehung?


Wie im anderen thread schon besprochen, Dein Filter v[n] = (x[n+1] - 
x[n]) *0.5 ist akausal. Da wirds schwierig mit einer Echtzeitregelung.
Für mein Verständis bedeutet die Formel auch folgendes: Wo ist der Motor 
in Zukunft, davon ziehe ich die Gegenwart ab und das ist (ich habe die 
Skalierungen 1/T usw. nun nicht notiert, da Du sowieso äquidistant 
(hoffentlich) abtastest und dieser Faktor nur eine Multiplikation mit 
einer Konstanten bedeuten würde) meine Gegenwärtige Geschwindigkeit.

Ich habe gelernt das die Momentangeschwindigkeit so berechnet wird:
Wo war das Objekt vorher, wo ist es jetzt -> "Ort jetzt - Ort 
vorher"/Zeit
bzw. wenn Du den einfachsten Differenziator verwenden willst v[n] = x[n] 
- x[n-1] .

Hast Du den Link durchgearbeitet aus dem anderen Thread?




lg
russenbaer

von :-) (Gast)


Lesenswert?

Hallo Russenbär.

Das ganze klingt soweit logisch und nachvollziehbar. Selbst wenn ich nur 
wenige Steps/Umdrehung hätte, müsste ich trotzdem mehr als doppelt so 
schnell abtasten, wie der Motor läuft.
Ich habe übrigens noch ein Register, das mir die Dreh- bzw Zählrichtung 
angibt, aber das nur am Rand.

Zu deiner Befürchtung: Die Abtastpunke sind äquidistant und der 
Interrupt des Timers hat eine hohe Priorität.

Der Motor hat eine Nenndrehzahl von 3000u/min @ 40V. Auf die 40V werden 
wir eher nicht kommen (der wird später per PWM geregelt), er soll eher 
Positionen genau anfahren können. Daher reicht eine Mittelung über z.B. 
eine oder eine halbe Umdrehung nicht, sondern die 
Geschwindigkeitsberechnung sollte in möglichst kurzen Zeitabständen 
erfolgen.

Es soll später zwei Betriebsmodi geben. Einmal Geschwindigkeiten 
"abfahren" (aus einer Tabelle zum Beispiel), oder Winkel anfahren (bei 
beiden Modi wird der Motor - wenn überhaupt 1 oder 2 Umdrehungen machen, 
mehr nicht. Aber in beide Richtungen).

Das Auslesen per Matlab ist jetzt erst einmal fürs Aufnehmen der 
Motorkennlinie und der Sprungantwort gedacht.


Ja den Artikel habe ich durchgelesen und denke auch verstanden. Der 
"normale" Vorwärtsdifferenzenquotient ist akausal, ja. Für Echtzeit eher 
blöd. Wie gesagt, der kam mir nur am "natürlichsten" vor. Hier die 
anderen Varianten: 
http://de.wikipedia.org/wiki/Differenzenquotient#Varianten

Ich habe die in deinem Link angegebene Variante mit dem schöneren 
Frequenzgang ausprobiert. Der erzeugt schon eine hübschere Kurve, aber 
sollte ich den auch in der Echtzeitregelung Verwenden? Gespeichert habe 
ich die Werte ja eh, denke das Berechnen dauert auch nicht so lang, aber 
ist das sinnvoll vom Physikalischen her?

Noch was: Falls aus irgendeinem Grund die Drehzahl des Motors doch mal 
höher als die angestrebten 50/s(kurzzeitig) sind, so bekomme ich 
Aliaseffekte. Dann wird unter Umständen eine falsche Geschwindigkeit 
angenommen. Sollte man daher das Signal vorher noch durch den Tiefpass 
jagen (wie z.B. in NT Grundsätzlich gemacht wurde), oder ist das in der 
Praxis (hier im uC) nicht erforderlich?

Vielleicht mache ich mir ja auch zu viele Gedanken, so eine blöde 
Motorsteuerung haben schon viele gebaut Google zufolge, solche Gedanken 
wurden sich da irgendwie nicht gemacht :D

Danke für eure Hilfe!

von :-) (Gast)


Lesenswert?

Ich muss mich leider korrigieren: Der Filter aus dem Artikel macht 
deutlich ausgefranstere Kurven, als der einfache diff Filter. Werde 
gleich mal ein Bild anhängen.

von :-) (Gast)


Lesenswert?

Und noch was: eigentlich gilt das Abtasttheorem ja nur für Sinusförmige 
Kurven. Bedeutet hier: Ich müsste eigentlich noch viel höher abtasten, 
wollte ich das eigentliche Signal rekonstruieren.

Das war nur nochmal eine kleine Korrektur meiner Gedanken oben ;)

von Harri (Gast)


Lesenswert?

:-) schrieb:
> Und noch was: eigentlich gilt das Abtasttheorem ja nur für Sinusförmige
>
> Kurven.
Es gibt für die höchste Frequenz in Deinem Sigal. Das ist der 
tiefrequenteste Sinus innhalb der Quadraturpulse also Fkator 2 x 
Frequenz.

Nach oben kann man das theoretisch bis unendlich fortsetzen, muss es 
aber nicht. Es reicht die 5. oberwelle, die eine guten Kompromiss 
darstellt, weil Du mit dem Sinus ohne eine Oberwelle die Phase 
schlechter messen kannst - wegen der Ungeaugikeiten.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.