Ich habe das Arduino verwendet, um einige Daten aufzuzeichnen. In meiner Arduino-Skizze habe ich auch die millis()
Funktion verwendet, um den Zeitpunkt zu verfolgen, zu dem jeder von mir gemessene Wert gemessen wird. Mir ist jedoch aufgefallen, dass das Timing nicht korrekt ist. Zum Beispiel werden 30 Sekunden im wirklichen Leben nur als 10 Sekunden ausgegeben (erfundenes Beispiel).
Habe ich Recht, wenn ich sage, dass die Arduino-Verzögerungsfunktion die Zeiteinsparung beeinflusst millis()
? Mit anderen Worten, ich habe eine Verzögerung von 50 ms. Bedeutet das, dass die millis()
Funktion auch für diese Dauer stoppt und dann für die Dauer der Verbindung fortgesetzt wird? Ich bemerkte dies, als ich versuchte, einige Daten zu zeichnen und feststellte, dass die Häufigkeit der Peaks in meinen Daten angesichts der verstrichenen Zeit zu häufig war. Ich möchte also wissen, ob dies der Grund für diese Nichtübereinstimmung des Timings ist, und wenn ja, wie kann ich dies beheben, damit ich die Zeit behalten kann, zu der jede Probe auftritt?
Um hier einen Kontext zu geben, ist meine Skizze:
#include <eHealth.h>
unsigned long time;
// The setup routine runs once when you press reset:
void setup() {
Serial.begin(9600);
}
// The loop routine runs over and over again forever:
void loop() {
float ECG = eHealth.getECG();
time = millis();
Serial.print(time);
Serial.print(" ");
Serial.print(ECG, 5);
Serial.println("");
delay(50);
}
quelle
millis()
ist Interrupt-gesteuert,delay()
sollte sich also nicht darauf auswirken.Antworten:
millis()
ist Interrupt-gesteuert, hat alsodelay()
keine Auswirkungen, zumindest nicht auf einem ATmega-basierten Board.Das heißt nicht, dass
millis()
das auch völlig richtig ist. Jeder Tick des Timers ist nicht genau 1 ms, sondern 1,024 ms. Dieser Fehler sammelt sich allmählich an, bis eine Korrektur vorgenommen wird. Dies ist in der Implementierung des Interrupt-Handlers TIMER0_OVF (Timer 0 Overflow) zu sehen.Eine weitere Ursache für Ungenauigkeiten ist der Oszillator / Kristall selbst, der nicht genau 16 MHz beträgt. Es ist jedoch ziemlich nahe und solange die Temperatur nicht zu stark ändert, ist es relativ stabil.
Das oben Gesagte bedeutet, dass Sie bei der Verwendung möglicherweise etwa 1 ms entfernt sind
millis()
. Das klingt nicht nach Ihrem Problem.Ein weiteres potenzielles Problem wäre, was
getECG()
getan wird - es könnte sehr langsam sein.analogRead()
ist langsam, aber nicht so langsam, dass eine solche Schleife beeinflusst wird.Ein weiteres Problem, das ich gesehen habe, ist, wenn Leute die Taktrate ändern, aber board.txt nicht richtig ändern. Dies bedeutet, dass die in der
millis()
Implementierung verwendeten Konstanten falsch und die Zeiten falsch sind.Wenn Sie tatsächlich alle 50 ms Werte lesen möchten, können Sie dies viel besser implementieren, indem Sie die folgenden Schritte ausführen
Wir müssten wirklich die Zeitstempel sehen, die Sie erhalten. Wenn Sie tatsächlich 30er als 10er sehen, ist noch etwas anderes am Werk.
quelle
Wenn Interrupts für eine signifikante Bruchdauer des
eHealth.getECG()
Anrufs deaktiviert werden, kannmillis()
die Anzahl zurückfallen. Andernfallsmillis()
sollte die Zeit viel genauer zurückgegeben werden als die von Ihnen beschriebenen 3x-Fehler.Sie sagten, dass Ihr abgetastetes Signal eine höhere Frequenz aufweist als erwartet. Dies kann passieren, wenn Ihre Abtastrate niedriger ist als beabsichtigt. Gehen Sie von einer Abtastrate von 20 Hz aus? Ihre Schleife könnte etwas länger als 50 ms dauern, was Sie in den gedruckten Zeiten sehen würden, aber diese sollten immer noch die Uhrzeit verfolgen. Wenn Sie dies nicht berücksichtigen, aber 50 ms / Probe annehmen, sehen Sie eine offensichtliche Beschleunigung der Daten.
Wenn dies nicht der Fall ist, besteht der nächste Schritt darin, einen Ausgang
loop()
umzuschalten, während Sie sich gerade befinden , und die Frequenz der resultierenden Rechteckwelle mit einem Frequenzmesser (einige kostengünstige DVMs können dies tun) oder einem Oszilloskop zu messen. Mach dasselbe mit einem leerenloop()
. Das erste Experiment wird Ihre tatsächliche Abtastrate oder Ihr Intervall bestimmen. Die zweite zeigt Ihnen, obmillis()
(dh die Timer0-Frequenz) Ihren Erwartungen entspricht.quelle
Hier gilt das gleiche. Ich kann hinzufügen, dass bei ausgeschalteten Unterbrechungen die gemessene Zeit "Echtzeit" ist. Wie auch immer, ich verstehe nicht, warum diese Verzögerung, denn wenn die Schleife zu lange dauert, sollte millis () sowieso Echtzeitwerte zurückgeben (nur mit mehr Abstand zwischen jedem Wert)
quelle