2026年7月22日 星期三

【Arduino UNO Q 專欄06】- 關鍵字偵測

 Jack OmniXRI, 2026/07/15

Arduino-UNO-Q-06_Fig00

大家還記得 2014 年 Amazon 推出智慧音箱 Echo 系列時,只要說一句「Hi Alexa」之後,就能接著以口語描述方式進行查詢、網購、訂位甚至控制家電等工作。這樣的操作方式令人感到神奇,從此開啟了智慧音箱百花齊放、電腦語音辨識的新人機介面世代。

不過這樣的操作方式一開始很令人感到困惑,為什麼電腦都已可以辨識完整句子,還要先說「Hi, Alexa」這樣的關鍵字(Keyword)呢?其中最主要的因素是為了省錢、省通訊流量及省推論計算時間。因為接收端通常是由一個幾塊美金的單晶片(MCU)構成,實在難以處理複雜的語音、語意辨識,若24小時每分每秒把接收到的語音資料往雲端伺服器送,那麼整個通訊頻寬及伺服器計算能力就會馬上被癱瘓掉,所以當接受到語音且是特定關鍵字後再將完整句子送到雲端進行分析就能免除超過99%的浪費。

為滿足上述「關鍵字偵測(Keyword Spotting, KWS)」需求,原則上只要使用 Arm Cortex-M4 以上等級 MCU 就足夠處理,當然使用 Arduino UNO Q [1] (以下簡稱 UNO Q)內建 Arm Cortex-A53 + Cortex-M33 更是可以輕鬆解決。本文就將帶著大家了解如何使用 UNO Q 來完成「關鍵字偵測」。

1. UNO Q 關鍵字偵測軟硬體架構

 Arduino App Lab [2](以下簡稱 App Lab)中有自帶一個「Hey Arduino! [3]」的關鍵字偵測範例。想要完成關鍵字偵測,在硬體部份首先要有收音(錄音)裝置(如麥克風),如 Fig. 1 下半部所示,由於 UNO Q 板子上並沒有自帶實體麥克風(如電容式或微機電式),也沒有傳統 3.5mm 的立體聲耳機麥克插座,所以外接麥克風只能選用 USB 接頭型式,再插入 USB Type C 集線器(Hub)。此時 Hub 必須採用外接電源,以免 UNO Q 供電不足無法順利啟動。根據原廠建議要使用 +5V / 3A ,如果臨時找不到,用 2A 也可以。另外由於 UNO Q 的 Type C 接頭已被 Hub 佔用,所以筆電上執行的 App Lab 只能透過 WiFi 遠端連線操作了。

在軟體架構上,如 Fig. 1 上半部所示,在「Hey Arduino! [3]」這個範例中,主要會使用到 App Lab 的 「keyword Spotting」磚塊(Brick),它負責接收和辨識關鍵字「Hey, Arduino」,當 Python 程式辨識到結果後,會透過橋接程式(Bridge)通知 MCU 產生 LED 點矩陣動畫。

Arduino-UNO-Q-06_Fig01
Fig. 1 Arduino UNO Q 關鍵字偵測軟硬體架構圖。(OmniXRI整理製作,2026/07/15)

2. 和 UNO Q 說嘿

為了方便測試,開啟 App Lab 後,如 Fig. 2 所示,首先點擊左側範例程式(Examples),找到「Hey, Arduino!」範例,點擊進入後按右上角執行(RUN)就可執行。

執行後,UNO Q 右下角 LED 點矩陣會出現一個空心愛心符號,當對著麥克風說「Hey Arduino」或「Hi Arduino」時,愛心圖案會向逐步外擴張成全亮模式(動畫模式)。經實驗用不同聲速、聲調、節奏大部份都能正確辨識,故意使用其它文字測試則不會反應,表示辨識正確。但要注意,實驗時必須等動畫結束才能接受下一個語音。

Arduino-UNO-Q-06_Fig02
Fig. 2 App Lab 範例「Hey, Arduino!」執行步驟及結果圖。(OmniXRI整理製作,2026/07/15)

接下來簡單說明主要程式內容。首先是 Python 部份main.py 如下程式所示,簡單宣告及配置關鍵字偵測磚塊並指定 MCU 橋接程式即可。

