INMP441 ESP32 I2Sマイク:音声の読み取り、dB測定、波形表示
INMP441 I2SマイクをESP32につなぐ方法を解説します。配線表、I2Sでの24ビット音声の読み取り、dBレベルの計算、シリアルプロッタでの波形表示、PicoのMicroPythonコードまで紹介します。
INMP441は、チップの中で音をデジタルに変換し、24ビットのサンプルをI2Sバスで直接送る小さなMEMSマイクモジュールです。INMP441 ESP32の組み合わせは、アナログマイクやアンプ、ADCを使わずにきれいな音声を得るいちばん簡単な方法です。モジュールをESP32に6本の線でつなぎ、数行のI2Sコードで1秒間に16,000サンプルを取得し、そのサンプルから周囲の音の大きさをデシベル(dB)で計算して、シリアルプロッタで音の波形をリアルタイムに見ることができます。
このガイドでは、INMP441の仕組み、I2Sの3本の信号線の役割、ESP32 Arduinoコアの2.xと3.xの両方でコンパイルできるコード、dBFSとdB SPLの違い、本物の騒音計の計算式をステップごとに紹介します。最後には、Raspberry Pi PicoでのMicroPythonの使い方、安価なアナログのKY-038サウンドセンサーとの違い、よくある配線ミスもまとめています。

