Monday 14 August 2017

Tertanam C Moving Average


Mungkinkah menerapkan rata-rata bergerak di C tanpa memerlukan jendela sampel, saya telah menemukan bahwa saya dapat mengoptimalkan sedikit, dengan memilih ukuran jendela, itulah kekuatan dua untuk memungkinkan perpindahan bit daripada membagi, tapi tidak memerlukannya. Penyangga akan menyenangkan Apakah ada cara untuk mengungkapkan hasil rata-rata bergerak baru hanya sebagai fungsi dari hasil lama dan sampel baru Tentukan contoh rata-rata bergerak, di atas jendela 4 sampel menjadi: Tambahkan sampel baru e: Rata-rata bergerak dapat diimplementasikan secara rekursif. , Tapi untuk kalkulasi rata-rata bergerak yang tepat, Anda harus mengingat sampel masukan tertua dalam jumlah (misalnya huruf a pada contoh Anda). Untuk panjang N rata-rata bergerak yang Anda hitung: di mana yn adalah sinyal output dan xn adalah sinyal input. Pers. (1) dapat ditulis secara rekursif. Jadi Anda harus selalu mengingat sampel xn-N untuk menghitung (2). Seperti yang ditunjukkan oleh Conrad Turner, Anda dapat menggunakan jendela eksponensial (jauh lebih panjang), yang memungkinkan Anda menghitung keluaran hanya dari keluaran lalu dan masukan saat ini: namun ini bukan standar pergerakan rata-rata (tanpa bobot) namun secara eksponensial Rata bergerak tertimbang, di mana sampel lebih jauh di masa lalu mendapatkan bobot yang lebih kecil, tapi (setidaknya secara teori) Anda tidak akan pernah melupakan apapun (bobotnya semakin kecil dan kecil untuk sampel jauh di masa lalu). Saya menerapkan rata-rata bergerak tanpa memori item individual untuk program pelacakan GPS yang saya tulis. Saya mulai dengan 1 sampel dan bagi 1 untuk mendapatkan nilai rata-rata saat ini. Saya kemudian menambahkan sampel anothe dan membagi dengan 2 ke avg saat ini. Ini berlanjut sampai saya mencapai panjang rata-rata. Setiap saat setelah itu, saya menambahkan sampel baru, mendapatkan rata-rata dan menghapus rata-rata dari total. Saya bukan seorang matematikawan tapi ini sepertinya cara yang bagus untuk melakukannya. Kupikir itu akan mengubah perut orang matematika sejati tapi, ternyata itu adalah salah satu cara yang bisa diterima untuk melakukannya. Dan hasilnya bagus. Ingatlah bahwa semakin tinggi panjangnya semakin lambat maka mengikuti apa yang ingin Anda ikuti. Itu mungkin tidak masalah sebagian besar waktu tapi ketika mengikuti satelit, jika Anda lamban, jejaknya bisa jauh dari posisi sebenarnya dan akan terlihat buruk. Anda bisa memiliki jarak antara tempat duduk dan titik-titik trailing. Saya memilih panjang 15 update 6 kali per menit untuk mendapatkan smoothing yang memadai dan tidak terlalu jauh dari posisi duduk sebenarnya dengan titik jepret yang merapikan. Jawab 16 16 16 di 23:03 menginisialisasi total 0, count0 (setiap kali melihat nilai baru Kemudian satu masukan (scanf), satu menambahkan totalnewValue, satu kenaikan (hitungan), satu rata-rata pembagian (jumlah total) Ini akan menjadi rata-rata bergerak di atas Semua input Untuk menghitung rata-rata hanya di atas 4 masukan terakhir, akan memerlukan 4 variabel input, mungkin menyalin setiap masukan ke inputvariable yang lebih tua, kemudian menghitung rata-rata pergerakan baru. Sebagai jumlah dari 4 variabel input, dibagi dengan 4 (pergeseran kanan 2 akan menjadi Baik jika semua input positif membuat perhitungan rata-rata dijawab 3 Feb 15 at 4:06 Itu benar-benar akan menghitung rata-rata total dan TIDAK rata-rata bergerak. Seiring bertambahnya dampak, setiap sampel masukan baru menjadi sangat kecil ndash Hilmar Feb Stack Exchange, IncI tahu ini dapat dicapai dengan dorongan sesuai: Tapi saya benar-benar ingin menghindari penggunaan dorongan. Saya telah googled dan tidak menemukan contoh yang sesuai atau mudah dibaca. Pada dasarnya saya ingin melacak bergerak Rata-rata arus aliran angka floating point yang sedang berlangsung menggunakan 1000 nomor terbaru sebagai sampel data. Apa cara termudah untuk mencapainya? Saya bereksperimen dengan menggunakan array melingkar, moving average eksponensial dan rata-rata bergerak yang lebih sederhana dan menemukan bahwa hasil dari array melingkar sesuai dengan kebutuhan saya yang terbaik. Tanya 12 Jun 12 at 4:38 Jika kebutuhan Anda sederhana, Anda mungkin hanya mencoba menggunakan rata-rata bergerak eksponensial. Sederhananya, Anda membuat variabel akumulator, dan saat kode Anda melihat setiap sampel, kode akan memperbarui akumulator dengan nilai baru. Anda memilih alpha konstan yaitu antara 0 dan 1, dan hitung ini: Anda hanya perlu menemukan nilai alfa dimana efek sampel tertentu hanya bertahan sekitar 1000 sampel. Hmm, saya tidak yakin ini cocok untuk anda, sekarang saya sudah meletakkannya disini. Masalahnya adalah bahwa 1000 adalah jendela yang cukup panjang untuk rata-rata bergerak eksponensial Im tidak yakin ada alfa yang akan menyebar rata-rata selama 1000 nomor terakhir, tanpa arus dalam perhitungan floating point. Tapi jika Anda menginginkan rata-rata yang lebih kecil, seperti 30 angka atau lebih, ini adalah cara yang sangat mudah dan cepat untuk melakukannya. Jawab 12 Jun pukul 4:44 1 di posmu Rata-rata pergerakan eksponensial dapat memungkinkan alfa menjadi variabel. Jadi ini memungkinkannya digunakan untuk menghitung rata-rata basis waktu (misalnya byte per detik). Jika waktu sejak update akumulator terakhir lebih dari 1 detik, Anda membiarkan alpha menjadi 1.0. Jika tidak, Anda bisa membiarkan alpha menjadi (usecs sejak update1000000 terakhir). Ndash jxh 12 Jun 12 at 6:21 Pada dasarnya saya ingin melacak rata-rata bergerak aliran arus dari sebuah angka floating point dengan menggunakan 1000 nomor terbaru sebagai sampel data. Perhatikan bahwa di bawah ini update total sebagai elemen sebagai tambahan yang ditambahkan, hindarkan O (N) yang mahal untuk menghitung jumlah yang dibutuhkan untuk rata-rata - sesuai permintaan. Total dibuat parameter yang berbeda dari T untuk mendukung mis. Menggunakan panjang panjang bila total 1000 s panjang, int untuk char s, atau double to total float s. Ini sedikit cacat pada numsamples yang bisa melewati INTMAX - jika Anda peduli Anda bisa menggunakan unsigned long long. Atau gunakan anggota data bool tambahan untuk merekam saat wadah pertama kali diisi saat bersepeda mendekati numamples di sekitar array (terbaik kemudian berganti nama menjadi sesuatu yang tidak berbahaya seperti pos). Dijawab 12 Jun 12 at 5:19 seseorang mengasumsikan bahwa operator quotvoid (T sample) quot sebenarnya adalah quotvoid operatorltlt (T sample) quot. Ndash oPless 8 Jun 14 jam 11:52 oPless ahhh. Baik terlihat Sebenarnya saya bermaksud untuk itu menjadi operator void () (sampel T) tapi tentu saja Anda bisa menggunakan notasi apa pun yang Anda sukai. Akan memperbaiki, terima kasih. Ndash Tony D 8 Jun 14 di 14: 27 Seperti yang telah disebutkan orang lain, Anda harus mempertimbangkan filter IIR (respon impuls tak terbatas) daripada filter FIR (respon impaksi rendah) 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 manfaatnya?

No comments:

Post a Comment