Я использовал Arduino для записи некоторых данных. В моем наброске Arduino я также использовал millis()
функцию, чтобы я мог отслеживать время, в которое берется каждое измеряемое значение. Тем не менее, я заметил, что выбор времени не правильный. Например, 30 секунд в реальной жизни выходят как 10 секунд (выдуманный пример).
Правильно ли я сказал, что функция задержки Arduino влияет на время использования millis()
? Другими словами, предположим, что у меня задержка 50 мс. Означает ли это, что millis()
функция также останавливается на эту продолжительность, а затем продолжается и так далее на время соединения? Я заметил это, когда попытался построить некоторые данные и обнаружить, что частота пиков в моих данных была слишком частой, учитывая прошедшее время. Итак, я хочу знать, является ли это причиной такого несоответствия времени, и если да, то как я могу это исправить, чтобы я мог сохранить время каждого образца?
Чтобы дать некоторый контекст, вот мой набросок:
#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);
}
источник
millis()
управляется прерыванием, поэтомуdelay()
не должно влиять на него.Ответы:
millis()
управляется прерыванием, поэтомуdelay()
не будет влиять на него, по крайней мере, на плате на базе ATmega.Это не значит, что
millis()
это абсолютно точно. Каждый такт таймера не точно равен 1 мс, но равен 1,024 мс. Эта ошибка постепенно накапливается, пока не будет произведена коррекция. Это можно увидеть в реализации обработчика прерываний TIMER0_OVF (переполнение таймера 0).Другим источником неточностей является сам осциллятор / кристалл, который не совсем 16 МГц. Это довольно близко, хотя, и пока температура не меняется слишком сильно, она относительно стабильна.
Вышесказанное означает, что вы можете быть около 1 мс при использовании
millis()
. Это не похоже на твою проблему.Другой потенциальной проблемой может быть то, что
getECG()
происходит, - это может быть очень медленно.analogRead()
медленный, но не такой медленный, чтобы воздействовать на такую петлю.Еще одна проблема, с которой я сталкивался у людей, это когда они меняют тактовую частоту, но неправильно меняют board.txt. Это означает, что константы, используемые в
millis()
реализации, неправильные, а времена неправильные.Если вы действительно хотите читать значения каждые 50 мс, гораздо лучший способ реализовать это - сделать следующее
Нам действительно нужно увидеть метки времени, которые вы получаете. Если вы на самом деле видите 30-е годы, которые показывают как 10-е, значит, на работе есть что-то еще.
источник
Если прерывания отключаются в течение какой-либо значительной
eHealth.getECG()
длительности вызова,millis()
счет может отставать. В противном случаеmillis()
должно возвращаться гораздо более точное время, чем 3х ошибочные, которые вы описали.Вы сказали, что ваш сэмплированный сигнал имеет более высокую частоту, чем вы ожидали, что может произойти, если ваша частота сэмплирования ниже, чем вы предполагали. Вы предполагаете частоту дискретизации 20 Гц? Ваш цикл может занимать чуть больше 50 мс, что вы увидите в распечатанном времени, но оно все равно должно отслеживать время. Если вы не учли это, но предположили 50 мс / сэмпл, вы бы увидели очевидное ускорение данных.
Если это не проблема, то следующим шагом будет переключение выхода, когда вы находитесь
loop()
, и измерение частоты результирующей прямоугольной волны с помощью измерителя частоты (некоторые недорогие DVM могут сделать это) или «область действия». Сделайте то же самое с пустымloop()
. Первый эксперимент будет вашей реальной частотой дискретизации или интервалом; вторая скажет вам, является лиmillis()
(то есть, частота таймера 0) тем, что вы ожидали.источник
Тоже самое. Я могу добавить, что если прерывания отключены, измеренное время является «реальным временем». Во всяком случае, я не понимаю, почему эта задержка, потому что если цикл занимает слишком много времени, в любом случае millis () должен возвращать значения в реальном времени (только с большим расстоянием между каждым значением)
источник