INMP441とは?その仕組み
INMP441は、TDK InvenSense製の無指向性(全方向から同じように音を拾う)MEMSマイクです。ここでいうMEMSとは、シリコン上に加工された微細な振動膜と固定板からなる小さなコンデンサのことです。音波で膜が振動すると、静電容量が変化します。一般的なエレクトレットコンデンサーマイクはこの変化を弱いアナログ電圧として出力するため、増幅し、フィルタをかけ、ADCで測定する必要があります。一方、INMP441の内部にはプリアンプ、エイリアシング防止フィルタ、24ビットのシグマデルタADC、I2Sインターフェースがまとめて入っています。つまり、マイクから出てくるのはもはや電圧ではなく、クロック信号に合わせて送られてくる数値です。そのため配線にアナログのノイズがのらず、ボードのADCの性能も関係なくなり、条件に合う3.3 Vのマイコンならどれでも同じ音質が得られます。モジュールにある小さな穴はマイクの音の入り口です。ケースに取り付けるときは、この穴をふさがないように注意してください。
| 項目 | 値 |
|---|---|
| 種類 | MEMS、無指向性、デジタル出力のマイク |
| インターフェース | I2S、24ビット、MSBファースト、2の補数 |
| 電源 | 1.8〜3.3 V |
| 電流 | 約1.4 mA |
| 感度 | −26 dBFS(1 kHz、94 dB SPL) |
| S/N比(SNR) | 61 dBA |
| 周波数特性 | 60 Hz〜15 kHz |
| 最大音圧(AOP) | 120 dB SPL |
| SCKの周波数 | 約0.5〜3.2 MHz(サンプリング約7.8〜50 kHz) |
| モジュールのピン | VDD, GND, SD, L/R, WS, SCK |
I2Sとは?3本の線で送るデジタル音声
I2S(Inter-IC Sound)は、チップ間で音声のサンプルを運ぶために作られたシリアルバスで、名前は似ていますがI2Cとは関係ありません。信号線は3本です。SCK(ビットクロック)は各データビットを読むタイミングを、WS(ワードセレクト、LRCLKとも呼ばれます)はその時点で左右どちらのチャンネルを送っているかを示し、SDはデータそのものです。この構成ではESP32がマスターで、両方のクロックを生成し、マイクはクロックに合わせてSD線にデータを出力します。INMP441では、1フレームは64回のSCKパルスでできていて、左チャンネルに32ビット、右チャンネルに32ビットが割り当てられます。そのためサンプリングレートはSCK / 64になり、16 kHzでサンプリングするにはESP32が約1.024 MHzのビットクロックを生成します。マイクは24ビットの測定値を、自分のチャンネルの32ビットの枠にMSBファースト(最上位ビットから)で書き込み、残りの8ビットは0になります。コードで値を8ビット右にシフトしているのはこのためです。
| INMP441のピン | 役割 |
|---|---|
| VDD | 電源、1.8〜3.3 V |
| GND | グラウンド |
| SCK | ビットクロック入力(ボードから) |
| WS | チャンネル選択クロック入力(ボードから) |
| SD | シリアル音声データ出力(マイクからボードへ) |
| L/R | チャンネル選択:GND = 左チャンネル、VDD = 右チャンネル |
INMP441の配線:ESP32とRaspberry Pi Pico
| INMP441のピン | ESP32 | Raspberry Pi Pico |
|---|---|---|
| VDD | 3V3 | 3V3(OUT)(ピン36) |
| GND | GND | GND |
| SCK | GPIO 32 | GP16 |
| WS | GPIO 25 | GP17 |
| SD | GPIO 33 | GP18 |
| L/R | GND | GND |
ESP32では、I2Sの信号をGPIOマトリクス経由で好きなピンに割り当てられます。表の32、25、33は必須ではなく、安全な選択肢というだけです。ただし、起動時の動作を決めるストラッピングピン(GPIO 0、2、5、12、15)と、フラッシュメモリ用に予約されているGPIO 6〜11は避けてください。GPIO 34〜39は入力専用なので、SD線には使えますがSCKとWSには使えません。Picoのルールは異なります。MicroPythonのI2SドライバはPIOを使うため、WSピンはSCKピンの1つ上の番号でなければなりません(GP16とGP17など)。線は10〜15 cmより短くしてください。メガヘルツ単位のクロック信号は、長いジャンパーワイヤーでは波形が崩れます。ボードのピン配置は「ピン配置」ツールで確認できます。
ステップごとに:ESP32で初めての音声読み取り
- Arduino IDEにESP32のボードパッケージがインストールされていることを確認し、「ツール」>「ボード」でESP32 Dev Moduleを選びます。インストール方法がわからない場合は「ESP32とは?」の記事を参照してください。
- モジュールをブレッドボードに挿し、VDDを3V3に、GNDをGNDに、L/RもGNDにつなぎます。
- SCKをGPIO 32に、WSをGPIO 25に、SDをGPIO 33につなぎ、線は短くしておきます。
- 下のコードを書き込みます。追加のライブラリは不要です。3.xコアのESP_I2Sと2.xコアのdriver/i2s.hは、どちらもボードパッケージに含まれています。
- 115200ボーでシリアルモニタを開きます。静かな部屋では約35〜50 dB、話しているときは55〜70 dB程度の値が表示されるはずです。
- 「ツール」>「シリアルプロッタ」を開くと、dBFSとdB SPLの曲線をリアルタイムで見られます。マイクの近くで手をたたいて、曲線が跳ね上がるのを確認してください。
ESP32のコード:INMP441で音の大きさ(dB)を測る
コードはESP_ARDUINO_VERSION_MAJORでESP32 Arduinoコアのバージョンを確認します。3.xでは新しいESP_I2Sライブラリを、2.xではESP-IDFの従来のI2Sドライバを使います。どちらも同じmicBegin()とmicRead()関数を提供するので、loop()の中の計算は変わりません。1回のループで512サンプル、つまり16 kHzで32 ms分の音声を読み取り、DCオフセットを取り除いてRMS値を求め、デシベルに変換します。
1// INMP441 + ESP32: ses seviyesi (dB) olcer / sound level (dB) meter
2// ESP32 Arduino core 2.x ve 3.x / ESP32 Arduino core 2.x and 3.x
3#include <Arduino.h>
4#include <math.h>
5
6#define MIC_SCK 32 // INMP441 SCK
7#define MIC_WS 25 // INMP441 WS
8#define MIC_SD 33 // INMP441 SD
9
10const uint32_t SAMPLE_RATE = 16000; // ornekleme hizi / sample rate
11const size_t BLOCK = 512; // blok basina ornek / samples per block
12const double FS_RMS = 5931642.0; // 8388608 / sqrt(2): tam olcek sinus RMS / full-scale sine RMS
13const double DB_OFFSET = 120.0; // 94 dB SPL - (-26 dBFS)
14
15int32_t samples[BLOCK];
16
17#if ESP_ARDUINO_VERSION_MAJOR >= 3
18#include <ESP_I2S.h>
19I2SClass i2s;
20
21bool micBegin() {
22 i2s.setPins(MIC_SCK, MIC_WS, -1, MIC_SD); // bclk, ws, dout (yok / none), din
23 return i2s.begin(I2S_MODE_STD, SAMPLE_RATE, I2S_DATA_BIT_WIDTH_32BIT,
24 I2S_SLOT_MODE_MONO, I2S_STD_SLOT_LEFT); // L/R = GND -> sol / left
25}
26
27size_t micRead(int32_t *buf, size_t count) {
28 size_t bytes = i2s.readBytes((char *)buf, count * sizeof(int32_t));
29 return bytes / sizeof(int32_t);
30}
31#else
32#include <driver/i2s.h>
33
34bool micBegin() {
35 i2s_config_t cfg = {};
36 cfg.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX); // ana cihaz, alici / master, receiver
37 cfg.sample_rate = SAMPLE_RATE;
38 cfg.bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT;
39 cfg.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT; // L/R = GND -> sol / left
40 cfg.communication_format = I2S_COMM_FORMAT_STAND_I2S;
41 cfg.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1;
42 cfg.dma_buf_count = 4;
43 cfg.dma_buf_len = 256;
44 cfg.use_apll = false;
45
46 i2s_pin_config_t pins = {};
47 pins.mck_io_num = I2S_PIN_NO_CHANGE;
48 pins.bck_io_num = MIC_SCK;
49 pins.ws_io_num = MIC_WS;
50 pins.data_out_num = I2S_PIN_NO_CHANGE;
51 pins.data_in_num = MIC_SD;
52
53 if (i2s_driver_install(I2S_NUM_0, &cfg, 0, NULL) != ESP_OK) return false;
54 return i2s_set_pin(I2S_NUM_0, &pins) == ESP_OK;
55}
56
57size_t micRead(int32_t *buf, size_t count) {
58 size_t bytes = 0;
59 i2s_read(I2S_NUM_0, buf, count * sizeof(int32_t), &bytes, portMAX_DELAY);
60 return bytes / sizeof(int32_t);
61}
62#endif
63
64void setup() {
65 Serial.begin(115200);
66 if (!micBegin()) {
67 Serial.println("I2S baslatilamadi / I2S init failed");
68 while (true) delay(1000);
69 }
70}
71
72void loop() {
73 size_t n = micRead(samples, BLOCK);
74 if (n == 0) return;
75
76 double sum = 0;
77 for (size_t i = 0; i < n; i++) {
78 samples[i] >>= 8; // 32 bit yuvadan 24 bit veri / 24-bit data from 32-bit slot
79 sum += samples[i];
80 }
81 double mean = sum / n; // DC kaymasi / DC offset
82
83 double sq = 0;
84 for (size_t i = 0; i < n; i++) {
85 double v = (double)samples[i] - mean;
86 sq += v * v;
87 }
88 double rms = sqrt(sq / n);
89 if (rms < 1.0) rms = 1.0; // log10(0) olmasin / avoid log10(0)
90
91 double dbfs = 20.0 * log10(rms / FS_RMS);
92 double spl = dbfs + DB_OFFSET;
93
94 Serial.print("dBFS:");
95 Serial.print(dbfs, 1);
96 Serial.print(" dB_SPL:");
97 Serial.println(spl, 1);
98}| コードの部分 | 働き |
|---|---|
| SAMPLE_RATE = 16000 | 1秒間に16,000サンプルを取得します。SCKの周波数は16,000 × 64 = 1.024 MHzになります。会話には十分で、音楽なら44,100(SCK約2.82 MHz)を選べます。 |
| 32ビットのデータ幅 | INMP441はWSの1フレームごとに64回のSCKパルスを必要とします。16ビットを選ぶとフレームが短くなり、データが意味をなさなくなります。 |
| MONO + LEFT / ONLY_LEFT | 左チャンネルだけを読み取ります。L/RピンがGNDにつながっているので、マイクは左の枠を使います。 |
| samples[i] >>= 8 | 32ビットの枠から24ビットの測定値を取り出します。値は−8,388,608〜+8,388,607の範囲になります。 |
| 平均値を引く | 信号に含まれる小さなDCオフセットを取り除きます。そうしないとRMSが本来より大きくなります。 |
| rms(実効値) | サンプルを2乗した値の平均の平方根で、音の平均的なパワーを表します。 |
| dbfs + DB_OFFSET | データシートの感度−26 dBFS @ 94 dB SPLを使って、結果をdB SPLに変換します。 |
音の大きさの計算方法:dBFSとdB SPL
音圧はとても広い範囲で変化するため、対数のデシベル尺度が使われます。振幅が2倍になると約+6 dB、10倍になると+20 dBです。マイクから得た数値は、まずdBFS(フルスケールを基準にしたデシベル)に変換します:dBFS = 20 × log10(RMS / フルスケールのRMS)。フルスケールとは、ピークが24ビットの最大値8,388,608に達する正弦波のRMS値で、8,388,608 / √2 ≈ 5,931,642です。この尺度では0 dBFSがマイクのクリッピングの限界で、それより小さい音はすべてマイナスの値になります。物理的な音圧であるdB SPLに換算するには、データシートの感度を使います。INMP441は94 dB SPLの1 kHzの音を−26 dBFSとして出力します。ここからdB SPL = dBFS + 94 − (−26) = dBFS + 120という式が得られます。たとえばRMS値が5,932なら、dBFS = 20 × log10(0.001) = −60となり、音の大きさは約60 dB SPLで、普通の会話くらいのレベルです。
| 音源 | dB SPLの目安 | INMP441でのdBFS |
|---|---|---|
| マイク自体のノイズフロア | 33 | −87 |
| 静かな部屋 | 40 | −80 |
| 普通の会話(1 m) | 60 | −60 |
| 交通量の多い道路、掃除機 | 70〜80 | −50〜−40 |
| 長時間さらされると聴覚に危険 | 85 | −35 |
| 測定の基準(校正器) | 94 | −26 |
| ドリル、コンサートのステージ前 | 100〜110 | −20〜−10 |
| マイクの上限(AOP) | 120 | 0 |
シリアルプロッタで波形を表示する
デシベル値は音の大きさを教えてくれますが、音の形を見るには生のサンプルをグラフにする必要があります。同じスケッチで、loop()関数だけを下のものに置き換えてください。ここには大事な制限があります。115200ボーのシリアル通信で送れるのは1秒間に約11,500文字で、1秒間に16,000サンプルを出力するには足りません。そこでコードは512サンプルのブロックをまとめて出力します。ブロックの出力中に届いた音は取りこぼしますが、プロッタに表示される各部分は途切れのない本物の32 ms分の音です。
1// dB taslaginda loop() yerine bunu kullan / Use this instead of loop() in the dB sketch
2void loop() {
3 size_t n = micRead(samples, BLOCK);
4 for (size_t i = 0; i < n; i++) {
5 int32_t v = samples[i] >> 8; // 24 bit ham ornek / 24-bit raw sample
6 Serial.print("ses:");
7 Serial.println(v);
8 }
9}マイクに向かって口笛を吹くと、プロッタにはほぼきれいな正弦波が表示されます。1 kHzの口笛なら1周期は1 msで、16 kHzのサンプリングでは16点に相当します。1周期の点の数を数えれば、周波数をおおよそ見積もれます。会話はたくさんの周波数が混ざっているので、不規則で包絡線のある波になります。手をたたくと、短くてとても高い鋭いピークが現れます。プロッタは軸を自動で調整するため、静かなときは小さなノイズの揺れが大きく見えることがありますが、これは正常です。シリアルモニタとシリアルプロッタの使い方の詳細は「Arduinoのシリアルモニタ」の記事を参照してください。
Raspberry Pi PicoでINMP441を使う(MicroPython)
Raspberry Pi Picoには専用のI2Sユニットはありませんが、プログラム可能なPIOブロックがハードウェアの速度でI2Sを再現し、MicroPythonのmachine.I2Sクラスがその処理を引き受けてくれます。追加のファイルをインストールする必要はなく、最新のMicroPythonが入っていれば十分です。コードではbits=32とformat=I2S.MONOを指定し、読み取ったサンプルを同じく8ビット右にシフトしてから、同じ式でデシベルに変換します。PythonのループはCより遅いので、ブロックサイズを512サンプルにしておくのがちょうどよいバランスです。計算中に数ミリ秒分の音を取りこぼしても、結果にはほとんど影響しません。Arduino IDEでPicoをプログラムする場合は、arduino-picoコアのI2Sライブラリでも同じことができます。その場合もWS(LRCLK)ピンはBCLKピンの1つ上の番号にする必要があります。MicroPythonが初めての場合は、まず「Raspberry Pi Picoとは?」の記事を読んでみてください。
1from machine import Pin, I2S
2import array
3import math
4
5SCK_PIN = 16 # INMP441 SCK
6WS_PIN = 17 # INMP441 WS (SCK + 1 olmali / must be SCK + 1)
7SD_PIN = 18 # INMP441 SD
8
9FS_RMS = 5931642.0 # 8388608 / sqrt(2): tam olcek sinus RMS / full-scale sine RMS
10DB_OFFSET = 120.0 # 94 dB SPL - (-26 dBFS)
11LN10 = math.log(10)
12
13mic = I2S(0, sck=Pin(SCK_PIN), ws=Pin(WS_PIN), sd=Pin(SD_PIN),
14 mode=I2S.RX, bits=32, format=I2S.MONO,
15 rate=16000, ibuf=8192)
16
17samples = array.array('i', [0] * 512) # 32 bit ornek dizisi / 32-bit sample array
18
19while True:
20 n = mic.readinto(samples) // 4 # okunan ornek sayisi / number of samples read
21 if n == 0:
22 continue
23 total = 0
24 for i in range(n):
25 samples[i] >>= 8 # 24 bit degeri ayikla / extract 24-bit value
26 total += samples[i]
27 mean = total / n # DC kaymasi / DC offset
28 sq = 0.0
29 for i in range(n):
30 d = samples[i] - mean
31 sq += d * d
32 rms = max(math.sqrt(sq / n), 1.0)
33 dbfs = 20 * math.log(rms / FS_RMS) / LN10
34 print("dBFS: {:.1f} dB SPL: {:.1f}".format(dbfs, dbfs + DB_OFFSET))INMP441とKY-038アナログサウンドセンサーの違い

