Wednesday 9 August 2017

Pindah rata filter mikrokontroler


Salah satu aplikasi utama papan Arduino adalah membaca dan mencatat data sensor. Misalnya seseorang memantau tekanan setiap detiknya setiap hari. Karena tingkat sampel yang tinggi sering menghasilkan lonjakan pada grafik, seseorang juga ingin memiliki rata-rata pengukuran. Karena pengukurannya tidak statis dalam waktu yang sering kita perlukan adalah rata-rata yang sedang berjalan. Ini adalah rata-rata periode tertentu dan sangat berharga saat melakukan analisis trend. Bentuk paling sederhana dari rata-rata yang sedang berjalan dapat dilakukan dengan kode yang dibangun berdasarkan rata-rata yang berjalan sebelumnya: Jika seseorang tidak ingin menggunakan matematika floating point - karena ini membutuhkan memori dan mengurangi kecepatan - orang dapat melakukan hal yang sama sepenuhnya di domain integer. Pembagian oleh 256 dalam kode contoh adalah shift-right 8, yang lebih cepat dari pada pembagian menurut mis. 100. Hal ini berlaku untuk setiap kekuatan 2 sebagai pembagi dan kita hanya harus menjaga jumlah weigths sama dengan kekuatan 2. Dan tentu saja orang harus berhati-hati tidak ada melimpah antara (pertimbangkan untuk menggunakan unsigned long) Jika Anda membutuhkan Rata-rata berjalan yang lebih akurat, dalam konkret dari 10 pengukuran terakhir, Anda memerlukan daftar (atau linked list) untuk menahannya. Array ini bertindak sebagai penyangga melingkar dan dengan setiap pengukuran baru yang tertua dihapus. Rata-rata yang berjalan dihitung sebagai jumlah semua elemen dibagi dengan jumlah elemen dalam array. Kode untuk menjalankan rata-rata akan menjadi seperti ini: Kelemahan dari kode ini adalah bahwa array untuk menahan semua nilai bisa menjadi cukup besar. Jika Anda memiliki satu pengukuran per detik dan Anda menginginkan rata-rata berjalan per menit Anda memerlukan sebuah array dari 60 rata-rata per jam akan membutuhkan sebuah array dari 3600. Itu tidak dapat dilakukan dengan cara ini pada Arduino karena hanya memiliki 2K RAM. Namun dengan membangun rata-rata 2 tahap itu bisa didekati dengan cukup baik (disclaimer: tidak untuk semua pengukuran). Dalam kode psuedo: Karena array statis internal baru dibutuhkan untuk setiap fungsi runningAverage, jeritan ini akan diimplementasikan sebagai kelas. RunningAverage library Perpustakaan runAverage membuat kelas fungsi di atas sehingga dapat digunakan berkali-kali dalam sketsa. Ini memisahkan fungsi add () dan avg () menjadi sedikit lebih fleksibel mis. Seseorang bisa memanggil rata-rata berkali-kali tanpa menambahkan apapun. Harap dicatat bahwa setiap instance dari kelas menambahkan array sendiri untuk menahan pengukuran, dan ini menambahkan hingga penggunaan memori. Antarmuka kelas dijaga sekecil mungkin. Catatan: dengan versi 0,2 nama metode semua dibuat lebih deskriptif. Sketsa kecil menunjukkan bagaimana bisa digunakan. Generator acak digunakan untuk meniru sensor. Di setup () myRA dibersihkan sehingga kita bisa mulai menambahkan data baru. Dalam loop () pertama, bilangan acak dihasilkan dan dikonversi ke float untuk ditambahkan ke myRA. Kemudian runningAverage tercetak ke port serial. Kita juga bisa menampilkannya di beberapa LCD atau mengirim ethernet dll. Saat 300 barang ditambahkan myRA dibersihkan untuk memulai lagi dari awal. Untuk menggunakan perpustakaan, buatlah folder di SKETCHBOOKPATHlibaries Anda dengan nama RunningAverage dan letakkan. h dan. cpp di sana. Opsional membuat subdirektori contoh untuk menempatkan contoh aplikasi. 2011-01-30: versi awal 2011-02-28: destruktor yang hilang tetap dalam file. h 2011-02-28: menghapus konstruktor default 2012--. Trimvalue () Yuval Naveh menambahkan trimValue (ditemukan di web) 2012-11-21: refactored 2012-12-30: tambah fillValue () yang refactored untuk penerbitan 2014-07-03: kode proteksi memori tambahan - jika array internal tidak dapat dialokasikan ukuran Menjadi 0. Ini untuk memecahkan masalah yang dijelaskan di sini - forum. arduino. ccindex. phptopic50473.msg1790086msg1790086 - Uji secara ekstensif. Kelas template RunningAverage. h RunningAverage. cpp Seperti yang telah disebutkan orang lain, Anda harus mempertimbangkan filter IIR (respon impuls tak terbatas) daripada filter FIR (respon impaksi yang terbatas) yang Anda gunakan sekarang. Ada lebih dari itu, tapi sekilas filter FIR diimplementasikan sebagai konvolusi eksplisit dan filter IIR dengan persamaan. Saringan IIR yang saya gunakan banyak di mikrokontroler adalah tiang tunggal yang low pass filter. Ini adalah analog digital dari filter analog R-C sederhana. Untuk kebanyakan aplikasi, ini akan memiliki karakteristik yang lebih baik daripada filter kotak yang Anda gunakan. Sebagian besar penggunaan filter kotak yang saya temui adalah hasil dari seseorang yang tidak memperhatikan kelas pemrosesan sinyal digital, bukan sebagai akibat dari kebutuhan akan karakteristik khusus mereka. Jika Anda hanya ingin menipiskan frekuensi tinggi yang Anda tahu adalah suara, satu kutub low pass filter lebih baik. Cara terbaik untuk menerapkan satu digital di mikrokontroler biasanya: FILT FILT FF (NEW - FILT) FILT adalah bagian dari keadaan persisten. Ini adalah satu-satunya variabel persisten yang Anda butuhkan untuk menghitung filter ini. BARU adalah nilai baru yang disaring dengan iterasi ini. FF adalah fraksi filter. Yang menyesuaikan berat filter. Lihatlah algoritma ini dan lihat bahwa untuk FF 0 filternya sangat berat karena hasilnya tidak pernah berubah. Untuk FF 1, sama sekali tidak ada filter sama sekali karena output hanya mengikuti input. Nilai yang berguna ada di antaranya. Pada sistem kecil Anda memilih FF menjadi 12 N sehingga multiply oleh FF dapat dilakukan sebagai pergeseran yang tepat dengan bit N. Sebagai contoh, FF mungkin 116 dan multiply oleh FF oleh karena itu pergeseran yang tepat dari 4 bit. Jika tidak, filter ini hanya memerlukan satu pengurangan dan satu menambahkan, meskipun jumlahnya biasanya lebih lebar daripada nilai masukan (lebih pada ketepatan numerik pada bagian terpisah di bawah ini). Saya biasanya mengambil pembacaan AD secara signifikan lebih cepat daripada yang dibutuhkan dan menerapkan dua filter ini mengalir. Ini adalah gabungan digital dari dua filter R-C secara seri, dan dilemahkan dengan 12 dBoctave di atas frekuensi rolloff. Namun, untuk pembacaan AD biasanya lebih relevan untuk melihat filter di domain waktu dengan mempertimbangkan respons langkahnya. Ini memberitahu Anda seberapa cepat sistem Anda akan melihat perubahan saat hal yang Anda ukur berubah. Untuk memudahkan merancang filter ini (yang hanya berarti memilih FF dan menentukan berapa banyak dari mereka untuk berjemur), saya menggunakan FILTBITS program saya. Anda menentukan jumlah bit pergeseran untuk setiap FF dalam rangkaian filter bertingkat, dan ini menghitung respons langkah dan nilai lainnya. Sebenarnya saya biasanya menjalankan ini melalui skrip wrapper PLOTFILT saya. Ini menjalankan FILTBITS, yang membuat file CSV, lalu memplot file CSV. Sebagai contoh, berikut ini adalah hasil dari PLOTFILT 4 4: Dua parameter untuk PLOTFILT berarti akan ada dua filter yang bertingkat dari jenis yang dijelaskan di atas. Nilai 4 menunjukkan jumlah bit shift untuk mewujudkan multiply oleh FF. Oleh karena itu, kedua nilai FF 116 dalam kasus ini. Jejak merah adalah respons satuan langkah, dan merupakan hal utama yang harus diperhatikan. Sebagai contoh, ini memberitahu Anda bahwa jika perubahan input seketika, output dari filter gabungan akan menetap sampai 90 dari nilai baru dalam 60 iterasi. Jika Anda peduli dengan 95 waktu penyelesaian maka Anda harus menunggu sekitar 73 iterasi, dan untuk 50 waktu penyelesaian hanya ada 26 iterasi. Jejak hijau menunjukkan output dari satu lonjakan amplitudo penuh. Ini memberi Anda beberapa gagasan tentang penekanan kebisingan secara acak. Sepertinya tidak ada sampel tunggal yang akan menyebabkan lebih dari 2,5 perubahan pada output. Jejak biru adalah memberi perasaan subjektif tentang apa yang dilakukan filter ini dengan white noise. Ini bukan tes yang ketat karena tidak ada jaminan apa sebenarnya isi angka acak yang diambil sebagai masukan suara putih untuk menjalankan PLOTFILT ini. Ini hanya untuk memberi Anda perasaan kasar tentang berapa banyak itu akan terjepit dan betapa halusnya itu. PLOTFILT, mungkin FILTBITS, dan banyak barang bermanfaat lainnya, terutama untuk pengembangan firmware PIC tersedia di rilis perangkat lunak Development Tools PIC di halaman download Perangkat Lunak saya. Ditambahkan tentang ketepatan numerik yang saya lihat dari komentar dan sekarang ada jawaban baru bahwa ada minat dalam membahas jumlah bit yang dibutuhkan untuk mengimplementasikan filter ini. Perhatikan bahwa multiply oleh FF akan membuat log 2 (FF) bit baru di bawah titik biner. Pada sistem kecil, FF biasanya dipilih menjadi 12 N sehingga multiply ini sebenarnya disadari oleh pergeseran bit N yang tepat. FILT oleh karena itu biasanya merupakan fixed point integer. Perhatikan bahwa ini tidak mengubah salah satu matematika dari sudut pandang prosesor. Misalnya, jika Anda menyaring pembacaan 10 bit AD dan N 4 (FF 116), Anda memerlukan 4 bit pecahan di bawah pembacaan ADC 10 bit. Salah satu prosesor yang paling, Anda akan melakukan operasi 16 bit integer karena pembacaan AD 10 bit. Dalam kasus ini, Anda masih bisa melakukan operti 16 bit integer yang sama persis, tapi mulailah dengan pembacaan AD yang kiri digeser oleh 4 bit. Prosesor tidak mengetahui perbedaan dan tidak perlu. Melakukan matematika pada bilangan bulat 16 bit keseluruhan bekerja baik jika Anda menganggapnya sebagai 12,4 titik tetap atau bilangan bulat 16 bit sejati (titik tetap 16,0). Secara umum, Anda perlu menambahkan N bit setiap pole filter jika Anda tidak ingin menambahkan noise karena representasi numerik. Pada contoh di atas, filter kedua dua harus memiliki 1.044 18 bit agar tidak kehilangan informasi. Dalam prakteknya pada mesin 8 bit yang berarti Anda menggunakan nilai 24 bit. Secara teknis hanya tiang kedua dua akan membutuhkan nilai yang lebih luas, tapi untuk kesederhanaan firmware saya biasanya menggunakan representasi yang sama, dan dengan demikian kode yang sama, untuk semua kutub filter. Biasanya saya menulis subrutin atau makro untuk melakukan satu operasi kutub filter, lalu menerapkannya pada masing-masing kutub. Apakah subrutin atau makro bergantung pada apakah siklus atau memori program lebih penting dalam proyek tertentu. Either way, saya menggunakan beberapa keadaan awal untuk melewati NEW ke dalam subroutinemacro, yang memperbarui FILT, tapi juga memuatnya ke keadaan awal yang sama dengan NEW. Hal ini memudahkan penerapan beberapa kutub sejak FILT yang diperbarui dari satu kutub adalah NEW Dari yang berikutnya. Ketika sebuah subrutin, berguna untuk menunjuk ke FILT dalam perjalanan, yang diperbarui tepat setelah FILT di jalan keluar. Dengan cara itu subroutine secara otomatis beroperasi pada filter berturut-turut di memori jika disebut berkali-kali. Dengan makro Anda tidak memerlukan pointer sejak Anda meneruskan alamat untuk beroperasi pada setiap iterasi. Contoh Kode Berikut adalah contoh makro seperti yang dijelaskan di atas untuk PIC 18: Dan ini adalah makro yang serupa untuk PIC 24 atau dsPIC 30 atau 33: Kedua contoh ini diimplementasikan sebagai macro menggunakan assembler PIC assembler saya. Yang lebih mampu daripada fasilitas makro internal. Clabacchio: Masalah lain yang seharusnya saya sebutkan adalah implementasi firmware. Anda bisa menulis satu kutub low pass filter subrutin sekali, lalu aplikasikan berkali-kali. Sebenarnya saya biasanya menulis subrutin semacam itu untuk mengambil pointer ke memori ke status filter, lalu memajukan penunjuknya sehingga bisa disebut suksesi dengan mudah untuk mewujudkan filter multi-pole. Ndash Olin Lathrop 20 Apr 12 at 15:03 1. Terima kasih banyak atas jawaban Anda - semuanya. Saya memutuskan untuk menggunakan Filter IIR ini, namun Filter ini tidak digunakan sebagai Filter LowPass Standar, karena saya memerlukan Nilai Counter rata-rata dan membandingkannya untuk mendeteksi Perubahan pada Range tertentu. Karena Nilai-nilai ini van memiliki dimensi yang sangat berbeda tergantung Hardware yang ingin saya gunakan rata-rata agar bisa bereaksi terhadap perubahan spesifik Hardware ini secara otomatis. Ndash sensslen 21 Mei jam 12:06 Jika Anda dapat hidup dengan pembatasan kekuatan dua item sampai rata-rata (yaitu 2,4,8,16,32 dll) maka pembagian dapat dilakukan dengan mudah dan efisien pada Kinerja mikro rendah tanpa pembagian khusus karena bisa dilakukan sebagai sedikit pergeseran. Setiap shift kanan adalah satu kekuatan dari dua contoh: OP mengira dia memiliki dua masalah, terbagi dalam sebuah PIC16 dan memori untuk buffer cincinnya. Jawaban ini menunjukkan bahwa membagi tidak sulit. Diakui hal itu tidak mengatasi masalah memori namun sistem SE memungkinkan jawaban sebagian, dan pengguna dapat mengambil sesuatu dari setiap jawaban untuk dirinya sendiri, atau bahkan mengedit dan menggabungkan jawaban lainnya. Karena beberapa jawaban lain memerlukan operasi pembagian, keduanya sama tidak lengkap karena tidak menunjukkan bagaimana memanfaatkan ini secara efisien pada PIC16. Ndash Martin Apr 20 12 at 13:01 Ada jawaban untuk filter rata-rata bergerak sejati (alias filter boxcar) dengan sedikit kebutuhan memori, jika Anda tidak keberatan melakukan downsampling. Yang disebut sikat integrator-comb filter (CIC). Idenya adalah bahwa Anda memiliki integrator yang Anda ambil perbedaannya selama periode waktu tertentu, dan perangkat penyimpanan memori utama adalah dengan menggunakan downsampling, Anda tidak perlu menyimpan setiap nilai integrator. Hal ini dapat diimplementasikan dengan menggunakan pseudocode berikut: Panjang rata-rata pergerakan efektif Anda adalah penipisanFactorstatesize tetapi Anda hanya perlu menyimpan sampel yang bervariasi. Jelas Anda bisa mendapatkan kinerja yang lebih baik jika Anda menyatakan dan penipisanFaktor adalah kekuatan 2, sehingga operator pembagian dan sisanya digantikan oleh pergeseran dan topeng. Postscript: Saya setuju dengan Olin bahwa Anda harus selalu mempertimbangkan filter IIR sederhana sebelum filter rata-rata bergerak. Jika Anda tidak memerlukan frekuensi-nulls dari filter boxcar, filter low-pass 1-pole atau 2-pole mungkin akan bekerja dengan baik. Di sisi lain, jika Anda memfilter untuk tujuan penipisan (gunakan input tingkat sampel tinggi dan rata-rata untuk digunakan oleh proses dengan tingkat rendah), filter CIC mungkin hanya sesuai dengan yang Anda cari. (Terutama jika Anda dapat menggunakan stateize1 dan hindari ringbuffer sama sekali dengan nilai integrator tunggal saja) Ada beberapa analisis mendalam tentang matematika di belakang menggunakan filter orde pertama IIR yang telah dijelaskan oleh Olin Lathrop di tumpukan pertukaran Digital Signal Processing (Termasuk banyak gambar cantik.) Persamaan untuk filter IIR ini adalah: Ini dapat diimplementasikan hanya dengan bilangan bulat dan tidak ada pembagian dengan menggunakan kode berikut (mungkin memerlukan beberapa debugging saat saya mengetik dari memori.) Filter ini mendekati rata-rata bergerak dari Sampel K terakhir dengan menetapkan nilai alpha menjadi 1K. Lakukan ini pada kode sebelumnya dengan menentukan BITS to LOG2 (K), yaitu untuk K 16 set BITS sampai 4, untuk K 4 set BITS ke 2, dll. (Minta verifikasi kode yang tercantum di sini segera setelah saya mendapatkan perubahan dan Edit jawaban ini jika diperlukan.) Dijawab 23 Juni 12 jam 4:04 Heres sebuah filter low-pass single-pole (moving average, dengan cutoff frequency CutoffFrequency). Sangat sederhana, sangat cepat, bagus, dan hampir tidak ada memori di atas kepala. Catatan: Semua variabel memiliki ruang lingkup di luar fungsi filter, kecuali yang dilewatkan dalam newInput Catatan: Ini adalah filter satu tahap. Beberapa tahap dapat mengalir bersama untuk meningkatkan ketajaman filter. Jika Anda menggunakan lebih dari satu tahap, Anda harus menyesuaikan DecayFactor (yang berkaitan dengan Cutoff-Frequency) untuk memberi kompensasi. Dan yang pasti yang Anda butuhkan hanyalah dua baris yang ditempatkan di manapun, mereka tidak memerlukan fungsinya sendiri. Filter ini memang memiliki waktu ramp-up sebelum moving average mewakili sinyal input. Jika Anda perlu melewati waktu ramp-up itu, Anda bisa menginisialisasi MovingAverage ke nilai pertama dari newInput, bukan 0, dan berharap newInput baru bukan outlier. (CutoffFrequencySampleRate) memiliki range antara 0 dan 0.5. DecayFactor adalah nilai antara 0 dan 1, biasanya mendekati 1. Pelampung presisi tunggal cukup baik untuk kebanyakan hal, saya lebih memilih ganda. Jika Anda perlu tetap dengan bilangan bulat, Anda dapat mengubah DecayFactor dan Amplitude Factor menjadi bilangan bulat fraksional, di mana pembilang disimpan sebagai bilangan bulat, dan penyebutnya adalah bilangan bulat dari 2 (sehingga Anda dapat menggeser bit ke kanan seperti Penyebut daripada harus membagi selama loop filter). Misalnya, jika DecayFactor 0,99, dan Anda ingin menggunakan bilangan bulat, Anda dapat mengatur DecayFactor 0.99 65536 64881. Dan kemudian kapan saja Anda mengalikan dengan DecayFactor di loop filter Anda, cukup geser hasilnya 16. Untuk informasi lebih lanjut tentang ini, sebuah buku yang sangat bagus Online, bab 19 tentang filter rekursif: dspguidech19.htm PS Untuk paradigma Moving Average, pendekatan yang berbeda untuk menetapkan DecayFactor dan AmplitudeFactor yang mungkin lebih relevan dengan kebutuhan Anda, katakanlah Anda menginginkan yang sebelumnya, sekitar 6 item dirata-ratakan bersama, lakukan secara diskrit, Anda akan menambahkan 6 item dan bagi dengan 6, jadi Anda dapat mengatur AmplitudeFactor menjadi 16, dan DecayFactor menjadi (1.0 - AmplitudeFactor). Menjawab 14 Mei 12 di 22:55 Semua orang telah berkomentar secara menyeluruh tentang kegunaan IIR vs FIR, dan pada divisi power-of-two. Id hanya ingin memberikan beberapa rincian implementasi. Di bawah ini bekerja dengan baik pada mikrokontroler kecil tanpa FPU. Tidak ada perkalian, dan jika Anda mempertahankan N dua kekuatan, semua divisi itu sedikit bergeser bit. Penyangga cincin FIR dasar: simpan buffer yang sedang berjalan dari nilai N terakhir, dan SUM berjalan dari semua nilai di buffer. Setiap kali sampel baru masuk, kurangi nilai tertua dari buffer dari SUM, ganti dengan sampel baru, tambahkan sampel baru ke SUM, dan output SUMN. Modifikasi penyangga cincin IIR: simpan SUM berjalan dari nilai N terakhir. Setiap kali sampel baru masuk, SUM - SUMN, tambahkan sampel baru, dan output SUMN. Dijawab 28 Agu 13 at 13:45 Jika saya membaca Anda benar, Anda menggambarkan filter IIR orde pertama nilai yang Anda kurangi bukanlah nilai tertua yang jatuh, tapi bukan nilai rata-rata sebelumnya. Filter IIR orde pertama tentu bisa berguna, tapi saya tidak yakin dengan apa yang Anda maksudkan saat Anda menyarankan bahwa hasilnya sama untuk semua sinyal periodik. Pada tingkat sampel 10KHz, memberi makan gelombang persegi 100Hz ke dalam kotak filter 20-tahap akan menghasilkan sinyal yang naik secara merata untuk 20 sampel, duduk tinggi selama 30, turun secara merata untuk 20 sampel, dan duduk rendah untuk 30. Perintah pertama IIR filter Ndash supercat Aug 28 13 at 15:31 akan menghasilkan gelombang yang dengan tajam mulai naik dan berangsur-angsur turun mendekati (tapi tidak di) input maksimal, lalu dengan tajam mulai jatuh dan berangsur-angsur turun mendekati (tapi tidak di) input minimal. Perilaku yang sangat berbeda. Ndash supercat Aug 28 13 at 15:32 Satu masalah adalah bahwa rata-rata bergerak sederhana mungkin atau mungkin tidak berguna. Dengan filter IIR, Anda bisa mendapatkan filter yang bagus dengan jumlah yang relatif sedikit. FIR yang Anda jelaskan hanya bisa memberi Anda sebuah persegi panjang pada waktunya - sebuah sinc di freq - dan Anda bisa mengelola lobus samping. Ini mungkin layak untuk dilemparkan beberapa bilangan bulat banyak untuk membuatnya menjadi FIR yang bagus simetris yang bagus jika Anda bisa mengimbangi kutu jam. Ndash Scott Seidman Aug 29 13 at 13:50 ScottSeidman: Tidak perlu mengalikan jika seseorang hanya memiliki setiap tahap FIR baik output rata-rata input ke tahap itu dan nilai yang tersimpan sebelumnya, dan kemudian menyimpan input (jika seseorang memiliki Kisaran numerik, seseorang bisa menggunakan jumlah tersebut daripada rata-rata). Apakah itu lebih baik daripada filter kotak tergantung pada aplikasi (respons langkah filter kotak dengan penundaan total 1ms, misalnya, akan mengalami lonjakan d2dt yang buruk saat input berubah, dan lagi 1ms kemudian, namun akan memiliki minimum Mungkin ddt untuk filter dengan penundaan 1ms total). Ndash supercat Aug 29 13 at 15:25 Seperti kata mikeselectricstuff, jika Anda benar-benar perlu mengurangi kebutuhan ingatan Anda, dan Anda tidak keberatan respons impuls Anda menjadi eksponensial (bukan pulsa persegi panjang), saya akan mencari filter rata-rata bergerak eksponensial . Saya menggunakannya secara ekstensif. Dengan jenis filter itu, Anda tidak memerlukan penyangga. Anda tidak perlu menyimpan N sampel masa lalu. Hanya satu. Jadi, kebutuhan memori Anda bisa ditebang oleh faktor N. Juga, Anda tidak memerlukan pembagian untuk itu. Hanya perkalian. Jika Anda memiliki akses ke aritmatika floating-point, gunakan perkalian floating-point. Jika tidak, lakukan perkalian bilangan bulat dan bergeser ke kanan. Namun, kami di tahun 2012, dan saya akan merekomendasikan Anda untuk menggunakan kompiler (dan MCU) yang memungkinkan Anda bekerja dengan nomor floating-point. Selain memori yang lebih efisien dan lebih cepat (Anda tidak perlu memperbarui item dalam buffer melingkar), saya akan mengatakan itu juga lebih alami. Karena respons impuls eksponensial lebih sesuai dengan perilaku alam, pada kebanyakan kasus. Menjawab 20 Apr 12 at 9:59 Salah satu masalah dengan filter IIR karena hampir disentuh oleh olin dan supercat namun tampaknya diabaikan oleh orang lain adalah pembulatannya menurunkan beberapa ketidaktepatan (dan berpotensi biastruncasi). Dengan asumsi bahwa N adalah kekuatan dua, dan hanya aritmatika integer yang digunakan, pergeseran benar secara sistematis menghilangkan LSB sampel baru. Itu berarti berapa lama seri itu bisa, rata-rata tidak akan pernah memperhitungkannya. Sebagai contoh, anggaplah sebuah seri yang perlahan menurun (8,8,8,87,7,7 7,6,6,) dan anggap rata-rata memang 8 di awal. Tinju 7 sampel akan membawa rata-rata 7, apa pun kekuatan saringannya. Hanya untuk satu sampel. Cerita yang sama untuk 6, dll Sekarang pikirkan sebaliknya. Serie naik. Rata-rata akan tetap di 7 selamanya, sampai sampel cukup besar untuk membuatnya berubah. Tentu saja, Anda bisa memperbaiki bias dengan menambahkan 12N2, tapi wont itu benar-benar memecahkan masalah presisi. Dalam hal ini seri yang menurun akan bertahan sampai 8 sampai sampel adalah 8-12 (N2). Untuk N4 misalnya, sampel di atas nol akan tetap rata-rata tidak berubah. Saya percaya solusi untuk itu berarti menyandang akumulator LSB yang hilang. Tapi saya tidak membuatnya cukup jauh untuk memiliki kode yang siap, dan saya tidak yakin itu tidak akan merugikan kekuatan IIR dalam beberapa kasus seri lainnya (misalnya, apakah rata-rata 7,9,7,9 sampai 8 saat itu). Olin, kaskade dua tahap Anda juga perlu penjelasan. Maksud Anda memegang dua nilai rata-rata dengan hasil dari umpan pertama ke kedua dalam setiap iterasi. Apa manfaat dari Forum ini: Digitale Signalverarbeitung DSP MOVING AVERAGE FILTER di FastAVR Dim indeks sebagai byte dim value (4) sebagai byte redup rata-rata seperti kata dim count sebagai indeks byte 1 39arrays di bascom beginnen mit 1 :-( nilai (index) Getadc (x) 39messen incr index jika indeks 5 kemudian indeks 1 untuk menghitung 1 sampai 4 nilai rata-rata rata-rata (hitungan) rata-rata pergeseran berikutnya, kanan, 2 39geht schneller als 4 loop Fastavr wird ja nicht sooo viel anders sein. Anstatt do-loop kannst Du das adalah dazwischen steht natrlich auch als sub aufrufen lainnya yang lebih tua. Dann mach es doch begitu bertele-tele pada Beispiel (nur ohne den Fehler rata-rata bis in unendliche hochzuaddieren -)), nur da der letzte Mittelwert den ltesten Wert des arrays ersetzt: do Nilai indeks indeks (indeks) getadc (x) 39messen (indeks-1) rata-rata jika indeks 5 kemudian indeks 1 rata-rata 0 untuk menghitung 1 sampai 4 nilai rata-rata (rata-rata) rata-rata pergeseran berikutnya, kanan, 2 39geht schneller als 4 loop Noch Ne Idee zum gltten, ev. Etwas trge: - Jika messen als Anfang Dann immer: - neuen Wert messen Wert (3Wert neuer Wert) 4 nur falls es noch einen interessiert. Soweit ich die bisherigen Varianten hier berblickt habe, wird immer die Summe fr den Mittelwert ausgewertet. Das macht diese Methoden aber langsamer mit steigernder Fensterlnge. Nachdem der Mittelwert linier ist, kann ich die Summe auch einfach zerlegen und aur mir jadi jedesmal die Summe auszuwerten. Define WindowSize 4 int samplesWindowSize int index 0 int average 0 while (1) Alten Wert abziehen. Rata - rata - sampelindex Neuen Wert zufgen. Sampleindex input WindowSize Neuen Mittelwert bilden. Rata-rata sample index Im Ringbuffer indeks indeks weiterstellen WindowSize Der Code ist keinesfalls quotoptimalquot, sondern sollte nur die Funktionsweise demonstrieren. Desweiteren muss man bei diesem Verfahren meninggal Rundungsfehler beachten, d. h. Bei Benutzung von Integer-Arithmetik ist der gewonnene Mittelwert etwas ungenauer. Autor: Martin (Gast) Datum: 02.05.2009 03:29 mal ein ganz anderer Ansatz: Warum erhhst Du nicht einfach die Sampling-Zeit am AD-Wandler. Somit memiliki Du-Ein Hardware-Moving-Average-Filter Nimm einfach ne viermal jadi hohe Samplingrate, ist das gleiche, wie wenn Dein AD-Wandler vier Werte aufnimmt und Du Sie dann wieder mittelst (Oke. Gesame Sampling - und Convert - Zeit betrachten) ) Die vier Einzelwerte interessieren Dich ja eh nicht und die Werte die der AD-Wandler liefert werden auch besser (Im Datenblatt des AD-Wandlers drfte auch ne Formel fr die Mindest-Sample-Zeit angegeben sein). Nur jadi ein Gedanke. Mal ein ganz anderer Ansatz: Warum erhhst Du nicht einfach die Sampling-Zeit am AD-Wandler. Suatu saat, Du-nin Hardware-Moving-Average-Filter N jadi pria terbaik bisa mengalahkan Falle eine Unterabtastung. Wenn man vor dem ADC Eingang noch einen RC-Tiefpass mit passender Grenzfrequenz setzt dann wird ein Schuh draus. Ohne diesen schlgt mati SampleampHoldstufe des ADCs zu, wir reden ja vom AVR. Und mati bentigt nur 1.5 ADC Takte um das Eingangssignal zu sampeln. Antwort schreiben Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail ber Antworten auf Ihren Beitrag informiert werden mchten, melden Sie sich bitte an. Wichtige Regeln - erst lesen, dann posten Gro - und Kleinschreibung verwenden Lngeren Sourcecode nicht im Teks einfgen, sondern als Dateianhang Formatierung (mehr Informationen.) CC-Codec avrasmAVR-Assembler-Codeavrasm codeCode in anderen Sprachen, ASCII-Zeichnungencode mathFormel in LaTeX-Syntaxmath Titel - Link zu Artikel Verweis auf anderen Beitrag einfgen: Rechtsklick auf Beitragstitel, Adresse kopieren, und in den Teks einfgen

No comments:

Post a Comment