J'utilise l'Arduino pour enregistrer certaines données. Dans mon croquis Arduino, j'ai également utilisé la millis()
fonction afin que je puisse garder une trace de l'heure à laquelle chaque valeur que je mesure est prise. Cependant, j'ai remarqué que le timing n'est pas correct. Par exemple, 30 secondes dans la vraie vie ne sortent que comme 10 secondes (exemple composé).
Ai-je raison de dire que la fonction de retard Arduino affecte la durée d'utilisation millis()
? En d'autres termes, supposons que j'ai un retard de 50 ms, cela signifie-t-il que la millis()
fonction s'arrête également pendant cette durée, puis continue et ainsi de suite pendant la durée de la connexion? Je l'ai remarqué lorsque j'ai essayé de tracer certaines données et de constater que la fréquence des pics dans mes données était trop fréquente compte tenu du temps qui s'était écoulé. Donc, je veux savoir si c'est le raisonnement pour cette inadéquation du timing et si oui, comment puis-je résoudre ce problème afin que je puisse garder l'heure à laquelle chaque échantillon se produit?
Pour donner un peu de contexte, voici mon croquis:
#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);
}
la source
millis()
est piloté par interruption,delay()
il ne devrait donc pas l'affecter.Réponses:
millis()
est piloté par interruption, donc ildelay()
n'aura pas d'impact, du moins pas sur une carte basée sur ATmega.Cela ne veut pas dire que
millis()
c'est tout à fait exact non plus. Chaque tick de la minuterie n'est pas exactement de 1 ms, mais est de 1,024 ms. Cette erreur s'accumule progressivement jusqu'à ce qu'une correction soit effectuée. Cela peut être vu dans l'implémentation du gestionnaire d'interruption TIMER0_OVF (timer 0 overflow).Une autre source d'inexactitude est l'oscillateur / cristal lui-même, qui n'est pas exactement 16 MHz. Il est assez proche cependant, et tant que la température ne change pas trop, il est relativement stable.
Ce qui précède signifie que vous pourriez être à environ 1 ms pendant l'utilisation
millis()
. Cela ne ressemble pas à votre problème.Un autre problème potentiel serait ce qui
getECG()
se passe - cela pourrait être très lent.analogRead()
est lent, mais pas assez lent pour avoir un impact sur une boucle comme celle-ci.Un autre problème que j'ai vu est que les gens changent la vitesse d'horloge mais ne changent pas correctement boards.txt. Cela signifie que les constantes utilisées dans l'
millis()
implémentation sont incorrectes et que les temps sont incorrects.Si vous voulez réellement lire les valeurs toutes les 50 ms, une bien meilleure façon de l'implémenter est de faire ce qui suit
Nous aurions vraiment besoin de voir les horodatages que vous obtenez. Si vous voyez réellement 30s afficher comme 10s, alors il y a autre chose au travail.
la source
Si les interruptions sont désactivées pour une
eHealth.getECG()
durée d'appel fractionnelle importante ,millis()
le nombre de 'pourrait prendre du retard. Sinon, celamillis()
devrait renvoyer un temps beaucoup plus précis que les erreurs 3x que vous avez décrites.Vous avez dit que votre signal échantillonné apparaît en fréquence plus élevée que ce à quoi vous vous attendiez, ce qui pourrait se produire si votre fréquence d'échantillonnage est inférieure à ce que vous vouliez. Vous supposez une fréquence d'échantillonnage de 20 Hz? Votre boucle pourrait prendre un peu plus de 50 ms, ce que vous verriez dans les temps imprimés, mais ceux-ci devraient toujours suivre l'heure de l'horloge. Si vous ne teniez pas compte de cela mais supposiez 50 ms / échantillon, vous verriez une accélération apparente des données.
Si ce n'est pas le problème, alors la prochaine étape serait de basculer une sortie pendant que vous êtes
loop()
dedans, et de mesurer la fréquence de l'onde carrée résultante avec un fréquencemètre (certains DVM peu coûteux peuvent le faire) ou une 'portée'. Faites la même chose avec un videloop()
. La première expérience sera votre taux ou intervalle d'échantillonnage réel; la seconde vous dira simillis()
(c.-à-d. la fréquence du timer0) est ce que vous attendiez.la source
Pareil ici. Je peux ajouter que si les interruptions sont désactivées, le temps mesuré est "temps réel". Quoi qu'il en soit, je ne comprends pas pourquoi ce retard, car si la boucle prend trop de temps, de toute façon les millis () devraient retourner des valeurs en temps réel (seulement avec plus de distance entre chaque valeur)
la source