Skip to content
まことの手帳
Go back

ESP32 でセンサーデータを AWS に送る #4 センサー特定編

前回で Wi-Fi 接続とインターネット疎通が確認できました。AWS に送るデータの中身が決まっていなかったので、今回はセンサーを用意します。

FNK0090 はボード2枚組の製品で、センサーは同梱されていません。手元に別のプロジェクトで買った覚えのないモジュールが4個ありましたが、シルク印刷が読めず何なのか分からない状態でした。

写真で判別しようとしたものの、解像度の限界でお手上げになり、実測で特定することにしました。

目次

手元にあったもの

4個のモジュールを並べてみます。

4つのモジュール。上から傾斜センサー、DHT11、正体不明の2つ

写真から分かったのは2個だけでした。

残り2個は、シルク印刷から接続方式だけは読み取れました。

型番までは分かりません。ここから実測に入ります。

診断ツールを作る

推測で当てずっぽうに配線するのではなく、ESP32 自身に調べさせることにしました。PlatformIO の環境を分けて、本体のファームウェアを壊さずに使えるようにします。

[env:esp32dev]
build_src_filter = +<*> -<diagnostics/>

[env:sensor-scan]
build_src_filter = +<diagnostics/sensor_scan.cpp>
pio run -d firmware -e sensor-scan -t upload

I2C モジュールの特定

まず配線に悩んだ

このボードは幅が広く、ブレッドボードに挿すと GPIO21/22(I2C の既定ピン)側の列が塞がってしまいました。

ここで思い出したのですが、ESP32 の I2C は GPIO マトリクスにより任意のピンに割り当てられます。Wire.begin(SDA, SCL) で指定すればよく、空いている上側の列(GPIO25/26)を使うことにしました。

ただし入力専用ピン(GPIO34-39)は I2C には使えません。SDA は双方向で出力も必要なためです。

スキャンしても何も出てこない

配線して I2C スキャンを実行しましたが、結果はこうでした。

SDA=25 SCL=26  応答なし

エラーも出ず、ただ「何もいない」という結果です。配線ミスなのか、電源が来ていないのか、それとも I2C 自体が動いていないのか、この時点では区別がつきません。

プルアップの有無で切り分ける

I2C は正しく配線され電源が入っていれば、モジュール上のプルアップ抵抗によって SDA/SCL が 待機時に HIGH に固定されます。これを利用すれば、「配線されているか」を「機器が応答するか」とは独立に確認できます。

pinMode(sda, INPUT);   // 内部プルアップは使わない
pinMode(scl, INPUT);
// 50回読んで HIGH の割合を見る

実行結果です。

SDA=25 SCL=26  HIGH率 100% / 100%  プルアップ検出 → 配線と電源は生きている

配線と電源は生きていました。 つまり原因は別にあります。

VCC ではなく 3.3 ピンから給電する

エラーコードの内訳を見ると、全アドレスがきれいに NACK を返していました。

アドレスに NACK : 126 件

これはバスが完全に正常に動作している証拠です。タイムアウトは1件もありません。配線もバスも正常なのに、センサー IC だけが起動していないという状態でした。

この手の基板(GY シリーズ)は、VCC に 5V を入れて、基板上のレギュレータで 3.3V を作る設計のものが多くあります。3.3 と書かれたピンは、そのレギュレータの出力です。

VCC に 3.3V を入れると、レギュレータのドロップアウト分だけ電圧が下がり、センサー IC の動作電圧に届きません。厄介なのは、プルアップ抵抗はレギュレータ出力側に繋がっているため、電圧が足りなくても SDA/SCL は HIGH に見えることです。「配線は生きている」という判定と「IC が動いていない」という実態が両立してしまいます。

対処は単純で、VCC を外し、3.3 ピンに直接 3.3V を入れるだけです。レギュレータを迂回して、IC に必要な電圧をそのまま渡します。

それでも応答しない

配線を直しても、まだ応答がありません。

SDA=25 SCL=26  HIGH率 100% / 100%  プルアップ検出 → 配線と電源は生きている
SDA=25 SCL=26  アドレスに NACK : 126 件

プルアップは検出できているのに、バススキャンでは何も見つからない。ここでもう一つ、電気的には判別できない罠にはまっていました。

SDA と SCL が逆だった

SDA と SCL を入れ替えても、両方の線にプルアップは見えます。 信号の向きに関係なく、プルアップ抵抗はただの抵抗だからです。プルアップ検出だけでは、配線が正しいのか逆なのかが分かりません。

両方の順序を試すしかないと判断し、スキャンを2回、ピンを入れ替えて実行しました。

SDA=25 SCL=26  応答なし
SDA=26 SCL=25  0x77  応答あり

逆でした。 実際の配線は SDA=GPIO26、SCL=GPIO25 です。

チップ ID で機種を確定する

0x77 というアドレスは、BMP180 / BMP280 / BME280 が共有しています。3つとも見た目がほぼ同じで、外観だけでは区別できません。湿度が測れるかどうかも機種によって違うので、ここは確定させたいところです。

Bosch のセンサーは、レジスタ 0xD0 にチップ ID を持っています。1バイト読むだけです。

