Hallo Leute!
Die Situation:
Ich habe hier einen Absolutwert- Drehwinkelgeber(MLX90316) der mir via
SPI(Ü-Rate 142kBit/s) ca. alle 5ms einen 14 Bit Winkelwerte liefert. Der
erregende Magnet sitzt auf einer Motorwelle. Ich möchte aus den
Winkeldaten zusätzlich die momentane Drehzahl berechnen (max. 2000
U/min). Der Controller ist ein M16C(16MHz). Mein Ansatz ist folgender:
Ich messe die genaue Zeit die eine Winkelmessung benötigt, bestimme die
Änderung des Winkels in diesem Intervall und berechne:
(delta_omega/(delta_t*360))*60 = Drehzahl. Richtig oder Falsch???
Mein Problem: Ich habe grosse Schwankungen bei der Berechnung der
Winkeldifferenz. Ich schreibe jeden Winkelwert in einen
Ringpuffer(array[0..3]) und subtrahiere immer den letzten vom aktuellen
Wert.
Das müsste doch eigentlich funktionieren, oder?
Allerdings bin ich auch kein so toller programmierer und wäre froh wenn
mir da jemand tips geben kann!
Vielen Dank
Svente wrote:
> Allerdings bin ich auch kein so toller programmierer und wäre froh wenn> mir da jemand tips geben kann!
Der beste Tip ist immer noch:
Wenn du denkst, dass du möglicherweise Fehler in dein Programm
eingebaut hast, dann ist es ratsam, das Programm herzuzeigen.
Ansonsten müssen wir raten, und das willst du ganz sicher nicht
wenn du die drehzahl berechnen willst, dann könntest du auch immer nach
einer umdrehung, die zeit messen, die vergangen ist, um die drehzahl zu
errechnen...
immer wenn 0 grad überschritten wird - zeit nehmen... usw...
d.
Deine Berechnung stimmt soweit, obwohl deine Namensgebung wahrscheinlich
unglücklich ist: d_omega -> d_phi. Aber das nur als akademische
Spitzfindigkeit ;) . Dein Geber gibt doch bestimmt einen Winkelwert in
Grad, oder? In welcher Auflösung? Was meinst du mit Subtraktion vom
vorherigen Wert; nimmst du am Anfang eine Startmessung und nach delta_t
eine Endmessung vor um daraus per_Subtraktion ein delta_phi zu
erhalten? Wenn ja: gut, aber dort können sich Fehlerchen einschleichen
die vor allem bei kurzen delta_t zu ordentlichen Fehlern führen können.
Poste doch mal Code oder Pseudocode.
pumpkin
Nimm lieber ein Intervall von z.B. 1 Sekunde und miss wieviel
Umdrehungen du da machst.
Also zu Beginn der Sekunde den Encoder auslesen, dann zählen wie oft der
Wert übersprungen wurde (sind die ganzen Umdrehungen).
Zum Ende der Sekunde Encoder nochmal auslesen, Wert vom Anfangswert
subtrahieren, dass ist dann ein Bruchteil einer Umdrehung.
Du erhältst dann direkt ein Ergebnis von z.B. 7,42 U/s (*60 = Upm)
OK.
Und welche Werte (nenn doch mal ein paar Beispiele)
verursachen jetzt dein Problem.
Was ich im Code so gesehen habe (Ich sags gleich:
mit dem M16C hab ich nichts am Hut)
Mittels
ta2s = 0x
startest du anscheinend den Timer.
Die vielen Waits da drinnen schmecken mir nicht besonders.
Sind wohl dazu da um das SPI Timing einzuhalten. Aber:
Hier
delta_t = us_counter - t_old; //us_counter = aktueller Stand des
Mikrosekundenzählers
greifst du anscheined das nächste mal auf den Timer zu.
Nur: Was hast du eigentlich gemessen?
Was du gemessen hast, ist die Zeitdauer, die vergeht bis der
Code von ta2s=0 bis zum Abfragen des Timers kommt. Die ist
aber reichlich ungenau. Da sind einige ifs drinnen, etc.
D.h. deine Aussage: "Ich messe die genaue Zeit die eine
Winkelmessung benötigt" mit der Betonung auf 'genaue' nehm ich
dir so nicht ab.
temp1 = delta_t*0.00001; //zeit in sekunden
temp2 = winkeldif*0.02197;
temp = (temp2/(temp1*360))*60;
Diese ganzen floating Point Berechnungen (hast du echte double
oder so wie beim gcc nur float zur Verfügung), sind problematisch.
Versuche ohne floating point auszukommen.
(hmmm wird hier in LateX \Rightarrow nicht unterstützt?)
pseudo:
werte auslesen,
mit alten werten delta werte bestimmen,
f berechnen,
ausgelesene werte als alte abspeichern....
bei dem fall, wie oben schon erwähnt, können schwankungen bei f
auftreten, da
lieber timer_overflow_interrupt oder CTC, falls der µC das unterstützt,
noch besser, du speicherst die ausgelesenen werte über
einen bestimmten Zeitraum und mittelst diese,...
grüüüüüße da kai
________________________________>Das war ein sinnfreier Beitrag :D
Hallo
Der Sensor liefert den absoluten Winkel bezogen auf einen Fixpunkt und
nicht die Winkelgeschwindigkeit.
Das 1. Problem das dich darauf ergibt ist, das du nicht weißt in welche
Richtung die Achse gedreht wurde.
zb: Wert 1 : 50° Wert 2 : 150°
mögliche Winkeländerung sind
0° ; 50° ; 150° ; 180° ; .... = delta (+)100°
50° ; 0° ; 270°; 180°; 150°;...... = delta (-)260°
Welche der beiden Richtungen ein + oder - bekommt hängt alleine davon
ab, wie du dein Koordinatensystem legen willst.
Die Winkeldifferenz also wie weit hat sich die Achse zwischen 2
Meßwerten gedreht ist eine Subtraktion , Meßwert [n] - Meßwert [n-1].
Das 2. Problem ist wie oft hat sich die Achse gedreht, das heißt X *
360° . Es könnten ja auch mehrere Umdrehungen sein.
Nach Datenblatt wird der Winkel je nach Konfiguration alle 1,5ms oder
alle 350 µs von Sensor gemessen. Der letzte gemessene Wert wird
festgehalten und bei Anforderung von SPI Master gesendet.
Wenn du jetzt alle 5 ms Daten von Sensor anforderst, folgt daraus das
der Zeitabstand zwischen 2 Messungen 3,5 bis 5 ms, bzw 4,65 bis 5 ms
betragen kann.
Die Zeit die du messen kannst ist von Beginn einer Datenaforderung bis
zum Beginn der nächsten Anforderung. Den Zeitabstand zwischen 2
Messungen kannst du nicht messen. Das könnte dir nur der Sensor sagen.
Also deine Berechnug muss lauten :
Winkelgeschwindigkeit = (Meßwert [n] - Meßwert [n-1])
----------------------------------------------------
(Anforderungszeitpunkt [n] -
Anforderungszeitpunkt [n-1])
Winkelgeschwindigkeit in [°/ms] umrechnen in [n/min]
Desweiteren solltest du die Winkelgschwindigkeiten filtern, zb ein
Mittelwertfilter über die letzten n Meßwerte. Und erst diesen
gefilterten Wert in die Drehzahl umrechnen.
Hi Leute!
Viele Dank mal für die Beiträge! Ich werde das jetzt mal durcharbeiten.
Zu der Bemerkung von dem Michael: Ich habe die 13us Delay´s aus meinem
Data- Frame rausgenommen. Ergebnis: Ich bekomme ne Menge Peaks pro
Umdrehung. Also, wenn mann sich die Messwerte in einer Exelgrafik
anschaut, dann bekommt man quasi einen Sägezahn der ohne die 13us viele
fiese Peaks hat! Ich denke schon , daß der Sensor diese "Inter-Byte-
Zeit" braucht!
Ich mach mich mal an die Arbeit...