組員: 411114324 范立翰
動機:
有時候半夜睡覺時,室友可能會不小心發出較大的聲音,影響休息。雖然我偶爾會下床請他們稍微小聲一些,但如果能有一個明確的音量標準當作依據會更好。因此我想設計一個可以偵測環境音量的裝置,當音量超過某個值時,就會透過亮燈或聲音作出提醒,既能幫助我判斷,也能提醒室友們注意音量。
Arduino一塊,電線若干,麵包版,Arduino 聲音感測模組KY-038 (檢測聲音大小),螢幕顯示板TM1637(顯示分貝),LED燈(提示音量過大),蜂鳴器(警告用)
圖中溫度感測儀的部分由音量感測器KY-038替代
作品介紹:我使用 KY-038 聲音感測器與 TM1637 顯示器製作了音量檢測器,可即時顯示分貝值,並計算平均音量。當音量超過 75 dB 時,會啟動 LED 警示並使蜂鳴器短暫響起,並在序列監控視窗顯示音量變化,方便進一步分析與記錄。
程式碼:
#include <TM1637Display.h>
#define CLK 2
#define DIO 3
#define MIC_PIN A0
#define LED_PIN 8
#define BUZZER_PIN 9
TM1637Display display(CLK, DIO);
const float Vref = 512.0; // 校正值
const float dBref = 80.0;
const int numReadings = 50;
int readings[numReadings];
int idx = 0;
long total = 0;
// 警告音量
const float threshold = 75.0;
const int buzzCount = 3;
const int buzzLen = 100;
const int buzzGap = 100;
void setup() {
pinMode(LED_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
Serial.begin(9600);
display.setBrightness(0x0f);
for (int i = 0; i < numReadings; i++) readings[i] = 0;
}
void loop() {
int raw = analogRead(MIC_PIN);
float voltage = raw;
float dB = 20.0 * log10(voltage / Vref) + dBref; // 電阻與分貝換算
total -= readings[idx];
readings[idx] = (int)dB;
total += readings[idx];
idx = (idx + 1) % numReadings;
float avgDB = total / numReadings;
display.showNumberDecEx((int)dB, 0, true);
Serial.print(millis());
Serial.print("\t");
Serial.print(dB);
Serial.print("\t");
Serial.println(avgDB);
if (dB >= threshold) {
digitalWrite(LED_PIN, HIGH);
for (int i = 0; i < buzzCount; i++) {
tone(BUZZER_PIN, 1000);
delay(buzzLen);
noTone(BUZZER_PIN);
delay(buzzGap);
}
} else {
digitalWrite(LED_PIN, LOW);
}
delay(100); // 每 100ms 更新一次
}
心得與結論:
這次的VIP課程做出了這個音量檢測器,但是效果並不好,音量檢測模組KY-038(27元)的精度太低,需要很靠近它檢測器的聲音才會有較大的反應,假如還有時間的話會想要用更好的、精度更高的模組,像是MAX9814(95元)、Gravity: Analog Sound Level Meter (這個要1500元)之類的。
另外在寫程式的部分,使用到了幾個上學期有教過的模組,最麻煩的是把訊號換算成分貝的部分,需要先用確定的分貝校準,並配合參數修正來符合實際結果。