KY-038は、エレクトレットコンデンサーマイクのカプセル、しきい値を設定する半固定抵抗、LM393コンパレーターでできた安価なモジュールです。デジタル出力(DO)は、音が設定したしきい値を超えると状態が切り替わります。アナログ出力(AO)はカプセルの生の電圧を出力し、ボードのADCで読み取ります。この構成は、拍手の検知や部屋に音があるかどうかの判定には十分です。しかしモジュールにアンプがないため、信号はとても弱く、Arduino Unoの10ビットADCでは会話で数段階しか変化が見えず、ESP32のADCはノイズが多めです。一方INMP441は、マイクの内部で24ビットで測定します。途中にアナログの配線、アンプ、ADCがないので、ノイズフロアからクリッピングの限界まで約87 dBの範囲をきれいに記録できます。まとめると、KY-038は音のスイッチで、INMP441は本物のマイクです。アナログ読み取りの限界については「ADCのガイド」で詳しく紹介しています。
| 項目 | INMP441 | KY-038 |
|---|---|---|
| マイクの種類 | MEMS、デジタル出力 | エレクトレットのカプセル、アナログ |
| 出力 | I2S、24ビットのサンプル | AOのアナログ電圧+DOのしきい値出力 |
| 電源 | 1.8〜3.3 V | 3.3〜5 V |
| 対応ボード | ESP32、Pico、I2S対応のボード | Unoを含むすべてのボード |
| 音質 | 録音や解析に十分(60 Hz〜15 kHz) | おおまかなレベルのみ |
| dBの測定 | 式を使えば可能 | 信頼できない |
| 主な用途 | 騒音計、録音、FFT、音声コマンド | 拍手スイッチ、音のあり/なしアラーム |
INMP441を使ったプロジェクトのアイデア
- 音に反応するLED:音の大きさをWS2812Bテープで点灯するLEDの数に変換します。詳しくは「音に反応するLED」と「WS2812B NeoPixel」の記事を参照してください。
- 教室の騒音信号機:55 dB未満で緑、55〜70 dBで黄、それ以上で赤に光る警告ランプを作ります。
- Webでリアルタイムの騒音ダッシュボード:dB値をWebSocketでブラウザに送り、スマホでグラフとして見ます。基本の構成は「ESP32のWebサーバーとWebSocket」で紹介しています。
- スマートホームの騒音センサー:測定値をMQTTでHome Assistantに送ります。「ESP32のMQTTとHome Assistant」のガイドが役立ちます。
- 赤ちゃんの泣き声や犬のほえ声の通知:音が一定時間しきい値を超えたら、Telegramボットでスマホにメッセージを送ります。
- 録音機:サンプルを16ビットのWAVファイルとしてSDカードモジュールに書き込み、パソコンで聞きます。
- 口笛での操作:FFTで最も強い周波数を求め、特定の高さの口笛でLEDやリレーを動かします。
よくあるミスと対処法
| 症状 | 考えられる原因 | 対処法 |
|---|---|---|
| dB SPLの値が−15.5付近で変わらない | SD線からデータが来ておらず、すべてのサンプルが0 | SDの線と、L/RがGNDにつながっていることを確認します。それでもだめならチャンネルを右に切り替えます(3.xではI2S_STD_SLOT_RIGHT、2.xではI2S_CHANNEL_FMT_ONLY_RIGHT) |
| 音を大きくしても値が上がらず、ランダムに跳ねる | SCKとWSが入れ替わっているか、線が長すぎる | 表のとおりにピンを直し、線を10〜15 cm未満に短くします |
| 起動時に「CONFLICT! The new i2s driver can't work along with the legacy i2s driver」(新旧のI2Sドライバの競合)というエラー | 3.xコアで古いdriver/i2s.hと新しいドライバを一緒に使っている | ドライバは1つだけにします。このコードの#ifの構造が正しいほうを自動で選びます |
| dB値が騒音計と10〜20 dBずれる | ビットシフトが間違っている、DCを取り除いていない、またはキャリブレーションをしていない | シフトを8ビットにし、平均値を引き、一定のトーンでキャリブレーションします |
| PicoでI2Sを作成するときにValueError | WSピンがSCKピンの1つ上の番号になっていない | SCK = GP16、WS = GP17のように連続したピンを使います |
| マイクが熱くなる、またはまったく反応しない | VDDを5 Vにつないでいる | すぐに3V3につなぎ直します。マイクが壊れている可能性があるので、新しいものを試してください |
| シリアルプロッタで波形が途切れ途切れに見える | シリアル通信で1秒間に16,000サンプルを送りきれない | これは正常です。より滑らかに表示したい場合はボーレートを921600に上げます |
INMP441を使えば、数本の線と短いスケッチでESP32に本物のデジタルマイクを追加できます。音の大きさの測定から音に反応するライトまで、たくさんのプロジェクトの土台になります。アナログセンサーで済ませるのではなく、音を数値として処理したいときには、まずこのマイクを選ぶとよいでしょう。BlueGraysアプリでは、LED、ブザー、WS2812Bテープ、WebサーバーなどのESP32のプロジェクトを、回路図とコードでステップごとに確認でき、そこにこのマイクを簡単に追加できます。
よくある質問
INMP441はArduino Unoで使えますか?
いいえ、実際には使えません。Arduino UnoやNanoにはI2Sのハードウェアがなく、5 Vのロジックで動作し、2 KBのRAMでは音声バッファに足りません。INMP441にはESP32、ESP32-S3、Raspberry Pi Pico、またはI2Sに対応したほかの3.3 Vのボードを使ってください。
INMP441のL/Rピンは何をするピンですか?
L/Rピンは、マイクがステレオのフレームのどちらのチャンネルを使うかを選びます。GNDにつなぐと左、3.3 Vにつなぐと右です。2個のINMP441のSCK、WS、SD線を共通につなぎ、片方を左、もう片方を右に設定すれば、1本のI2Sバスでステレオの音声を取得できます。ピンは未接続のままにしないでください。読み取り値が0になったり不安定になったりします。
INMP441で録音できますか?
はい。24ビットのサンプルを16ビットに減らし、WAVヘッダーを付けてSDカードに書き込めば、パソコンで再生できる録音ファイルになります。会話なら16 kHzのサンプリングで十分です。16ビット・モノラルで1分間録音すると、約1.9 MBになります。
INMP441でのデシベル測定はどのくらい正確ですか?
データシートの感度−26 dBFSを使った計算なら、キャリブレーションなしでも数dB以内の結果が得られます。マイクの感度のばらつきは±1 dBです。計算はA特性の重み付けをしていないため、低い周波数のうなりが多い環境では騒音計より高い値になることがあります。既知の音源でキャリブレーションすれば部屋の騒音にはかなりよい結果が得られますが、公式の測定器の代わりにはなりません。
INMP441とKY-038のどちらを買えばいいですか?
拍手や大きな音を検知して何かを動かすだけなら、KY-038で十分で、どのボードでも使えます。音の大きさをdBで測りたい、録音したい、周波数を解析したい、音に反応するライトを作りたい場合は、INMP441のほうがずっときれいで正確な結果が得られます。
ESP32でINMP441がいつも0を読むのはなぜですか?
よくある原因は、L/Rピンが未接続、コードのチャンネルがマイクの設定と合っていない、SDの線が違うピンに挿さっている、の3つです。まずL/RをGNDにつなぎ、次にコードのチャンネルを右に切り替えて試してください。ビット幅が32ビットになっていること、モジュールに3V3から電源を供給していることも確認してください。
この記事を読んだ後に作れるプロジェクト
全プロジェクトを見る
ESP32でLEDを点滅
ESP32のGPIO出力の基本を学びます。デジタルピンからLEDを点灯・消灯させて、点滅させます。Arduino UNOの定番のLED点滅プロジェクトのESP32版です。Arduino環境で使う基本的な点滅コマンドは同じですが、ESP32のピン配置と3.3 VのGPIO電圧レベルはArduino UNOとは異なります。