Wire.beginTransmission(addr);
Wire.write(0xD0);
Wire.endTransmission(false);  // リピートスタートのため stop を送らない
Wire.requestFrom(addr, (uint8_t)1);
const uint8_t id = Wire.read();

結果はこうでした。

チップ ID 0x55 → BMP180(気圧・温度)
ID機種測定できるもの
0x55BMP180気圧・温度
0x58BMP280気圧・温度
0x60BME280気圧・温度・湿度

BMP180 と確定しました。 湿度は測れませんが、温度の精度は ±0.5℃ と DHT11(±2℃)より高く、気圧から高度も算出できます。

BMP180 のピン配置。VCC GND SCL SDA 3.3 のシルク印刷が読める

Grove モジュールの特定

黄色い線を SIG に繋いだが反応しない

Grove ケーブルは色ごとに役割が決まっています。標準的な対応は「黄 = SIG」です。これに従って GPIO34 に繋ぎましたが、値は 0〜4095 の間を乱高下するばかりでした。

未接続のピンは電荷が保持されないため、読むたびに値がばらつきます。これは典型的な「フローティング」の挙動で、信号が来ていないことを示しています。

4本を全部監視する

どの線が SIG なのかを当てずっぽうで探すより、候補になる線を複数同時に監視して比較する方が確実です。黄と白をそれぞれ別のアナログピンに挿し、GPIO32/33/34/35 の4本を同時に読みました。

GPIO34  平均 1001  ばらつき 4095  乱高下 → 未接続
GPIO35  平均 2259  ばらつき   40  安定した中間値 → 接続あり
GPIO32  平均  343  ばらつき 1901  乱高下 → 未接続
GPIO33  平均  824  ばらつき 1600  乱高下 → 未接続

GPIO35(白線)だけが安定した値を示しました。 SIG は黄ではなく白だったということです。ケーブルの色は当てにならない、という前提で挑むべきでした。

電源も来ていなかった

線は特定できましたが、値は動いているのに刺激(光や音)に反応しません。直流成分がゆっくりドリフトするだけで、はっきりした変化がないのです。

BMP180 と見比べると、給電しているブレッドボードの区画が違うことに気づきました。フルサイズのブレッドボードは、+ と − のレールが中央で分断されていることがあります。ESP32 から給電した区画と、Grove を挿した区画が別だと、電気が届きません。

Grove の電源線を、BMP180 の電源線と同じ列に挿し直しました。

スマートフォンのライトで確定

配線を直してから連続測定すると、はっきり反応しました。

   0 (   0 mV)  覆った状態
1272 (1025 mV)  スマートフォンのライトを当てた状態

手をかざす程度では反応が乏しく、判断に迷いました。光を強く当てる・完全に遮るという極端な刺激で試すのが確実です。

基板の印字を見ると LIGHT と書かれていました。Grove - Light Sensor です。

Grove Light Sensor のクローズアップ。基板に LIGHT の印字が見える

特定結果

4個すべて判明しました。

#センサー測定項目接続
1傾斜センサー(SW-520D 系)傾き(二値)デジタル
2DHT11温度・湿度デジタル1線
3BMP180気圧・温度I2C 0x77
4Grove Light Sensor照度アナログ

最終的な配線です。

BMP180                    ESP32
------                    -----
3.3    ─────────────────  3V3      ← VCC ではなくこちら
GND    ─────────────────  GND
SDA    ─────────────────  GPIO26   ← 当初の想定と逆
SCL    ─────────────────  GPIO25

Grove Light Sensor        ESP32
------------------        -----
赤 (VCC) ───────────────  3V3
黒 (GND) ───────────────  GND
白 (SIG) ───────────────  GPIO35   ← 黄ではなく白

2箇所とも、最初に想定した配線と食い違っていました。

ブレッドボード全体。BMP180 と Grove Light Sensor を接続した状態

今回作った診断ツール

同じ切り分けを毎回手で書くのは無駄なので、汎用の診断ツールとしてリポジトリに残しました。

pio run -d firmware -e sensor-scan -t upload
.venv/bin/python firmware/tools/serial_monitor.py -d 30

やっていることは4つです。

  1. I2C バスの電気的状態 — プルアップの有無で配線と電源を確認
  2. I2C スキャン — 応答の内訳を出し、SDA/SCL の入れ替えも自動で試す
  3. チップ ID の読み出し — 0x76/0x77 に応答があれば 0xD0 を読んで機種を確定
  4. アナログ入力の監視 — ADC1 の複数ピンを同時に見て、フローティングと信号を区別する

次に型番不明のモジュールに当たったときは、このツールから始めるつもりです。

次回

センサーが2個、実際に動くところまで確認できました。次はこれを使って気圧・温度・照度を継続的に読み、AWS へ送る準備に入ります。DHT11 を追加すれば湿度も揃います。

AWS 側のアーキテクチャ(IoT Core を使うか、API Gateway + Lambda にするか)もそろそろ決める必要があります。

参考リンク


Share this post on:

Previous Post
ESP32 でセンサーデータを AWS に送る #3 Wi-Fi 接続編
Next Post
ESP32 でセンサーデータを AWS に送る #5 実測編