Arduinoで音センサーを使う方法|配線・コード・しきい値調整を徹底解説
音センサーモジュールは、周囲の音の大きさを検知できる部品です。拍手を検知するスイッチや、簡易的な騒音モニターなどに使われます。本記事では、配線とコードの基本を解説します。あわせて、音ならではの扱いにくさや、しきい値の調整方法まで、初心者の方に向けて順を追って紹介します。
01音センサーモジュールとは
マイクとコンパレータの組み合わせ
代表的な音センサーモジュールには、決まった構成があります。小さなマイク(エレクトレットコンデンサマイク)と、LM393という比較回路(コンパレータ)です。この構成には既視感があるかもしれません。実は、土壌水分センサーの回路とよく似ているのです。仕組みはシンプルです。マイクが拾った音の信号を増幅し、あらかじめ設定したしきい値と比較します。
AO(アナログ出力)とDO(デジタル出力)の役割分担

音センサーモジュールには、2種類の出力があります。AO(アナログ出力)は、音の大きさに応じて連続的に変化する信号です。DO(デジタル出力)は、音がしきい値を超えたときにHIGHまたはLOWに切り替わる信号です。しきい値は、基板上のポテンショメータで調整します。用途に応じて、この2つを使い分けます。
土壌水分センサーでLM393コンパレータの仕組みを学んだLさんは、音センサーモジュールを手に取った。基板の構成を見て、既視感を覚えたという。ポテンショメータでしきい値を決め、超えたらデジタル出力が切り替わる。同じ設計思想が、まったく違うセンサーにも使われていることに気づいたのだ。一つの仕組みを理解すると、応用が利く部品は他にもたくさんあります。
02なぜ単純なanalogReadでは音量を測れないのか
音は振動し続ける交流信号
これまでのセンサーとは、少し勝手が違う点があります。可変抵抗やCdSセルの値は、比較的ゆっくり変化します。しかし、音はまったく違います。1秒間に何十回、何百回と細かく振動し続ける信号なのです。analogRead()を1回呼び出すだけでは足りません。その瞬間の波形のたった1点を切り取っているにすぎないのです。たまたま波の谷にあたれば小さい値になります。山にあたれば大きい値になってしまいます。
短い時間で最大・最小を記録する「振幅」の考え方
そこで必要になるのが、別の考え方です。短い時間(例えば50ミリ秒程度)の中で、何度も連続してanalogRead()を行います。そして、その中での最大値と最小値の差を計算するのです。この差を「振幅」と呼びます。振幅が大きいほど、音が大きかったと判断できます。複数の技術解説記事でも、この方法が音量測定の基本として紹介されています。
03配線方法:Arduinoと音センサー

基本の4本配線
多くの音センサーモジュールには、VCC・GND・AO・DOという4本のピンがあります。VCCはArduinoの5Vに、GNDはGNDにつなぎます。AOはアナログピンのA0に、DOはデジタルピンのD2につなぎます。配線自体は、これまで扱ってきたセンサーと大きく変わりません。
対応電圧の目安
多くの製品は3.3V〜5.5V程度の範囲で動作します。パッケージや商品説明に記載された対応電圧を確認しておきましょう。マイク部分は振動や風の影響を受けやすい部品です。設置場所にも配慮すると、より安定した動作が得られます。
04基本のコード|AOで音量の振幅を測る
50ミリ秒間の最大・最小を記録する
2章で紹介した考え方を、実際のコードにしてみましょう。analogRead()を短い時間の中で繰り返し呼び出します。そして、最大値と最小値を記録していきます。
// 50ミリ秒間の振幅(音の大きさ)を測るコード
const int soundPin = A0;
void setup() {
Serial.begin(9600);
}
void loop() {
unsigned long startTime = millis();
int maxValue = 0;
int minValue = 1023;
// 50ミリ秒間、繰り返し読み取って最大・最小を更新する
while (millis() - startTime < 50) {
int value = analogRead(soundPin);
if (value > maxValue) maxValue = value;
if (value < minValue) minValue = value;
}
int amplitude = maxValue - minValue; // 振幅(音の大きさの目安)
Serial.print("振幅: ");
Serial.println(amplitude);
}
シリアルモニタで振幅の変化を確認する
このコードを書き込んだら、シリアルモニタを開いてみましょう。静かな状態と、手を叩いたり話しかけたりした状態を比べてみます。振幅の値がどう変化するか確認してください。静かな環境でも、多少の振幅は残ります。これは、電気的なノイズや周囲の環境音によるものです。
05DOとしきい値調整|ポテンショメータの使い方
ポテンショメータで感度を調整する
DOピンを使う場合、コード側でしきい値を設定する必要はありません。基板上のポテンショメータを回すだけで調整できます。多くの製品には共通の傾向があります。反時計回りに回すと感度が上がり、より小さな音でも反応するようになります。時計回りに回すと感度が下がります。大きな音にしか反応しなくなります。
DOを読み取るコード
// DOピンで音の有無を判定するコード
const int doPin = 2;
const int ledPin = 13;
void setup() {
pinMode(doPin, INPUT);
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}
void loop() {
int state = digitalRead(doPin);
if (state == HIGH) {
digitalWrite(ledPin, HIGH);
Serial.println("しきい値を超える音を検知しました");
} else {
digitalWrite(ledPin, LOW);
}
delay(50);
}
製品によって表記が異なる点に注意
DOの信号がHIGHとLOWのどちらで「検知あり」を表すかは、製品によって表記が分かれています。お手元のモジュールで実際に動かして確認しておくと安心です。
06実践例:拍手でLEDを点灯させる