# main.py # SPDX-FileCopyrightText: Copyright (C) Arduino s.r.l. and/or its affiliated companies # # SPDX-License-Identifier: MPL-2.0 from arduino.app_utils import * from arduino.app_bricks.keyword_spotting import KeywordSpotting # 導入關鍵字偵測磚塊 # 當偵測到關鍵字時工作函式 def on_keyword_detected(): """Callback function that handles a detected keyword.""" Bridge.call("keyword_detected") # 使用橋接器呼叫 MCU 對應函式工作 spotter = KeywordSpotting() # 宣告一組關鍵字偵測磚塊 spotter.on_detect("hey_arduino", on_keyword_detected) # 指定當偵測到關鍵字時對應的工作函式 App.run()

接著是 MCU 部份 C++ 程式 sketch.ino ,主要定義好要給 Python 呼叫的橋接程式和 LED 點矩陣動畫程式,如下所示。

// sketch.ino // SPDX-FileCopyrightText: Copyright (C) Arduino s.r.l. and/or its affiliated companies // // SPDX-License-Identifier: MPL-2.0 #include <Arduino_LED_Matrix.h> // 導入 LED 矩陣控制函式 #include <Arduino_RouterBridge.h> // 導入 Python 橋接函式 #include "heart_frames.h" // 導入愛心動畫定義內容 Arduino_LED_Matrix matrix; void setup() { // 初始化 LED 矩陣函式,清除所有內容,顯示靜態空心愛心圖案 matrix.begin(); matrix.clear(); matrix.loadFrame(HeartStatic); // 初始化橋接函式,並宣告給 Python 呼叫的函式名稱為 keyword_detected,而 MCU 點矩陣動畫的函式為 wake_up Bridge.begin(); Bridge.provide("keyword_detected", wake_up); } void loop() {} void wake_up() { matrix.loadSequence(HeartAnim); // 載入動畫愛心圖案 matrix.playSequence(); // 執行播放動作 delay(1000); // 延時一秒 matrix.loadFrame(HeartStatic); // 載入靜態愛心圖案 }

LED 點矩陣靜態及動畫圖案內容定義 heart_frame.h 如下所示,如果想要更進一步了解如何設計不一樣的顯示效果,可參考【Arduino UNO Q 專欄03】- 板載點矩陣LED應用 [4]

// heart_frame.h /* * SPDX-FileCopyrightText: Copyright (C) Arduino s.r.l. and/or its affiliated companies * * SPDX-License-Identifier: MPL-2.0 */ const uint32_t HeartStatic[4] = { 0x00006c04, 0x90208088, 0x02800800, 0x00000000, }; const uint32_t HeartAnim[][5] = { {0x1dc11108, 0x08404104, 0x04401400, 0x40000000, 55}, {0x3fe31198, 0x0cc06306, 0x0c603600, 0xe0000000, 55}, {0x3fe31198, 0x0cc06306, 0x0c603600, 0xe0000000, 55}, {0x7ff711f8, 0x0fc07707, 0x1c707701, 0xf0000000, 55}, {0xffff11f8, 0x0fc07f07, 0xbc78f783, 0xf8000000, 55}, {0xffff11f8, 0x0fc07f07, 0xfc7ff7ef, 0xfe000000, 55}, {0xffff11f8, 0x0fc07f07, 0xfc7ff7ff, 0xff000000, 55}, {0xffff11f8, 0x0fc07f07, 0xfc7ff7ff, 0xff000000, 55}, };

3. 如何變更自定義關鍵字

目前這個範例只能偵測「Hey Arduino」這個關鍵字,實務上沒有太多意義。要如何改成自定義關鍵字呢?可以用國語、台語、客家話甚至是原住民語嗎?當然沒問題,只要搭配 Edge Impulse Studio [5] 這個免費工具就能完成,從語音資料集收集、模型選用、訓練、優化到部署皆包含在內。更重要的是 Edge Impulse 及 Arduino 都已在 2025 被高通(Qualcomm)收購,所以相互的支援性更是輕鬆搞定。

這裡受限篇幅就先不介紹完整訓練方式,大家可參考 Edge Impulse 給出的關鍵字偵測教學[6],完成自定義關鍵字訓練。

完成訓練後最重要步驟是部署(Depoly),如 Fig. 3 所示,要先選擇開發板為 Arduino UNO Q,預設輸出會量化成 INT8 格式,若不在意推論時間需更高精度表現時可選擇未量化 FP32 格式。接著就可按下「建置(Build)」,完成後會產生一個名為「專案名稱-linux-aarch64-v版本號-impulse-#1.eim」(例:kws_omnixri-linux-aarch64-v3-impulse-#1.eim)並下載到個人電腦上。每次重新建置版本號會自動加1,方便管理。

