Mengukur Harmoni - Analyzer Spektrum Suara di STM32L4 Discovery
Dalam posting sebelumnya , kami menghubungkan layar LCD Cina murah ke papan STM32L4 Discovery . Sekarang kami akan mencoba menerapkan pada kombinasi ini sesuatu yang melampaui berkedip tradisional LED, yaitu, penganalisa spektrum suara yang menggunakan mikrofon di papan tulis. Pada saat yang sama, saya akan memberi tahu Anda cara menggunakan sistem operasi FreeRTOS, dan mengapa diperlukan, serta mengapa ada 12 nada dalam satu oktaf musik, dan lebih dari 53 nada lebih baik dari 12.
Digitalisasi suara
Kami ingin menerima sinyal dari mikrofon, menghitung spektrumnya menggunakan transformasi Fourier cepat (FPU untuk membantu kami) dan menunjukkan hasilnya pada LCD dalam bentuk 'air terjun berwarna'. Kekuatan suara akan dikodekan dalam warna. Kami akan menggambar garis piksel dari tepi tampilan di mana piksel paling kiri akan sesuai dengan frekuensi minimum dan yang paling kanan akan sesuai dengan maksimum, sementara gambar sebelumnya akan digeser oleh satu baris, membebaskan ruang untuk baris baru. Mikrokontroler kami terlalu rumit untuk memulai dari awal, jadi mari kita mulai dengan contoh dari kit STM32Cube yang disebut DFSDM_AudioRecord. Apa itu DFSDM? Ini adalah Filter Digital untuk Modulasi Sigma-Delta. Faktanya adalah bahwa, tidak seperti mikrofon analog tua yang baik, yang ada di papan Discovery tidak memberikan sinyal dalam bentuk tegangan sebanding dengan tekanan suara,dan sebagai urutan nol dan yang dengan frekuensi clock beberapa megahertz. Jika Anda melewatkan urutan ini melalui filter low-pass, Anda mendapatkan sinyal analog yang sama. Dalam model mikrokontroler sebelumnya, perlu membuat filter digital untuk menerima sinyal audio dalam bentuk digital. Sekarang mikrokontroler memiliki modul khusus untuk ini, dan semua yang diperlukan adalah mengkonfigurasinya pada awal program. Untuk melakukan ini, Anda dapat mempelajari membaca dokumentasi, atau menggunakan contoh yang sudah jadi. Saya pergi ke jalan kedua. Gambar berikut menggambarkan struktur internal program DFSDM_AudioRecord.Dalam model mikrokontroler sebelumnya, perlu membuat filter digital untuk menerima sinyal audio dalam bentuk digital. Sekarang mikrokontroler memiliki modul khusus untuk ini, dan semua yang diperlukan adalah mengkonfigurasinya pada awal program. Untuk melakukan ini, Anda dapat mempelajari membaca dokumentasi, atau menggunakan contoh yang sudah jadi. Saya pergi ke jalan kedua. Gambar berikut menggambarkan struktur internal program DFSDM_AudioRecord.Dalam model mikrokontroler sebelumnya, perlu membuat filter digital untuk menerima sinyal audio dalam bentuk digital. Sekarang mikrokontroler memiliki modul khusus untuk ini, dan semua yang diperlukan adalah mengkonfigurasinya pada awal program. Untuk melakukan ini, Anda dapat mempelajari membaca dokumentasi, atau menggunakan contoh yang sudah jadi. Saya pergi ke jalan kedua. Gambar berikut menggambarkan struktur internal program DFSDM_AudioRecord.
Suara digital menggunakan DMA masuk ke buffer cincin. DMA menyebabkan interupsi dua kali: sekali - ketika buffer setengah penuh, kedua kalinya - ketika buffer penuh. Rutin interupsi hanya mengatur bendera yang sesuai. Fungsi utama () setelah inisialisasi mengeksekusi loop tak terbatas di mana flag-flag ini diperiksa dan, jika flag diset, separuh buffer yang sesuai disalin. Contoh menyalin data ke buffer lain, dari mana, lagi menggunakan DMA, dikirim ke penguat headphone. Saya meninggalkan fungsi ini, menambahkan perhitungan spektrum sinyal audio.Ketika ada banyak tugas
Cara mudah untuk menambahkan fungsionalitas baru ke kode kita adalah menambahkan lebih banyak flag dan menulis fungsi yang akan dipanggil jika flag ini disetel. Hasilnya biasanya berantakan bendera, fungsi handler, dan konteks global, yang terpaksa bersifat global, karena solusi dari satu masalah dibagi menjadi banyak langkah kecil yang dilaksanakan oleh fungsi individu - event handler. Cara alternatif adalah mempercayakan manajemen tugas ke sistem operasi, seperti FreeRTOS. Ini memungkinkan Anda untuk menyederhanakan logika secara signifikan karena fakta bahwa setiap tugas diselesaikan dalam siklus pemrosesan peristiwa sendiri yang berinteraksi satu sama lain melalui fungsi sistem operasi. Misalnya, kita dapat menambahkan tugas pemrosesan data sebagai siklus terpisah,yang akan menunggu data siap pada sinkronisasi primitif - semaphore. Semafornya sangat sederhana: Anda dapat melewatinya jika flag dicentang, dan flag secara otomatis dihilangkan. Dalam kasus kami, sumber data akan menaikkan bendera ketika menyiapkan data untuk tugas lain. Dengan cara yang sama, Anda dapat membuat rantai sewenang-wenang dari tugas-tugas sumber data dan tugas-tugas konsumen data, mirip dengan bagaimana ini terjadi, misalnya, dalam sistem operasi Linux.dalam sistem operasi Linux.dalam sistem operasi Linux.
Tentu saja, pelaksanaan tugas secara simultan adalah ilusi, terutama ketika inti komputasi hanya satu. Dalam hal ini, kita dapat mengatakan bahwa kita memiliki satu utas eksekusi program oleh prosesor. Semaphores, seperti primitif sinkronisasi lainnya, memainkan peran kelinci ajaib, di mana aliran eksekusi gagal muncul dalam tugas lain.Menghubungkan FreeRTOS ke proyek Anda cukup sederhana. Hanya perlu mengganti loop tanpa ujung, yang biasanya mengakhiri fungsi utama () di mikrokontroler, dengan panggilan ke osKernelStart (). Setelah itu, kompiler akan menjelaskan kepada Anda apa yang kurang untuk dikompilasi. Semua tindakan yang sebelumnya Anda lakukan dalam loop perlu ditransfer ke tugas yang terpisah dan terdaftar dengan panggilan xTaskCreate. Setelah itu, Anda dapat menambahkan tugas sebanyak yang Anda inginkan. Harus diingat bahwa antara panggilan ke xTaskCreate dan osKernelStart lebih baik tidak menempatkan kode yang berfungsi dengan perangkat keras, karena di sini timer sistem mungkin tidak berfungsi dengan benar. Panggilan ke pengatur waktu sistem operasi osSystickHandler () harus ditambahkan ke SysTick_Handler (), dan dua fungsi SVC_Handler dan PendSV_Handler harus dihapus dari kode mereka,karena mereka diimplementasikan dalam kode OS. Saat mendaftarkan tugas, penting untuk tidak membuat kesalahan dengan ukuran tumpukan. Jika ternyata terlalu kecil, Anda akan mendapatkan crash di tempat-tempat yang paling tak terduga. Pertama ketika stack overflows adalah struktur itu sendiri yang menggambarkan tugas. IAR memiliki kemampuan untuk melihat daftar tugas. Jika Anda melihat tugas dengan nama yang diubah di dalamnya, maka Anda perlu menambah ukuran tumpukan.Untuk menghitung spektrum, kami menggunakan transformasi Fourier cepat. Fungsi yang sesuai sudah ada di perpustakaan. Dia menerima buffer yang diisi dengan data yang kompleks, dan membentuk hasilnya di sana. Oleh karena itu, pada input, ia membutuhkan penyangga, di mana suara yang didigitalkan berganti dengan nol (bagian kompleks 0). Pada output, kita mendapatkan bilangan kompleks yang dengan segera kita menghitung kuadrat dari modul dengan menambahkan kuadrat dari bagian nyata dan imajiner. Kami melakukan ini hanya untuk setengah buffer, karena spektrumnya simetris. Kita akan membutuhkan paruh kedua jika kita ingin melakukan transformasi terbalik, tetapi untuk tampilan spektrum sederhana itu tidak diperlukan. Beberapa upaya tambahan diperlukan untuk dapat menghitung spektrum dalam rentang spektral yang berbeda. Untuk mendapatkan spektrum untuk frekuensi rendah,Saya mengumpulkan data untuk beberapa siklus membaca buffer, secara efektif mengurangi frekuensi pengambilan sampel suara, yang awalnya 44,1 kHz. Hasilnya adalah 6 rentang - 20kHz, 10kHz, 5kHz, 2600Hz, 1300Hz, 650Hz. Untuk beralih rentang, gunakan joystick dan tugas terpisah. Joystick juga melakukan fungsi memulai / menghentikan 'air terjun', serta menyesuaikan sensitivitas. Lebih mudah memperlihatkan spektrum dalam satuan logaritmik (desibel), karena rentang dinamiknya biasanya sangat besar, dan pada skala linier kita hanya dapat membedakan komponen terkuat dari spektrum tersebut. Logaritma dianggap cukup lama bahkan pada FPU, jadi saya mengganti logaritma nyata dengan pendekatan linier piecewise, yang mudah didapat, karenaHasilnya adalah 6 rentang - 20kHz, 10kHz, 5kHz, 2600Hz, 1300Hz, 650Hz. Untuk beralih rentang, gunakan joystick dan tugas terpisah. Joystick juga melakukan fungsi memulai / menghentikan 'air terjun', serta menyesuaikan sensitivitas. Lebih mudah memperlihatkan spektrum dalam satuan logaritmik (desibel), karena rentang dinamiknya biasanya sangat besar, dan pada skala linier kita hanya dapat membedakan komponen terkuat dari spektrum tersebut. Logaritma dianggap cukup lama bahkan pada FPU, jadi saya mengganti logaritma nyata dengan pendekatan linier piecewise, yang mudah didapat, karenaHasilnya adalah 6 rentang - 20kHz, 10kHz, 5kHz, 2600Hz, 1300Hz, 650Hz. Untuk beralih rentang, gunakan joystick dan tugas terpisah. Joystick juga melakukan fungsi memulai / menghentikan 'air terjun', serta menyesuaikan sensitivitas. Lebih mudah memperlihatkan spektrum dalam satuan logaritmik (desibel), karena rentang dinamiknya biasanya sangat besar, dan pada skala linier kita hanya dapat membedakan komponen terkuat dari spektrum tersebut. Logaritma dianggap cukup lama bahkan pada FPU, jadi saya mengganti logaritma nyata dengan pendekatan linier piecewise, yang mudah didapat, karenaLebih mudah untuk menunjukkan spektrum dalam satuan logaritmik (desibel), karena rentang dinamiknya biasanya sangat besar, dan pada skala linier kita hanya dapat membedakan komponen-komponen terkuat dari spektrum tersebut. Logaritma dianggap cukup lama bahkan pada FPU, jadi saya mengganti logaritma nyata dengan pendekatan linier piecewise, yang mudah didapat, karenaLebih mudah untuk menunjukkan spektrum dalam satuan logaritmik (desibel), karena rentang dinamiknya biasanya sangat besar, dan pada skala linier kita hanya dapat membedakan komponen-komponen terkuat dari spektrum tersebut. Logaritma dianggap cukup lama bahkan pada FPU, jadi saya mengganti logaritma nyata dengan pendekatan linier piecewise, yang mudah didapat, karenaformat untuk mewakili angka di float32 . Bit yang paling signifikan adalah sebuah tanda. 8 bit berikutnya adalah eksponen biner ditambah 127. Bit yang tersisa adalah bagian fraksional dari mantissa meskipun fakta bahwa bagian integer adalah 1 (kami menghilangkan nuansa angka denormalized untuk kesederhanaan). Jadi, setelah memilih eksponen dari float32 dan meraih beberapa bit paling signifikan dari mantissa, Anda bisa mendapatkan perkiraan yang baik dari logaritma. Menggunakan tabel yang disiapkan sebelumnya, kami mengonversi angka yang dihasilkan menjadi kode RGB untuk ditampilkan pada LCD. Ternyata skala warna 90 atau 60 desibel. Level volume yang sesuai dengan nol skala ini dapat disesuaikan dengan menekan joystick ke atas dan ke bawah.Kami menampilkan gambar - tentang manfaat membaca lembar data
Sekarang kita hanya perlu menampilkan gambar dan menghidupkan kembali 'air terjun' kita. Cara mudah untuk melakukan ini adalah menyimpan gambar dari seluruh layar dalam buffer, memperbaruinya di sana dan menggambar ulang setiap kali data baru muncul. Tidak hanya solusi ini sangat tidak efisien, kami juga tidak memiliki cukup memori untuk menyimpan seluruh gambar. Tampaknya LCD itu sendiri memiliki memori yang cukup untuk ini, dan seharusnya dapat melakukan sesuatu yang menarik dengannya. Memang, studi tentang lembar datadiizinkan untuk mendeteksi perintah pengguliran yang tidak digunakan sampai sekarang, yang memungkinkan Anda untuk secara dinamis mengubah cara memori pengontrol LCD ditampilkan di layar. Bayangkan memori itu adalah selotip tertutup cincin yang Anda lihat di bawah kaca layar. Perintah Vertical Scrolling Start Address (0x37) memungkinkan Anda untuk mengatur posisi pada pita yang sesuai dengan tepi atas layar. Jadi, yang kita butuhkan untuk menghidupkan kembali 'air terjun' adalah merekam spektrum baru di posisi ini dan gulir melalui pita memori. Kode yang sesuai ditambahkan ke driver LCD, dipinjam dari Peter Drescher yang memiliki reputasi baik , dan diadaptasi seperti dijelaskan di sini. Satu-satunya kelemahan dari pendekatan ini: menggulir hanya berfungsi di sepanjang sisi panjang layar. Dengan demikian, hanya sisi pendek yang tersedia untuk output spektrum.12 ?
Mari beralih ke aplikasi praktis perangkat kita. Hal pertama yang mudah dilihat pada spektrum adalah harmonik, yaitu frekuensi yang merupakan kelipatan dari frekuensi fundamental. Terutama banyak dari mereka dalam suara. Ada juga suara yang membuat alat musik. Sangat mudah untuk memahami mengapa not oktaf tetangga berbeda dalam frekuensi 2 kali: maka not oktaf yang lebih tinggi bertepatan dalam frekuensi dengan harmonik kedua dari not oktaf rendah. Mereka mengatakan bahwa pada saat yang sama mereka terdengar "serempak." Agak lebih sulit untuk memahami mengapa ada 12 nada dalam satu oktaf - tujuh utama (tombol putih pada keyboard piano) ditambah 5 tambahan (tombol hitam). Catatan tambahan ditunjukkan oleh catatan utama dengan karakter tajam dan datar, meskipun pada kenyataannya tidak ada perbedaan antara mereka dan catatan utama - semua 12 catatan membentuk perkembangan geometris sehinggabahwa rasio frekuensi antara not-not yang berdekatan sama dengan akar dari tingkat ke-12 dari 2. Arti dari pembagian oktaf ini menjadi not adalah bahwa untuk not apa pun ada not lain yang berbeda frekuensinya satu setengah kali - kombinasi ini disebut yang kelima. Catatan yang membentuk nada kelima berbunyi serempak karena harmonik kedua dari satu not bertepatan dalam frekuensi dengan harmonik ketiga dari not lainnya. Foto di bawah ini menunjukkan spektrum catatan Do and Sol, membentuk kelima, harmonik yang cocok dilingkari dengan warna kuning.membentuk yang kelima, harmonik yang cocok dilingkari dengan warna kuning.membentuk yang kelima, harmonik yang cocok dilingkari dengan warna kuning.
Bagaimana catatan 12? Karena catatan membentuk progres geometris, kita beralih ke logaritma. Dalam (1,5) / ln (2) = 0,58496 ... Nilai dekat diperoleh untuk fraksi 7/12 = 0,583 ... Artinya, tujuh setengah-nada (interval antara not yang berdekatan) ternyata sangat dekat dengan quint - 1,498. Menariknya, fraksi 31/53 = 0,58491 .. memberikan akurasi yang jauh lebih besar, sehingga yang kelima berbeda dari 1,5 hanya di tempat desimal kelima. Fakta ini tidak luput dari perhatian, tetapi alat musik dengan 53 not dalam satu oktaf tidak menerima distribusi. Mereka sulit diatur, mereka sulit dimainkan, dan persentase orang yang bisa merasakan perbedaan dengan alat konvensional semakin kecil.Kode sumber
Kebohongan di sini . Untuk kompilasi IAR Embedded Workbench untuk ARM 7.50.2 digunakan. Tidak ada perpustakaan lain yang diperlukan untuk kompilasi. Source: https://habr.com/ru/post/id391311/
All Articles