Guten Morgen,
anknüpfend an meinen letzten Thread:
Beitrag "Zeitmessung in µC oder im PC" brauche ich immer noch
eure Hilfe.
Ich habe zwar das Problem mit der unregelmäßigen Zeit zwischen den
Messungen gelöst, jedoch habe ich festgestellt, dass ich ja nur jede 5.
Messung erfasse.
Hier mal die relevanten Code-Ausschnitte:
Aufgrund der AD-Wandlung im Sensor ergibt sich eine Update-Zeit der
Messwerte von 417µs, also 0,42ms (laut Datenblatt BMA180). Es werden XYZ
und der Temperaturwert in diesen 0,42ms aktualisiert.
Wenn ich jetzt das Programm so in Hterm teste, bekomme ich eine Zeit von
2,08ms zwischen den Messungen.
Lösche ich ein %d aus der printf-Übertragung, dann komme ich auf 1,67ms.
Lösche ich ein weiteres %d, komme ich auf 1,25ms. Lasse ich nur noch das
%u für die Zeit stehen, dann bekomme ich 0,83ms.
Das sind alles Vielfache der Update-Zeit. Mir kommts so vor, als wenn
ich mir aus jeder Update-Sequenz (Aktualisierung der 4 Werte) immer nur
einen Wert rauspicke, z.B. X, und ich für den nächsten Wert Y wieder
eine Update-Sequenz brauche. Das würde aber heißen das meine
X-,Y-,Z-Werte gar nicht zueinander passen, sondern immer zu dem
jeweiligen nächsten Update.
Liegt das Problem an der printf-Übertragung? Falls es an der "zu
langsamen" Übertragung liegt, könnte ich mir eine Art Ringpuffer
anlegen, der mir die Werte von 5 Update-Sequenzen zwischenspeichert und
ich diese dann auf einmal übertrage?
Könnt ihr mir weiterhelfen?? Ich hoffe, dass war jetzt nicht zu viel
Text.
Danke.
Gruß Martin R.
Ergänzend muss ich noch dazu schreiben, dass das Input Capture Interrupt
durch den Sensor ausgelöst wird, und zwar nur dann wenn ein neues Update
verfügbar ist, also wenn alle 4 Messwerte wieder aktuell zum auslesen
bereit stehen.. (INT erfolgt alle 417µs)
@Willi:
Hm...nach deiner Antwort, vermute ich, dass es unnötig ist. Sollte ich
besser schreiben:
1
ZeitstempelNeu=ICR1
Ich wollte in den beiden Variablen halt erst mal die ICR1 Register
sichern.
Das sollte doch aber nicht die Lösung für mein Problem sein, oder?
Gruß Martin
Zusammenfassend sagt das ja nur aus, dass printf() sehr langsam ist,
oder? Dem kann ich nicht widersprechen. Deswegen ersetze ich es meistens
durch andere Funktionen bzw. eigene Routinen. Das würde sicher auch in
diesem Fall einen Geschwindigkeitsvorteil bringen.
Bei solch zeitkritischen Berechnungen hilft wahrscheinlich zusätzlich
ein Umstieg auf Assembler.
Bei 115kBd dauert die Übertragung eines Zeichens ca. 0,1 ms.
Damit kannst Du abschätzen, wie schnell die Ausgabe überhaupt sein kann.
Printf() an sich muß nicht langsam sein, aber die ser. Ausgabe bremst
auf jeden Fall.
Eine Ausgabe mit FIFO (Ringpuffer mit 32 byte) per UART-Interrupt
beschleunigt insofern, dass printf() nicht warten muß und beide Abläufe
parallel passieren können.
Hm um auf Assembler umzusteigen habe ich nicht genügend Zeit. Das
kuriose ist ja, dass der Sensor für die AD-Wandlung 417µs braucht. Nach
den 417µs brauche ich 0,42ms für die Übertragung des Zeitwertes. Danach
wieder rund 0,42ms für den ersten Messwert und dann wieder 0,42ms und so
weiter bis alle 4 Werte übertragen wurden.
Mich wundert ja nicht, dass es so lange dauert, sondern das es Vielfache
dieser 417µs sind.
Mit Matlab habe ich die Daten dargestellt und bekomme auch logische
Kennlinien, wenn ich das Zeitintervall = 1,67ms setze.
Dadurch das ich den Zeitwert mit übertrage komme ich auf 2,08ms.
Meine Idee ist nun,
1.
...dass ich den Zeitwert einfach nicht mitübertrage. Dann komme ich auf
1,67ms. Habe jedoch keine Kontrolle mehr über die wirkliche Zeit.
2.
...oder ich übertrage den Zeitwert und ziehe danach in Matlab 0,42ms von
diesem ab.
Das ist dann aber bestimmt nicht die eleganteste Art.
Habe gehofft, dass jemand ein ähnliches Problem hatte.
Gruß Martin
Ok danke Willi für deine Zeitangabe. Das würde ich ungefähr hinkommen.
Meine Werte sehen z.B. so aus:
X Y Z Time
-23 134 5534 20755
D.h. die Anzahl der Zeichen ist unterschiedlich, aber angenommen es sind
5 Zeichen, dann wären es nach deiner Angabe ca. 0,5ms und das deckt sich
ja in etwa mit meinen Erkenntnissen.
Ist es vielleicht nur Zufall, dass die Zeiten Vielfache von der
Update-Zeit des Sensors sind?
Martin schrieb:> Ist es vielleicht nur Zufall, dass die Zeiten Vielfache von der> Update-Zeit des Sensors sind?
Wenn ich es richtig verstanden habe, synchronisiert doch der Sensor (ich
kenne ihn nicht) Deine Messung. Folglich muß die Ausgabe im 417µs-Raster
erfolgen.
Willi schrieb:> Martin schrieb:>> Ist es vielleicht nur Zufall, dass die Zeiten Vielfache von der>> Update-Zeit des Sensors sind?>> Wenn ich es richtig verstanden habe, synchronisiert doch der Sensor (ich> kenne ihn nicht) Deine Messung. Folglich muß die Ausgabe im 417µs-Raster> erfolgen.
Die verwendeten Libraries sperren aber alle Interrupts aus, so lange bis
sie ihrer Ansicht nach fertig sind. Erst dann wird der global Interrupt
wieder aktiviert. Daraus erklärt sich auch das Vielfache von besagten
417µs, da erst nach dieser Zeitspanne wieder ein Sync initiiert wird.
Lehrmann Michael schrieb:> Die verwendeten Libraries sperren aber alle Interrupts aus, so lange bis> sie ihrer Ansicht nach fertig sind.
Dann schmeiß die Libs weg!
Hm..
@Willi: Der Sensor ist ein 3 Achsen Beschleunigungssensor Bosch BMA180.
Und du hast Recht damit, dass er nur in dem 417µs-Raster einen Wert
bringen kann. Und liegt die Messung dazwischen, dann wird auf das
nächste Vielfache gewartet:-( Also kann ich doch so gar nicht genauer
messen, als in diesen 417µs-Schritten? Oder?
@Michael: Wenn ich die Libraries rausnehme und die Übertragung anders
realisiere, werden zwar die Interrupts zugelassen, aber ich kann die
Messwerte, die während der Übertragung eintrudeln doch dann nicht
parallel speichern?
Mein Timer gibt einen Wert von 2,08ms aus, also ignoriere ich ja drei
Messungen, weil die Interrupts während der Übertragung deaktiviert
werden:-(
Muss ich mal überlegen ob ich das auch anders hinkriege.