ブザーの使い方
呼び鈴やアラームがどうやって音を出すのか、気になったことはありませんか?Arduinoが小さなブザーを短い間隔で鳴らし、音を出す、止める、を繰り返します。電気で音が生まれる仕組みを学び、メロディーを演奏するプロジェクトへの第一歩を踏み出せます。

ESP32のPWMでLEDをフェード
LEDの明るさを0から最大へ、最大から0へと滑らかに変化させます。Arduinoと同じようにanalogWrite()でPWMを制御します。ESP32 Arduino Core 3.0+では同じ構文がそのまま使えます。ピンの定義とpinMode、analogWriteだけで実現できます。

ESP32とブザーでメロディーを演奏
パッシブブザーで簡単なメロディー「きらきら星」を演奏します。Arduinoと同じようにtone()とnoTone()で音を鳴らします。ESP32 Arduino Core 3.0+でも同じ構文が使えます。パッシブブザーを使用してください。アクティブブザーではメロディーを演奏できません。

ESP32 WS2812B NeoPixel LEDテープの制御
WS2812B(NeoPixel)は、1本のデータピンで連結したLEDを個別に制御できるスマートなRGB LEDです。このプロジェクトでは、8個のLEDを備えたWS2812BテープをAdafruit_NeoPixelライブラリで制御し、滑らかな虹色のアニメーションを作ります。ESP32の3.3VロジックレベルはほとんどのWS2812Bのロットで問題なく動作しますが、不安定な場合に備え、470Ωの直列抵抗と1000µFのコンデンサを使う対策も紹介します。アニメーションは、HSV色空間の色相(hue)をずらして作ります。

