Saya menggunakan Arduino Uno untuk mengirim informasi waktu dan tegangan melalui port serial ke Python untuk plot. Namun, interval waktu antara stempel waktu berturut-turut tampaknya meningkat dari waktu ke waktu, memengaruhi plot saya. Ini terutama benar ketika baud rate diatur ke 9600, di mana perbedaan waktu awal saya mungkin 1320 dan meningkat menjadi 16400 setelah periode waktu yang relatif singkat. Ketika laju ini mencapai maksimum 115200 bps, perubahannya lebih lambat dan kurang terlihat, dari sekitar 1340 hingga 1500 bahkan setelah jangka waktu pengiriman yang relatif lama. Semua waktu diberikan dalam mikrodetik.
Saya ingin tahu apakah saya dapat mengurangi atau menghilangkan efek ini, dan jika tidak mengerti mengapa itu ada. Saya telah membaca hal-hal tentang gangguan dan keterlambatan yang menyebabkan hal ini, tetapi saya tidak sepenuhnya menghargai kompleksitas elektronik yang ada dan ingin tahu:
- Bisakah saya mendapatkan ketepatan waktu yang lebih besar?
- Apa yang menyebabkan perubahan waktu ini?
Inilah yang saat ini saya miliki:
#include <eHealth.h>
extern volatile unsigned long timer0_overflow_count;
float fanalog0;
int analog0;
unsigned long time;
byte serialByte;
void setup() {
Serial.begin(9600);
}
void loop() {
while (Serial.available()>0){
serialByte=Serial.read();
if (serialByte=='S'){
while(1){
fanalog0=eHealth.getECG();
// Use the timer0 => 1 tick every 4 us
time=(timer0_overflow_count << 8) + TCNT0;
// Microseconds conversion.
time=(time*4);
//Print in a file for simulation
//Serial.print(time);
//Serial.print(" ");
Serial.print(fanalog0,5);
Serial.print("\n");
if (Serial.available()>0){
serialByte=Serial.read();
if (serialByte=='F') break;
}
}
}
}
}
sumber
eHealth.getECG()
harus dilakukan Apakah panggilan itu selalu berlangsung dalam jumlah waktu yang sama?Jawaban:
Gunakan timer dan ISR (interupsi servis rutin) untuk membuat timing menjadi lebih akurat.
Lihatlah Bukti Konsep Konsep interrupt 1ms saya . Idenya adalah untuk memiliki detak jantung 1ms yang cukup akurat dalam sistem yang dapat digunakan untuk memicu peristiwa lain. Dalam PoC digunakan untuk berkedip LED pada ½Hz, tetapi memiliki akses ke variabel baru
millisecondCounter
dansecondCounter
memungkinkan Anda untuk memicu peristiwa dalam loop utama pada saat-saat yang sewenang-wenang (tetapi waktunya akurat).sumber
loop()
), nilai ini sedang dimodifikasi oleh ISR. Itu bisa terjadi yangloop()
membaca nilai buruk (di tengah modifikasi oleh ISR). Saya telah memposting komentar di blog Anda tentang itu.loop()
: sampel saya baru saja mendapatkan nilai milidetik, bandingkan dengan nilai baca sebelumnya dan jika perbedaan> 0 (selain reset counter ke 0), tampilkan pesan.Saya dapat memikirkan beberapa hal yang dapat mempengaruhi "konsistensi" dari waktu penulisan serial:
ini mungkin hal yang paling jelas untuk dipikirkan, tetapi memang semakin banyak Anda mencetak, semakin banyak yang diperlukan untuk menanganinya.
Solusi: cetak format string menjadi string yang dikenal panjang.
pada unix Anda dapat mengakses port serial menggunakan cara buffered atau unbuffered. Menggunakan cara buffered untuk waktu yang lama mungkin membuatnya sedikit lebih lambat karena buffer mengisi, biasanya itu terjadi ketika data masuk lebih cepat daripada Anda membacanya ...
Solusi: gunakan baris serial yang tidak disadap ( misalnya : di Darwin / OSX itu
/dev/cu.usbmodemXXX
bukan/dev/tty.usbmodemXXX
)sepertinya Anda menggunakan interupsi TC, dan AVR memiliki prioritas dalam cara interupsi ditangani, saya tidak tahu urutan prioritas untuk Atmega328, dan itu bukan salah satu fitur yang paling banyak didokumentasikan, jadi saya tidak tahu seberapa aman TC0 versus interupsi UART.
Solusi: lihat lebih lanjut dalam dokumentasi / lembar data tentang prioritas interupsi dan ubah timer jika diperlukan; dan / atau melakukan tes tanpa menjalankan timer lainnya.
beberapa driver perlu rata-rata atau melakukan beberapa operasi di atas nilai sebelumnya, sehingga semakin banyak nilai yang Anda ukur, semakin lama buffernya, dan semakin lama waktu yang dibutuhkan untuk menghitung nilai, hingga Anda telah mencapai ukuran maksimum buffer.
Solusi: lihat kode sumber perpustakaan yang Anda gunakan, dan optimalkan, hapus kalkulasi jika ada atau pertimbangkan waktu pemrosesan yang semakin tinggi.
tetapi jika Anda benar - benar ingin mengoptimalkan output serial dari Arduino, Anda harus menghindari menggunakan overhead Arduino ... Tapi itu cara yang kurang elegan dan nyaman untuk digunakan.
Saya cukup yakin ada hal-hal lain yang saya lewatkan, tetapi itu adalah hal pertama yang akan saya periksa sebelum menggali lebih jauh.
HTH
sumber
Kode Anda termasuk durasi output dalam pengukuran selanjutnya. Jadi tergantung pada panjang output Anda akan mengukur waktu yang berbeda. Ini dapat diperbaiki dengan memformat ke output panjang tetap.
Masalah berikutnya adalah bahwa UNO memiliki timebase yang sangat buruk. Lihat di sini untuk perbandingan berbagai jenis Arduino vs referensi waktu DCF77.
Kesimpulan: jika Anda membutuhkan pengaturan waktu yang tepat, dapatkan Arduino dengan kristal atau gunakan RTC. Saya sangat merekomendasikan DS3231 / DS3232 RTC karena biasanya ini mencapai akurasi 2 ppm.
sumber