Manufaktur industri
Industri Internet of Things | bahan industri | Pemeliharaan dan Perbaikan Peralatan | Pemrograman industri |
home  MfgRobots >> Manufaktur industri >  >> Manufacturing Technology >> Proses manufaktur

Deteksi Kata Kunci TinyML untuk Mengontrol Lampu RGB

Komponen dan persediaan

Arduino Nano 33 BLE Sense
× 1

Aplikasi dan layanan online

Edge Impulse Studio

Tentang proyek ini

Premis

Pembelajaran mesin di edge sangat berguna untuk membuat perangkat yang dapat menyelesaikan tugas "cerdas" dengan pemrograman dan diagram alur logis yang jauh lebih sedikit dibandingkan dengan kode tradisional. Itu sebabnya saya ingin memasukkan deteksi kata kunci mutakhir yang dapat mengenali kata-kata tertentu dan kemudian melakukan tugas berdasarkan apa yang dikatakan.

Perangkat Keras

Proyek ini hanya memiliki satu komponen:Arduino Nano 33 BLE Sense. Keajaiban yang sebenarnya terjadi dalam model pembelajaran mesin. Arduino Nano 33 BLE Sense penuh dengan sensor, termasuk mikrofon, IMU 9-sumbu, sensor lingkungan, dan sensor isyarat/kedekatan/warna/cahaya sekitar (APDS-9960). Mikrokontroler di dalamnya adalah nRF52840 yang berjalan pada 64MHz dan berisi memori flash 1MB dan RAM 256KB. Proyek ini juga menggunakan LED RGB onboard untuk menampilkan warna saat ini.

Menyiapkan Impuls Tepi

Saya mulai dengan membuat proyek baru di Edge Impulse dan kemudian menginstal alat Edge Impulse CLI. Untuk instruksi lebih lanjut tentang cara melakukannya, kunjungi halaman instruksi instalasi. Ini memungkinkan Arduino Nano berkomunikasi dengan layanan cloud untuk menerima perintah dan mengirim data sensor secara otomatis. Saya mengunduh firmware Edge Impulse terbaru dan mem-flash-nya ke papan dengan mengklik dua kali tombol reset untuk membuatnya masuk ke mode bootloader. Kemudian saya menjalankan flash_windows.bat untuk mentransfernya.

Di atas command prompt saya menjalankan edge-impulse-daemon dan mengikuti wizard untuk mengaturnya. Sekarang Nano muncul di daftar perangkat proyek, yang memungkinkan sampel diambil dan diunggah sebagai bagian dari set data pelatihan/pengujian.

Mengumpulkan Sampel

Melatih model pembelajaran mesin membutuhkan data, dan cukup banyak. Saya ingin memiliki mode berikut untuk strip LED RGB:

  • Aktif
  • Nonaktif
  • Merah
  • Hijau
  • Biru

Saya mendapat sekitar 1 menit suara untuk setiap mode di mana saya berulang kali mengucapkan kata pada interval 1-2 detik dan membaginya.

Tetapi memiliki sampel ini saja tidak cukup, karena kebisingan latar belakang dan kata-kata lain akan memberikan pembacaan yang salah. Untungnya, Edge Impulse sudah menyediakan set data bawaan untuk kebisingan dan kata-kata 'tidak dikenal', jadi saya menggunakan alat "Unggah Data yang Ada" untuk mengunggah file audio ini ke dalam data pelatihan.

Akhirnya, saya menyeimbangkan kembali dataset agar masing-masing memiliki pembagian 80-20 yang direkomendasikan untuk data pelatihan dan pengujian.

Melatih Model

Sekarang dipersenjatai dengan satu jam data pelatihan dan banyak label, sudah waktunya untuk melatih seorang model. Impuls yang saya rancang mengambil audio sebagai data deret waktu dengan ukuran jendela 1 detik dan peningkatan jendela 500 ms. Kemudian melewati blok MFCC ke blok jaringan saraf Keras.

Blok MFCC memungkinkan Anda untuk mengonfigurasi bagaimana audio akan diproses, bersama dengan spektogram yang menunjukkan frekuensi secara visual.