Arduino-UNO-Q-06_Fig03
Fig. 3 Edge Impulse Studio 部署及建置 UNO Q 格式模型檔。(OmniXRI整理製作,2026/07/15)

由於剛才實驗時是直接執行範例程式,無法修改模型路徑,所以必須先按「執行(RUN)」旁的「複製(Clone)」產生新的專案,假設名稱為 copy-of-hey-arduino。

Arduino-UNO-Q-06_Fig04
Fig. 4 Windows 命令列執行步驟及遠端修改。(OmniXRI整理製作,2026/07/15)

如 Fig. 4 所示,啟動 Windows Cmd,將模型檔(*.eim)複製到 UNO Q 指定路徑下。由於 UNO Q 專案設定檔 app.yaml 無法在 App Lab 視窗操作模式下修改,所以須透過 ssh 遠端進入手動修改。完成後就能以新的自定義關鍵字偵測模型替代原有模型。完整的操作步驟及內容如下所示。

1. 進入命令列模式,將 vx 版本模型(x表示版號) `*.eim` 模型檔複製到遠端 Arduino UNO Q Edge Impulse 模型專用存放路徑 ei-models 下。 scp C:\Users\jack_\Downloads\kws_omnixri-linux-aarch64-vx-impulse-#1.eim arduino@192.168.2.xxx:/home/arduino/.arduino-bricks/ei-models 2. ssh 連線到 UNO Q,開發板名稱(固定為 arduino)@WiFi IP ssh arduino@192.168.2.xxx 3. 檢查模型是否已存入(可略) ls /home/arduino/.arduino-bricks/ei-models 4. 編輯專案設定檔 app.yaml ,假設專案名稱為 copy-of-hey-arduino nano ~/ArduinoApps/copy-of-hey-arduino/app.yaml 5. 新增 keyword spotting 的模型路徑,將原 - arduino:keyword_spotting 修改如下。 - arduino:keyword_spotting: { variables: { EI_KEYWORD_SPOTTING_MODEL: /home/arduino/.arduino-bricks/ei-models/kws_omnixri-linux-aarch64-vx-impulse-#1.eim } } 6. 按 Ctrl+O 存檔, Ctrl+X 離開,完成模型檔配置。

最後重新回到 App Lab ,其它程式都不用修改,按下執行(RUN)就能得到自定義關鍵字的操作。

結語

關鍵字偵測是語音辨識的起點,只要把基礎建立好,接下來就能挑戰多種聲音的分類問題,讓語音命令、環境音分類、機械異常音、鳥叫分析等各種聲音應用都能被順利解決。此次已初步認識 App Lab Brick 如何結合 Edge Impulse Studio 產生的模型讓應用能擴大,後續會再介紹更多不同的智慧感測器應用敬請期待。

本文同步發表在 MakerPRO

參考文獻

[1] Arduino, Document - Hardware - UNO Q - UNO Q User Manual
https://docs.arduino.cc/tutorials/uno-q/user-manual/
[2] Arduino, Document - Software - APP Lab - Tutorial: Using Arduino App Lab
https://docs.arduino.cc/software/app-lab/getting-started/quickstart/
[3] Arduino, Github - App Lab - Examples - Hey Arduino!
https://github.com/arduino/app-bricks-examples/tree/main/examples/common/keyword-spotting
[4] 許哲豪,【Arduino UNO Q 專欄03】- 板載點矩陣LED應用
https://omnixri.blogspot.com/2026/06/arduino-uno-q-03-led.html
[5] Edge Impulse, Document
https://docs.edgeimpulse.com
[6] Edge Impulse, Tutorials - end to end - keyword spotting
https://docs.edgeimpulse.com/tutorials/end-to-end/keyword-spotting

延伸閱讀

[A] 許哲豪,歐尼克斯實境互動工作室【系列發文】 - Arduino UNO Q 專欄
https://hackmd.io/@OmniXRI-Jack/series_articles#Arduino-UNO-Q-專欄

沒有留言:

張貼留言

【頂置】簡報、源碼、系列文快速連結區

常有人反應用手機瀏覽本部落格時常要捲很多頁才能找到系列發文、開源專案、課程及活動簡報,為了方便大家快速查詢,特整理連結如下,敬請參考! Edge AI Taiwan 邊緣智能交流區 全像顯示與互動交流區 台科大(NTUST)邊緣人工智慧實務(2026) 南開科大...