Saya mencoba menemukan penyilangan nol dari gelombang sinus untuk mengubah gelombang sinus menjadi gelombang persegi. Satu-satunya masalah adalah bahwa gelombang sinus berisik, jadi saya mendapatkan banyak jitter dan penyilangan nol palsu.
Adakah yang bisa merekomendasikan psuedocode sederhana atau materi yang relevan? Sejauh ini saya punya sesuatu seperti ini:
if (sample[i]>0 && sample[i+1]<0) || (sample[i]<0 && sample[i+1]>0)
Adakah yang bisa merekomendasikan metode yang lebih kuat?
Jawaban:
Anda dapat mencoba pemfilteran low-pass sinyal input untuk mendapatkan zero-crossing yang lebih mulus (atau bahkan pemfilteran band-pass jika Anda memiliki ide yang bagus tentang lokasi frekuensi dari gelombang sinus). Risikonya adalah bahwa jika informasi fase akurat sampel sangat penting untuk aplikasi Anda, kelambatan tambahan dari filter mungkin menjadi masalah.
Pendekatan lain: alih-alih mencoba mengubah gelombang sinus menjadi gelombang persegi, bagaimana dengan mendapatkan osilator gelombang persegi independen untuk menyelaraskan diri dalam fase / frekuensi dengan gelombang sinus? Ini dapat dilakukan dengan loop fase-terkunci .
sumber
Yang Anda tunjukkan tentu saja adalah detektor zero-crossing. Beberapa hal yang terlintas dalam pikiran yang dapat meningkatkan situasi Anda:
Jika Anda memiliki noise yang berada di luar pita sinyal Anda (yang hampir pasti demikian, karena input Anda adalah nada murni), maka Anda dapat meningkatkan rasio sinyal-ke-noise dengan menerapkan filter bandpass di sekitar sinyal yang menarik. . Lebar passband filter harus dipilih berdasarkan seberapa tepatnya Anda mengetahui frekuensi sinusoid a priori . Dengan mengurangi jumlah noise yang ada pada sinusoid, jumlah penyilangan nol palsu dan jitter mereka tentang waktu penyeberangan yang benar akan berkurang.
Sehubungan dengan detektor zero-crossing itu sendiri, Anda dapat menambahkan beberapa histeresis ke proses. Ini akan mencegah generasi penyeberangan terukur ekstra di sekitar persimpangan instan yang benar. Menambahkan histeresis ke detektor mungkin terlihat seperti ini:
Secara efektif, Anda menambahkan beberapa status ke detektor zero-crossing Anda. Jika Anda yakin sinyal input memiliki nilai positif, Anda mengharuskan sinyal turun di bawah nilai ambang batas yang dipilih
-T
untuk mendeklarasikan penyilangan nol nyata. Demikian juga, Anda mensyaratkan bahwa sinyal naik kembali di atas ambang pintuT
untuk menyatakan bahwa sinyal telah berosilasi kembali ke positif lagi.Anda dapat memilih ambang batas untuk menjadi apa pun yang Anda inginkan, tetapi untuk sinyal seimbang seperti sinusoid, masuk akal untuk membuatnya menjadi simetris tentang nol. Pendekatan ini dapat membantu memberikan Anda hasil yang tampak lebih bersih, tetapi itu akan menambah waktu tunda karena Anda benar-benar mengukur batas ambang bukan nol alih-alih nol persimpangan.
Seperti yang disarankan pichenettes dalam jawabannya, loop fase-terkunci kemungkinan besar adalah cara terbaik untuk pergi, karena PLL melakukan apa yang Anda coba lakukan. Singkatnya, Anda menjalankan generator gelombang persegi yang berjalan secara paralel dengan input sinusoid. PLL melakukan pengukuran fase berkala pada sinusoid, kemudian menyaring aliran pengukuran untuk mengarahkan frekuensi sesaat dari generator gelombang persegi. Pada titik tertentu, loop akan (semoga) mengunci, pada titik mana gelombang kuadrat harus dikunci dalam frekuensi dan fase dengan sinusoid input (tentu saja dengan sejumlah kesalahan, tentu saja; tidak ada teknik yang sempurna).
sumber
T
. Berarti bukannya&& (sample[i - 1] > -T) && (sample[i] < -T))
, gunakan&& (sample[i - 1] >= -T) && (sample[i] < -T))
. Ini perlu diterapkan untuk keduanyaif
danelse if
pernyataan.Saya memiliki pengalaman yang baik dengan metode yang sangat sederhana untuk menemukan tanda perubahan sinyal pada waktu:
rata-rata / rata-rata setiap cluster, ini adalah perubahan tanda Anda
lakukan korelasi dengan fungsi langkah pada poin yang diprediksi oleh 4
Dalam kasus saya 5 dan 6 tidak meningkatkan ketepatan metode ini. Anda dapat menggoyang-goyangkan sinyal Anda dengan noise dan melihat apakah itu membantu.
sumber
Saya tahu pertanyaan ini agak lama, tetapi saya harus menerapkan zero crossing baru-baru ini. Saya menerapkan cara yang disarankan Dan dan agak senang dengan hasilnya. Inilah kode python saya, jika ada yang tertarik. Saya tidak benar-benar seorang programmer yang elegan, tolong ikut saya.
Harap Catatan: kode saya tidak mendeteksi tanda dan menggunakan sedikit pengetahuan a-priori tentang frekuensi target untuk menentukan ambang waktu. Ambang ini digunakan untuk mengelompokkan penyeberangan berganda (titik-titik warna berbeda dalam gambar) dari mana median yang paling dekat dengan kelompok median dipilih (persilangan biru pada gambar).
sumber