ESP32非同期Webサーバー(LCDにIPアドレスを表示)
このプロジェクトでは、ESP32を同じWi-Fiネットワーク上のスマートフォンやパソコンから操作できる非同期Webサーバーにします。ESPAsyncWebServerライブラリを使うと、従来のWebServer.hのように1つのリクエストで処理がブロックされず、複数のリクエストを同時に処理できます。ブラウザーでESP32のIPアドレスを開き、ON/OFFボタン(/onと/offのルート)を押すと、GPIO 5に接続したLEDを点灯・消灯できます。

ESP32 WebSocketカウンター(2つのボタン+LCD+Webリアルタイム表示)
このプロジェクトでは、ESP32に接続した2つのボタンでカウンターの値を変更します(GPIO 5で増加、GPIO 4で減少)。値は16x2 I2C LCDに即座に反映され、ESPAsyncWebServerのWebSocket機能により、接続中のすべてのブラウザーでもページを再読み込みせずに更新されます。HTTPポーリングの代わりに1つの接続を維持し、ESP32がws.textAll()で新しい値を全員に送信します。

ESP32 HTTPClient+天気API(SSD1306 OLED付き)
このプロジェクトでは、ESP32でHTTPClient.hを使い、インターネット経由で天気API(wttr.in)をREST APIとして呼び出します。前のI2C LCD版とは異なり、SSD1306 OLED(128×64)ディスプレイを使うため、大きな文字やベクターアイコンで、1つの画面に豊かな表現ができます。天気を表す7種類のベクターアイコン(晴れ、晴れ時々曇り、曇り、雨、雪、嵐、霧)を実行時に描画するので、ビットマップファイルは不要です。気温は中央に3倍の大きさの文字で表示します。
ほかの記事
BlueGraysアプリ
この回路をスマホでステップごとに作る
回路図、コード、部品リストを1つの画面で確認できます。Arduino、ESP32、Picoのプロジェクトを200件以上用意しています。