振幅を使ったクラップスイッチ
4章で紹介した振幅の考え方を使えば、拍手を検知するクラップスイッチが作れます。振幅が一定のしきい値を超えたら、LEDの状態をトグル(反転)させる仕組みです。
// 拍手を検知してLEDのON/OFFを切り替えるコード
const int soundPin = A0;
const int ledPin = 13;
const int amplitudeThreshold = 100; // 実機での振幅を見て調整する
bool ledState = false;
unsigned long lastTrigger = 0;
const unsigned long cooldown = 500; // 連続反応を防ぐための待機時間
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}
void loop() {
unsigned long startTime = millis();
int maxValue = 0;
int minValue = 1023;
while (millis() - startTime < 50) {
int value = analogRead(soundPin);
if (value > maxValue) maxValue = value;
if (value < minValue) minValue = value;
}
int amplitude = maxValue - minValue;
if (amplitude > amplitudeThreshold && millis() - lastTrigger > cooldown) {
ledState = !ledState;
digitalWrite(ledPin, ledState);
lastTrigger = millis();
Serial.println("拍手を検知しました");
}
}
連続反応を防ぐクールダウン
この例では、工夫を1つ加えています。一定時間だけ次の反応を無視する「クールダウン」です。タクトスイッチのチャタリング対策と、似た発想の工夫です。
07よくあるトラブルと対処法
症状別の対処早見表
| 症状 | 主な原因 | 対処法 |
|---|---|---|
| 振幅の値がほとんど0のまま変化しない | 配線ミス、またはマイクの向きの問題 | AO・VCC・GNDの配線を確認し、マイクの穴を音源に向ける |
| DOがずっとHIGH(またはLOW)のまま | ポテンショメータの感度が高すぎる | 静かな環境でトリガーLEDが消えるまで感度を下げる(5章参照) |
| 小さな物音にも過剰に反応する | 感度が高すぎる、しきい値が低すぎる | ポテンショメータやコード内のしきい値を上げる |
| 拍手をしても反応しない | 感度が低すぎる、しきい値が高すぎる | ポテンショメータやコード内のしきい値を下げる |
| 1回の拍手で何度も反応してしまう | クールダウン処理がない | 一定時間は次の反応を無視する処理を追加する(6章参照) |
原因を素早く切り分けるコツ
Sさんはクラップスイッチのコードを試したが、拍手をしてもLEDがまったく反応しなかった。配線を確認しても間違いは見当たらなかった。そこで、シリアルモニタで振幅の生の値を表示させてみた。すると、拍手をしても振幅が30程度までしか上がらないことが分かった。設定していたしきい値100には遠く及ばなかったのだ。しきい値を50に下げると、正しく反応するようになった。しきい値は決め打ちせず、実測して調整することが大切です。
08よくある質問
基本のQ&A
応用のQ&A
関連記事・参考資料
基礎を学べる記事
- YOFUKASI LAB「Arduinoで土壌水分センサーを使う」2026年, https://yofukasi-lab-wp.com/2026/09/03/arduino-soil-moisture-sensor/
- YOFUKASI LAB「ArduinoでCdS光センサーを使う方法」2026年, https://yofukasi-lab-wp.com/2026/08/31/arduino-cds-light-sensor/
- YOFUKASI LAB「Arduinoに必要な工具・部品リスト」2026年, https://yofukasi-lab-wp.com/2026/08/22/arduino-tools-parts/
応用・関連記事
- YOFUKASI LAB「Arduinoでタクトスイッチ入力|配線とコード」2026年, https://yofukasi-lab-wp.com/2026/08/28/arduino-tact-switch-input/
- YOFUKASI LAB「Arduinoでブザーを鳴らす|tone関数入門」2026年, https://yofukasi-lab-wp.com/2026/08/29/tone/
- YOFUKASI LAB「Arduinoのコンパイルエラー一覧」2026年, https://yofukasi-lab-wp.com/2026/07/30/error/
参考資料(外部・一次情報)
- Arduino Documentation「analogRead()」, https://docs.arduino.cc/language-reference/en/functions/analog-io/analogRead/
- ComponentIndex「KY-038 Sound Sensor Guide」, https://componentindex.net/components/sound-sensor/
※本記事は個人の学習・電子工作用途を対象にしています。実際の製品や医療機器へ組み込む場合は、電気安全・製品規格の専門家に別途ご相談ください。
コメント