Saya meninggalkan pengaturan jaringan saraf sebagai sebagian besar default, tetapi membuat beberapa modifikasi juga. Pertama, saya mengubah ambang batas kepercayaan minimum dari 0,80 menjadi 0,70, dan menambahkan sedikit augmentasi data dalam bentuk pita waktu noise dan masking tambahan. Ini membantu NN untuk menghindari model yang terlalu pas, karena memiliki data yang lebih beragam untuk dikerjakan.

Menerapkan pada Arduino Nano 33 BLE Sense

Arduino Nano 33 BLE Sense bertindak sebagai mikrofon yang selalu aktif yang terus-menerus mengambil sampel audio dan mendeteksi jika salah satu kata kunci telah diucapkan. Setelah ditemukan, kata kunci diubah menjadi indeks yang digunakan untuk memecahkan kode warna yang diinginkan. Untuk kata kunci on atau off, LED diatur ke hitam atau abu-abu muda.

Saya mengunduh model sebagai pustaka dan menambahkannya ke Arduino IDE, lalu mengkompilasi dan mem-flash kode ke Nano.

Kode

  • Deteksi Kata Kunci RGBLED
RGBLEDDeteksi Kata KunciC/C++
/* Contoh Edge Impulse Arduino * Hak Cipta (c) 2020 EdgeImpulse Inc. * * Dengan ini izin diberikan, gratis, kepada siapa pun yang mendapatkan salinan * perangkat lunak ini dan file dokumentasi terkait ("Perangkat Lunak"), untuk menangani * dalam Perangkat Lunak tanpa batasan, termasuk namun tidak terbatas pada hak * untuk menggunakan, menyalin, memodifikasi, menggabungkan, menerbitkan, mendistribusikan, mensublisensikan, dan/atau menjual * salinan Perangkat Lunak, dan untuk mengizinkan orang-orang yang memiliki Perangkat Lunak * disediakan untuk melakukannya, tunduk pada ketentuan berikut:* * Pemberitahuan hak cipta di atas dan pemberitahuan izin ini harus disertakan dalam * semua salinan atau sebagian besar Perangkat Lunak. * * PERANGKAT LUNAK INI DISEDIAKAN "SEBAGAIMANA ADANYA", TANPA JAMINAN APA PUN, TERSURAT MAUPUN * TERSIRAT, TERMASUK NAMUN TIDAK TERBATAS PADA JAMINAN DIPERDAGANGKAN, * KESESUAIAN UNTUK TUJUAN TERTENTU DAN TANPA PELANGGARAN. DALAM KONDISI APAPUN * PENULIS ATAU PEMEGANG HAK CIPTA TIDAK BERTANGGUNG JAWAB ATAS KLAIM, KERUSAKAN ATAU TANGGUNG JAWAB * LAINNYA, BAIK DALAM TINDAKAN KONTRAK, KERUGIAN ATAU LAINNYA, YANG TIMBUL DARI, * DARI ATAU SEHUBUNGAN DENGAN PERANGKAT LUNAK ATAU LAINNYA DEALINGS DI * PERANGKAT LUNAK. */// Jika memori target Anda terbatas, hapus makro ini untuk menghemat 10K RAM#define EIDSP_QUANTIZE_FILTERBANK 0/** * Tentukan jumlah irisan per model jendela. Misalnya. jendela model 1000 ms * dengan irisan per jendela model disetel ke 4. Menghasilkan ukuran irisan 250 ms. * Untuk info lebih lanjut:https://docs.edgeimpulse.com/docs/continuous-audio-sampling */#define EI_CLASSIFIER_SLICES_PER_MODEL_WINDOW 3/* Termasuk ------------------- --------------------------------------------- */#include #include #include 
#define CONFIDENCE_THRESHOLD 0.7static const uint32_t colors[] ={0x00ff0000, 0x0000ff00, 0x000000ff}; // merah, hijau, blueenum Tindakan { LED_ON =1, LED_OFF =0, LED_RED =2, LED_GREEN =3, LED_BLUE =4, NONE =5};enum Fungsi{ CHANGE_LED_ON_OFF =0, CHANGE_LED_COLOR =1, CHANGE_LED_NONE =2}; static const uint8_t redPin =22, greenPin =23, bluePin =24;const std::map actionToFunctionMap ={ {LED_ON, CHANGE_LED_ON_OFF}, {LED_OFF, CHANGE_LED_ON_OFF}, {LED_RED, CHANGE_LED_LED_COLGEN} }, {LED_BLUE, CHANGE_LED_COLOR}, {NONE, CHANGE_LED_NONE}};const std::map labelToActionMap ={{"on", LED_ON}, {"off", LED_OFF}, {"red" , LED_RED}, {"green", LED_GREEN}, {"blue", LED_BLUE}, {"unknown", NONE}, {"noise", NONE}};/** Audio buffer, pointer, dan selector */typedef struct { ditandatangani pendek *buffer[2]; char buf_select yang tidak ditandatangani; char buf_ready yang tidak ditandatangani; int buf_count yang tidak ditandatangani; unsigned int n_samples;} inference_t;inferensi_t inferensi statis;statis bool record_ready =false;statis bertanda pendek *sampleBuffer;statis bool debug_nn =false; // Setel ini ke true untuk melihat mis. fitur yang dihasilkan dari raw signalstatic int print_results =-(EI_CLASSIFIER_SLICES_PER_MODEL_WINDOW);/** * @brief Arduino setup function */void setup(){ // letakkan kode setup Anda di sini, untuk dijalankan sekali:Serial.begin(115200); Serial.println("Inferensi Ujung Impuls"); setPixelColor(0xaeae00); // ringkasan pengaturan inferensi (dari model_metadata.h) ei_printf("Setelan inferensi:\n"); ei_printf("\tInterval:%.2f ms.\n", (mengambang)EI_CLASSIFIER_INTERVAL_MS); ei_printf("\tUkuran bingkai:%d\n", EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE); ei_printf("\tPanjang sampel:%d md.\n", EI_CLASSIFIER_RAW_SAMPLE_COUNT / 16); ei_printf("\tJumlah kelas:%d\n", sizeof(ei_classifier_inferencing_categories) / sizeof(ei_classifier_inferencing_categories[0])); run_classifier_init(); if (microphone_inference_start(EI_CLASSIFIER_SLICE_SIZE) ==false) { ei_printf("ERR:Gagal menyiapkan pengambilan sampel audio\r\n"); kembali; }}/** * @brief fungsi utama Arduino. Menjalankan loop inferensi. */void loop(){ bool m =microphone_inference_record(); if (!m) { ei_printf("ERR:Gagal merekam audio...\n"); kembali; } sinyal_t sinyal; signal.total_length =EI_CLASSIFIER_SLICE_SIZE; signal.get_data =µphone_audio_signal_get_data; ei_impulse_result_t hasil ={0}; EI_IMPULSE_ERROR r =run_classifier_continuous(&sinyal, &hasil, debug_nn); if (r !=EI_IMPULSE_OK) { ei_printf("ERR:Gagal menjalankan classifier (%d)\n", r); kembali; } if (++print_results>=(EI_CLASSIFIER_SLICES_PER_MODEL_WINDOW)) { // print prediksi ei_printf("Prediksi "); ei_printf("(DSP:%d ms., Klasifikasi:%d ms., Anomali:%d ms.)", result.timing.dsp, result.timing.classification, result.timing.anomaly); ei_printf(":\n"); for (size_t ix =0; ix  CONFIDENCE_THRESHOLD) { performAction(result.classification[ix].label); } ei_printf(" %s:%.5f\n", result.classification[ix].label, result.classification[ix].value); }#jika EI_CLASSIFIER_HAS_ANOMALY ==1 ei_printf(" skor anomali:%.3f\n", result.anomaly);#endif print_results =0; }}void setPixelColor(uint32_t c){ analogWrite(redPin, 255 - (c>> 16)); analogWrite(greenPin, 255 - ((c>> 8) &0xff)); analogWrite(bluePin, 255 - (c &0xff));}void performAction(const char*classificationLabel){ auto itr =labelToActionMap.find(classificationLabel); if(itr ==labelToActionMap.end()) kembali; auto itr2 =actionToFunctionMap.find(itr->second); if(itr2 ==actionToFunctionMap.end()) kembali; switch(itr2->second) { case CHANGE_LED_ON_OFF:setPixelColor((itr->second) ? 0x5c5c5c :0x00); merusak; case CHANGE_LED_COLOR:{ uint32_t pixelColor =colors[itr->second - 2]; setPixelColor(pixelColor); } merusak; kasus CHANGE_LED_NONE:istirahat; }}/** * @brief Printf function menggunakan vsnprintf dan output menggunakan Arduino Serial * * @param[in] format Variable argument list */void ei_printf(const char *format, ...) { static char print_buf[1024] ={ 0 }; argumen va_list; va_start(args, format); int r =vsnprintf(print_buf, sizeof(print_buf), format, argumen); va_end(args); if (r> 0) { Serial.write(print_buf); }}/** * @brief PDM buffer full callback * Dapatkan data dan panggilan audio thread callback */static void pdm_data_ready_inference_callback(void){ int bytesAvailable =PDM.available(); // baca ke buffer sampel int byteRead =PDM.read((char *)&sampleBuffer[0], bytesAvailable); if (record_ready ==true) { for (int i =0; i> 1; i++) { inference.buffers[inference.buf_select][inference.buf_count++] =sampleBuffer[i]; if (inference.buf_count>=inference.n_samples) { inference.buf_select ^=1; inference.buf_count =0; inferensi.buf_ready =1; } } }}/** * @brief Init inferencing struct dan setup/start PDM * * @param[in] n_samples N sampel * * @return { description_of_the_return_value } */static bool microphone_inference_start(uint32_t n_samples){ inference.buffers 0] =(pendek ditandatangani *)malloc(n_samples * sizeof(pendek ditandatangani)); if (inference.buffers[0] ==NULL) { mengembalikan salah; } inference.buffers[1] =(bertanda pendek *)malloc(n_samples * sizeof(bertanda pendek)); if (inference.buffers[0] ==NULL) { gratis(inference.buffers[0]); kembali salah; } sampleBuffer =(bertanda pendek *)malloc((n_samples>> 1) * sizeof(bertanda pendek)); if (sampleBuffer ==NULL) { free(inference.buffers[0]); gratis(inferensi.buffer[1]); kembali salah; } inference.buf_select =0; inference.buf_count =0; inference.n_samples =n_samples; inferensi.buf_ready =0; // mengkonfigurasi data menerima panggilan balik PDM.onReceive(&pdm_data_ready_inference_callback); // opsional mengatur gain, default ke 20 PDM.setGain(80); PDM.setBufferSize((n_samples>> 1) * sizeof(int16_t)); // inisialisasi PDM dengan:// - satu saluran (mode mono) // - laju sampel 16 kHz if (!PDM.begin(1, EI_CLASSIFIER_FREQUENCY)) { ei_printf("Gagal memulai PDM!"); } record_ready =benar; return true;}/** * @brief Tunggu data baru * * @return True ketika selesai */static bool microphone_inference_record(void){ bool ret =true; if (inference.buf_ready ==1) { ei_printf( "Error sample buffer overrun. Kurangi jumlah irisan per model jendela " "(EI_CLASSIFIER_SLICES_PER_MODEL_WINDOW)\n"); ret =salah; } while (inference.buf_ready ==0) { delay(1); } inference.buf_ready =0; return ret;}/** * Dapatkan data sinyal audio mentah */static int microphone_audio_signal_get_data(size_t offset, size_t length, float *out_ptr){ numpy::int16_to_float(&inference.buffers[inference.buf_select ^ 1][offset], out_ptr , panjang); return 0;}/** * @brief Hentikan PDM dan lepaskan buffer */static void microphone_inference_end(void){ PDM.end(); gratis(inference.buffers[0]); gratis(inferensi.buffer[1]); gratis(sampleBuffer);}#jika !defined(EI_CLASSIFIER_SENSOR) || EI_CLASSIFIER_SENSOR !=EI_CLASSIFIER_SENSOR_MICROPHONE#error "Model tidak valid untuk sensor saat ini."#endif

Proses manufaktur

  1. tips dan tren keamanan IIoT untuk tahun 2020
  2. Cloud and edge computing untuk IoT:sejarah singkat
  3. Mengapa komputasi tepi untuk IoT?
  4. Kontrons KBox A-150-WKL untuk Aplikasi IoT Edge Data-Intensive
  5. Manfaat Edge Computing untuk AI Crystallizing
  6. Empat Langkah untuk Memastikan Keberhasilan di Edge Computing
  7. Microsoft Meluncurkan Azure Edge Zones Untuk Aplikasi 5G
  8. Perlunya Open Source di Edge (eBook)
  9. Sistem Deteksi Kimia untuk Tingkat Konsentrasi Rendah
  10. 3 Alasan Memelihara Perangkat Deteksi Gas