《ESP32 入門》ESP32 聲音感測模組教學

學習用 ESP32 NodeMCU-32S 搭配聲音感測模組,從類比讀取、數位觸發到拍手聲控 LED,四個範例帶你快速上手聲音偵測應用。

《ESP32 入門》ESP32 聲音感測模組教學

你是否想過讓 ESP32 能「聽見」周遭的聲音?不管是偵測拍手來開關燈、監測環境噪音,還是做一個簡易的聲控裝置,聲音感測模組都是入門的好選擇。這篇教學會帶你從零開始,用 ESP32 NodeMCU-32S 搭配聲音感測模組,完成類比與數位雙模式的聲音偵測實作。


聲音偵測模組介紹

以我們常見的聲音偵測模組為例,核心元件是一顆駐極體電容麥克風(Electret Condenser Microphone),搭配 LM393 比較器晶片,提供類比輸出(AO)數位輸出(DO)兩種訊號。

模組腳位說明

腳位 功能說明
VCC(+) 電源正極,接 3.3V 或 5V
GND(G) 電源負極,接地
AO 類比輸出,輸出與音量成比例的電壓值
DO 數位輸出,當聲音超過門檻值時輸出 LOW

模組特性

  • 工作電壓:3.3V ~ 5V(與 ESP32 的 3.3V 相容)
  • 藍色可變電阻(VR1):用來調整 DO 的觸發靈敏度門檻值
  • LED1(電源指示燈):模組通電時亮起
  • LED2(觸發指示燈):當偵測到的聲音超過門檻值時亮起
小提醒:LM393 適合用來偵測「有沒有聲音」或「聲音大不大」,但它不是錄音用的麥克風模組,無法擷取音訊波形。如果你需要錄音功能,請參考 INMP441 或 MAX9814 等模組。

所需材料

