Saya telah menggunakan Arduino untuk merekam beberapa data. Dalam sketsa Arduino saya, saya juga menggunakan millis()
fungsi tersebut sehingga saya dapat melacak waktu di mana setiap nilai yang saya ukur diambil. Namun, saya perhatikan waktunya tidak tepat. Misalnya 30 detik dalam kehidupan nyata hanya keluar sebagai 10 detik (contoh dibuat-buat).
Apakah saya benar mengatakan bahwa fungsi penundaan Arduino memengaruhi penggunaan waktu millis()
? Dengan kata lain seandainya saya memiliki keterlambatan 50 ms, apakah itu berarti millis()
fungsi berhenti untuk durasi itu juga dan kemudian berlanjut dan seterusnya selama durasi koneksi? Saya perhatikan ini ketika saya mencoba merencanakan beberapa data dan menemukan bahwa frekuensi puncak dalam data saya terlalu sering mengingat waktu yang telah berlalu. Jadi saya ingin tahu apakah itu alasan ketidakcocokan waktu ini dan jika demikian, bagaimana cara memperbaikinya sehingga saya dapat menjaga waktu setiap sampel terjadi?
Untuk memberikan beberapa konteks di sini adalah sketsa saya:
#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);
}
sumber
millis()
adalah interrupt driven, jadidelay()
seharusnya tidak mempengaruhinya.Jawaban:
millis()
didorong interupsi sehinggadelay()
tidak akan berdampak, setidaknya tidak pada papan berbasis ATmega.Itu tidak berarti itu
millis()
juga benar-benar akurat. Setiap centang timer tidak tepat 1 ms, tetapi 1.024 ms. Kesalahan ini berakumulasi secara bertahap sampai koreksi dilakukan. Ini dapat dilihat dalam implementasi dari interrupt handler TIMER0_OVF (timer 0).Sumber ketidakakuratan lain adalah osilator / kristal itu sendiri, yang tidak persis 16MHz. Itu cukup dekat, dan selama suhu tidak berubah terlalu banyak, relatif stabil.
Di atas berarti bahwa Anda mungkin keluar sekitar 1 ms saat menggunakan
millis()
. Ini tidak terdengar seperti masalah Anda.Masalah potensial lainnya
getECG()
adalah apa yang sedang dilakukan - mungkin sangat lambat.analogRead()
lambat, tetapi tidak terlalu lambat untuk memengaruhi loop seperti ini.Masalah lain yang saya lihat orang miliki adalah ketika mereka mengubah kecepatan jam tetapi tidak dengan benar mengubah boards.txt. Ini berarti bahwa konstanta yang digunakan dalam
millis()
implementasi salah dan waktunya salah.Jika Anda benar-benar ingin membaca nilai setiap 50 ms, cara yang lebih baik untuk mengimplementasikan ini adalah dengan melakukan hal berikut
Kami benar-benar perlu melihat cap waktu yang Anda dapatkan. Jika Anda benar-benar melihat 30-an ditampilkan sebagai 10-an, maka ada sesuatu yang lain sedang bekerja.
sumber
Jika interupsi dimatikan untuk
eHealth.getECG()
durasi panggilan fraksi yang signifikan ,millis()
hitungan bisa tertinggal. Kalau tidak,millis()
seharusnya mengembalikan waktu yang jauh lebih akurat daripada kesalahan 3x yang Anda gambarkan.Anda mengatakan sinyal sampel Anda muncul dalam frekuensi yang lebih tinggi daripada yang Anda harapkan, yang bisa terjadi jika laju sampel Anda lebih rendah dari yang Anda inginkan. Apakah Anda mengasumsikan laju sampel 20Hz? Perulangan Anda mungkin memakan waktu agak lebih lama dari 50 ms, yang akan Anda lihat pada waktu dicetak, tetapi itu masih harus melacak waktu jam. Jika Anda tidak memperhitungkannya tetapi mengasumsikan 50 ms / sampel, Anda akan melihat kecepatan jelas dari data.
Jika ini bukan masalahnya, maka langkah selanjutnya adalah beralih output ketika Anda berada di
loop()
, dan mengukur frekuensi gelombang persegi yang dihasilkan dengan pengukur frekuensi (beberapa DVM murah dapat melakukan ini) atau cakupan. Lakukan hal yang sama dengan yang kosongloop()
. Eksperimen pertama adalah laju atau interval sampling nyata Anda; yang kedua akan memberi tahu Anda apakahmillis()
(mis., frekuensi timer0) adalah yang Anda harapkan.sumber
Sama disini. Saya dapat menambahkan bahwa jika gangguan dimatikan, waktu yang diukur adalah "waktu nyata". Lagi pula, saya tidak mengerti mengapa penundaan ini, karena jika loop terlalu lama, bagaimanapun juga millis () harus mengembalikan nilai waktu nyata (hanya dengan jarak yang lebih jauh antara setiap nilai)
sumber