品項 數量
ESP32 NodeMCU-32S 開發板 1
LM393聲音感測模組 1
麵包板 1
杜邦線(公對母) 4 條
Micro USB 傳輸線 1
LED(選用,用於聲控展示) 1
220Ω 電阻(選用,搭配 LED) 1
NodeMCU-32S 相容版本 ESP32開發板 WiFi 藍牙 可用Arduino IDE
全腳位引出,還保持迷你的身型,插上麵包後還能插杜邦線,真的是太棒了! 和NodeMCU V2幾乎一樣尺寸! 有5V供電輸出,非常方便! 有了ESP32開發板,真的可以忘記原來的那些Arduino板子了! 可以用Arduino IDE開發,但效能更強大,還內建WiFi 傑森實測記錄,大家可以到 F 粉 絲 團 B 看貼文哦! ESP32-D0WDQ6 內置兩個低功耗 Xtensa® 32-bit LX6 MCU。片上存儲包括: • 448 KB 的 ROM,用於程序啟動和內核功能
高感度 聲音感測模組 聲音感測器
用於聲音檢測 模組有2個輸出: 1、AO,類比量輸出,即時輸出麥克風的電壓信號 2、DO,當聲音強度到達某個閥值時,輸出高低電平信號,【閥值-靈敏度可以通過電位器調節】 模組特點: 2、有3mm的安裝螺絲孔 3、使用5v直流電源供電 4、有模擬量輸出 5、有閥值翻轉電平輸出 6、高感度麥克風,靈敏度高。 7、有電源指示燈 8、比較器輸出有指示燈
聲音感測模組 微雪原廠 聲控模組 聲音檢測 LM386模組 敏感度極佳
傑森實測,敏感度真的比幾十塊的那些好太多了!值得! 產品描述: 採用音頻處理芯片LM386對音頻信號進行200倍放大靈敏度可調信號輸出指示 產品參數: 麥克風的靈敏度:52dB頻段:50Hz ~ 20KHz工作電壓:3.3V ~ 5.3V固定孔尺寸:2.0mm 主要用途: 音頻放大、檢測環境聲音的有無或判斷聲音強度的大小(不能測量具體的分貝數)。 接口說明:(以接入MCU為例) VCC:接3.3V ~ 5.3VGND:接GNDAOUT:接MCU.IO (模擬量輸出)DOUT:接MCU.IO (
ESP32S擴展板 適用於Nodemcu-32s 38Pin全引出
※ 不含ESP32S開發板,需另購! ESP32S專用擴展板 適用於Nodemcu-32s,其它型號都不相容哦!請留意。 38Pin全引出,無敵方便!

接線方式

基本接線(類比 + 數位讀取)

KY-038 腳位 ESP32 腳位 說明
VCC(+) 3.3V 供電
GND(G) GND 接地
AO GPIO 34 類比輸入(ADC1_CH6)
DO GPIO 27 數位輸入
注意:ESP32 的 ADC2 在啟用 Wi-Fi 時無法使用,所以類比輸入請使用 ADC1 的腳位(GPIO 32~39)。這裡選用 GPIO 34 屬於 ADC1,不會有衝突問題。

範例一:類比值讀取(基礎版)

這個範例會持續讀取類比輸出值,並透過 Serial Monitor 觀察音量變化。

// ===================================
// ESP32 + 聲音模組 聲音感測 - 類比讀取
// 傑森創工 blog.jmaker.com.tw
// ===================================

const int aoPin = 34;  // AO 接 GPIO34

void setup() {
  Serial.begin(115200);
  Serial.println("聲音感測模組 - 類比讀取模式");
  Serial.println("===================================");
}

void loop() {
  int analogValue = analogRead(aoPin);
  
  Serial.print("類比值: ");
  Serial.print(analogValue);
  
  // 簡易音量條顯示
  int bars = map(analogValue, 0, 4095, 0, 30);
  Serial.print("  |");
  for (int i = 0; i < bars; i++) {
    Serial.print("█");
  }
  Serial.println("|");
  
  delay(100);
}
測試時,請在模組邊大力拍手,才會有明顯效果

觀察重點

  • ESP32 的 ADC 為 12 位元,讀取值範圍是 0 ~ 4095
  • 安靜時,類比值大約在 1800 ~ 2100 左右浮動(因為 AO 輸出是以中間電壓為基準)
  • 對著麥克風大聲說話、拍手或吹氣,數值會明顯跳動
  • Serial Plotter(序列繪圖器)可以更直觀地看到波形變化

調整靈敏度

模組上的藍色可變電阻(VR1)是用來調整 DO 的觸發門檻:

  • 順時針旋轉:降低靈敏度(需要更大的聲音才會觸發)
  • 逆時針旋轉:提高靈敏度(小聲音也會觸發)

建議調整方式:先將可變電阻轉到 LED2 剛好熄滅的位置,此時靈敏度最高且不會誤觸發。

拿到新的模組要轉非常非常多圈!

一般來說,LM393的效果並不如大家預期,你可能只會在很大的聲響時看到音量的變化。若是想改善,建議直接換其它更敏感的模組,像是LM386就是很好的選擇。只是貴一點囉^^

聲音感測模組 微雪原廠 聲控模組 聲音檢測 LM386模組 敏感度極佳
傑森實測,敏感度真的比幾十塊的那些好太多了!值得! 產品描述: 採用音頻處理芯片LM386對音頻信號進行200倍放大靈敏度可調信號輸出指示 產品參數: 麥克風的靈敏度:52dB頻段:50Hz ~ 20KHz工作電壓:3.3V ~ 5.3V固定孔尺寸:2.0mm 主要用途: 音頻放大、檢測環境聲音的有無或判斷聲音強度的大小(不能測量具體的分貝數)。 接口說明:(以接入MCU為例) VCC:接3.3V ~ 5.3VGND:接GNDAOUT:接MCU.IO (模擬量輸出)DOUT:接MCU.IO (
LM386在測試時比較容易看到不同聲響的變化

範例二:數位觸發偵測

利用 模組的 DO 腳位,偵測聲音是否超過門檻值。觸發時 DO 輸出 LOW

// ===================================
// ESP32 + 聲音模組 聲音感測 - 數位觸發
// 傑森創工 blog.jmaker.com.tw
// ===================================

const int doPin = 27;  // DO 接 GPIO27

void setup() {
  Serial.begin(115200);
  pinMode(doPin, INPUT);
  Serial.println("聲音感測模組 - 數位觸發模式");
  Serial.println("請調整模組上的藍色可變電阻來設定靈敏度");
  Serial.println("=====================================");
}

void loop() {
  int digitalValue = digitalRead(doPin);
  
  if (digitalValue == LOW) {
    Serial.println(">>> 偵測到聲音! <<<");
  }
  
  delay(50);
}


範例三:拍手聲控 LED 開關(實用版)

結合類比讀取與去彈跳邏輯,實作一個「拍手開/關 LED」的聲控裝置。

// =============================================
// ESP32 + 聲音模組 拍手聲控 LED 開關
// 傑森創工 blog.jmaker.com.tw
// =============================================

const int aoPin = 34;       // AO 接 GPIO34
const int ledPin = 2;       // LED 接 GPIO2
const int threshold = 2800; // 聲音觸發門檻(可依環境調整)
const int cooldown = 300;   // 冷卻時間(毫秒),避免連續觸發

bool ledState = false;
unsigned long lastTrigger = 0;

void setup() {
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
  
  Serial.println("拍手聲控 LED 開關");
  Serial.println("拍一下手切換 LED 狀態");
  Serial.println("========================");
}

void loop() {
  int analogValue = analogRead(aoPin);
  unsigned long now = millis();
  
  // 超過門檻且不在冷卻期間
  if (analogValue > threshold && (now - lastTrigger > cooldown)) {
    ledState = !ledState;  // 切換狀態
    digitalWrite(ledPin, ledState ? HIGH : LOW);
    lastTrigger = now;
    
    Serial.print("觸發!類比值: ");
    Serial.print(analogValue);
    Serial.print(" -> LED ");
    Serial.println(ledState ? "開" : "關");
  }
  
  delay(10);
}

調校建議

threshold 的值需要依照你的環境噪音來調整:

  1. 先用範例一觀察安靜時的類比值範圍
  2. 拍手時觀察類比值會跳到多高
  3. threshold 設在兩者之間(例如安靜時約 2000,拍手時跳到 3200,那就設 2800)

範例四:即時音量監測(進階版)

加入取樣統計,計算一段時間內的音量 RMS 值,更準確地反映環境音量。

// =============================================
// ESP32 + 聲音模組即時音量監測(RMS 計算)
// 傑森創工 blog.jmaker.com.tw
// =============================================

const int aoPin = 34;
const int sampleWindow = 50;  // 取樣視窗(毫秒)

void setup() {
  Serial.begin(115200);
  Serial.println("即時音量監測(RMS 模式)");
  Serial.println("========================");
}

void loop() {
  unsigned long startMillis = millis();
  long sumSquares = 0;
  int sampleCount = 0;
  int peakToPeak = 0;
  int signalMax = 0;
  int signalMin = 4095;
  
  // 在取樣視窗內連續取樣
  while (millis() - startMillis < sampleWindow) {
    int sample = analogRead(aoPin);
    
    // 峰對峰值計算
    if (sample > signalMax) signalMax = sample;
    if (sample < signalMin) signalMin = sample;
    
    // RMS 計算用
    int centered = sample - 2048;  // 以中間值為零點
    sumSquares += (long)centered * centered;
    sampleCount++;
  }
  
  peakToPeak = signalMax - signalMin;
  float rms = sqrt((float)sumSquares / sampleCount);
  
  // 將 RMS 映射到 0-100 的音量百分比
  int volumePercent = map((int)rms, 0, 1500, 0, 100);
  volumePercent = constrain(volumePercent, 0, 100);
  
  Serial.print("RMS: ");
  Serial.print(rms, 1);
  Serial.print("  峰對峰: ");
  Serial.print(peakToPeak);
  Serial.print("  音量: ");
  Serial.print(volumePercent);
  Serial.print("% ");
  
  // 視覺化音量條
  int bars = volumePercent / 5;
  Serial.print("[");
  for (int i = 0; i < 20; i++) {
    if (i < bars) Serial.print("=");
    else Serial.print(" ");
  }
  Serial.println("]");
  
  delay(100);
}

常見問題排解

Q1:類比值一直都很低或不會變化?

  • 確認接線是否正確,特別是 AO 腳位是否接到 ESP32 的 ADC1 腳位
  • 確認模組的 VCC 有正常供電(電源 LED 應亮起)
  • 嘗試將 VCC 接到 5V(Vin)而非 3.3V,有些模組在 3.3V 下輸出範圍較小

Q2:數位輸出(DO)不會觸發?

  • 用螺絲起子調整模組上的藍色可變電阻
  • 調整時觀察模組上的 LED2,轉到 LED2 剛好熄滅的位置附近即為最佳靈敏度

Q3:讀取值不穩定,跳動很大?

  • 這是正常的,麥克風本身就會收到環境噪音
  • 使用範例四的 RMS 取樣方式可以得到更平穩的讀數
  • 也可以在硬體上加一顆 100nF 的電容在 AO 和 GND 之間做簡單濾波

Q4:Wi-Fi 開啟後讀不到類比值?

  • ESP32 的 ADC2(GPIO 0, 2, 4, 12-15, 25-27)在 Wi-Fi 啟用時無法使用
  • 請確保類比輸入使用 ADC1 的腳位:GPIO 32, 33, 34, 35, 36, 39

延伸應用

學會了基本的聲音偵測之後,你可以嘗試以下進階專案:

  1. 智慧聲控燈:搭配繼電器模組,用拍手控制家電開關
  2. 噪音監測站:結合 OLED 顯示器,即時顯示分貝值與音量圖表
  3. 嬰兒哭聲偵測器:偵測到持續大音量時透過 LINE Notify 發送通知
  4. 節奏偵測器:分析拍手節奏,做出更複雜的聲控指令(例如拍兩下開燈、拍三下關燈)
  5. Wi-Fi 音量記錄器:將音量數據透過 MQTT 傳送到 Home Assistant 儀表板

結語

入門級的聲音感測模組搭配 ESP32 的處理能力,已經可以做出不少有趣的互動專案。這篇教學從基礎的類比與數位讀取,一路到 RMS 音量計算和拍手聲控,希望能幫你快速上手。如果你想做更精確的音訊處理,可以進一步研究 ESP32 的 I2S 介面搭配 INMP441 數位麥克風模組,那又是另一個有趣的主題了!