ESP32ボードを使用してBMP280(温度・気圧・湿度)とINA219(電圧・電流・電力)のセンサーデータを取得し、Render PostgreSQLバックエンドに送信するエンドツーエンドのシステムです。バックエンドはNode/Expressと共有モジュール(shared/analytics-service.js など)で構成され、取り込んだ最新データを解析して最適な計測レートを決定し、その結果(nextIntervalSeconds)をESP32へレスポンスとして返します。
- esp32/: センサー読み取りとHTTP送信、レスポンスに基づくスリープ制御
- web-service/: Render向けExpress API(PostgreSQLへ保存、レート計算、レスポンス生成)
- shared/: フロント/バックエンド共通のアナリティクス、レート判定ロジック、テスト
- public/: スタンドアロンの可視化ダッシュボード(ローカル検証用)
- ESP32開発ボード
- BMP280/BME280 温度・気圧・湿度センサー(I2C接続)
- INA219 電流・電圧センサーモジュール(I2C接続)
- ブレッドボード と ジャンパー線
ESP32にMicroPythonファームウェアをインストール:
# ファームウェアダウンロード
# https://micropython.org/download/esp32/
# フラッシュ消去
esptool.py --port /dev/ttyUSB0 erase_flash
# MicroPython書き込み
esptool.py --chip esp32 --port /dev/ttyUSB0 write_flash -z 0x1000 esp32-*.binHTTP通信に必要なurequestsライブラリをインストール:
# mpremoteを使用(推奨)
mpremote mip install urequests
# または、REPLから
import mip
mip.install("urequests")passwords.py ファイルを編集してWiFi設定を入力:
# WiFi Settings
HOME_WIFI_SSID = 'YOUR_HOME_WIFI_SSID' # ← 実際のSSIDに変更
HOME_WIFI_PASS = 'your_password'
LAB_WIFI_SSID = 'YOUR_LAB_WIFI_SSID' # ← 実際のSSIDに変更
LAB_WIFI_PASS = 'your_lab_password'
# 使用するWiFi('HOME' または 'LAB')
WIFI_MODE = 'HOME'ESP32にプロジェクトファイルをアップロード:
# mpremoteを使用
mpremote cp boot.py :boot.py
mpremote cp bmp280.py :bmp280.py
mpremote cp ina219.py :ina219.py
mpremote cp logging.py :logging.py
mpremote cp passwords.py :passwords.py
# または ampy を使用
ampy --port /dev/ttyUSB0 put boot.py
ampy --port /dev/ttyUSB0 put bmp280.py
ampy --port /dev/ttyUSB0 put ina219.py
ampy --port /dev/ttyUSB0 put logging.py
ampy --port /dev/ttyUSB0 put passwords.pyESP32をリセットして起動ログを確認:
# シリアルモニターで接続
screen /dev/ttyUSB0 115200
# または mpremote
mpremotegraph TD
A[起動] --> B[WiFi接続]
B --> C[センサー初期化]
C --> D[測定ループ開始]
D --> E[BMP280読み取り]
E --> F[INA219読み取り]
F --> G[ローカルCSV保存]
G --> H{WiFi接続中?}
H -->|Yes| I[Render APIへ送信]
H -->|No| J[ローカル保存のみ]
I --> K[LED点滅]
J --> K
K --> L[nextInterval秒待機]
L --> D
Render APIのレスポンスには nextIntervalSeconds が含まれ、HIGH=60s / MEDIUM=300s / LOW=900s のマッピングで調整されます。ネットワークエラー時はデフォルトの300秒スリープにフォールバックします。
POST https://m2r.onrender.com/api/measurements
{
"deviceId": "ESP32-001",
"temperature": 25.3,
"humidity": 60.5,
"recordedAt": null,
"payload": {
"voltage_v": 4.98,
"current_ma": 120.4,
"power_mw": 600.5,
"device_info": {
"platform": "ESP32",
"framework": "MicroPython"
}
}
}- 上記JSONを空白なしでシリアライズすると 約200バイト(~203B) です。
- HTTPヘッダー(
Content-Typeなど)を含めたリクエスト全体は 約230〜260バイト + TLSのオーバーヘッド。 - 送信フィールドを追加する場合は、この目安を超えないように整数・小数の桁数を調整してください。
フラッシュ書き換え回数を抑えるため、現在のboot.pyではCSV書き込みがコメントアウトされており ローカル保存は行われません。CSVへも保存したい場合は、該当箇所のコメントを外し(esp32/boot.pyのinitialize_csv_files()・BMP/INAの書き込み部分)、必要に応じてログローテーションを追加してください。
再有効化する場合の保存先:
- temp.csv: 温度・気圧・湿度データ
- elect.csv: 電圧・電流・電力データ
- debug.log: デバッグログ
temp.csv:
timestamp_ms,temperature_c,pressure_pa,humidity_percent
12345678,25.3,101325,60.5elect.csv:
timestamp_ms,voltage_v,current_ma,power_mw
12345678,4.98,120.4,600.5GPIO 2のLEDで動作状態を表示:
| パターン | 意味 |
|---|---|
| 💡 点灯 | センサー読み取り中 |
| ⚡ 高速点滅(3回) | データ送信中 |
| ✅ ゆっくり点滅(2回) | 送信成功 |
| ⭕ 消灯 | 待機中 |
ERROR: WiFi connection timeout
対処法:
passwords.pyのSSID/パスワードを確認- WiFiルーターの電波強度を確認
WIFI_MODE設定を確認('HOME' or 'LAB')
ERROR: No I2C devices found on the bus!
対処法:
- 配線を確認(SCL=GPIO22, SDA=GPIO21)
- センサーの電源供給を確認(3.3V or 5V)
- プルアップ抵抗の確認(多くのモジュールは内蔵)
i2c_scan.pyを実行してアドレス確認
✗ API error: HTTP 500
対処法:
- Render APIが起動しているか確認
RENDER_API_URLが正しいか確認- ネットワーク接続を確認
- debug.logでエラー詳細を確認
WARNING: urequests not available
対処法:
mpremote mip install urequestsM2_R/
├── esp32/ # センサー制御・WiFi送信(MicroPython)
│ ├── boot.py # メインループ(動的スリープ制御・HTTP送信)
│ ├── bmp280.py / ina219.py / logging.py
│ └── passwords.py # WiFi設定(手動で作成)
├── shared/ # analytics-service・測定プロセッサ・Jestテスト
├── web-service/ # Render配信用Express API(PostgreSQL接続)
├── public/ # オフラインダッシュボード(`public/index.html`)
├── analysis/, diagrams/ # レート制御や性能に関するドキュメント
└── README.md # プロジェクト全体の概要(本ファイル)
# API設定
RENDER_API_URL = "https://m2r.onrender.com/api/measurements"
DEVICE_ID = "ESP32-001" # デバイスIDを変更可能
# スリープ制御(抜粋)
sleep_interval = 300 # フォールバック値
send_success, next_interval = send_with_retry(...)
if send_success:
sleep_interval = next_interval # HIGH=60, MEDIUM=300, LOW=900
time.sleep(sleep_interval)バックエンド (web-service/src/server.js) は control_states テーブルの targetRate を参照し、RATE_INTERVAL_MAP = { HIGH: 60, MEDIUM: 300, LOW: 900 } をもとに nextIntervalSeconds を算出してレスポンスへ含めます。
max_wait = 20 # WiFi接続タイムアウト(秒)max_retries = 3 # 最大リトライ回数
retry_delay = 2 * attempt # 指数バックオフ(2秒、4秒、6秒...)送信されたデータはWebダッシュボードで確認できます:
https://m2r-frontend.onrender.com
-- 最新の測定データ
SELECT * FROM device_measurements
WHERE device_id = 'ESP32-001'
ORDER BY created_at DESC
LIMIT 10;- WiFi認証情報:
passwords.pyはGitで管理しない(.gitignore設定) - API認証: 現在は未実装(必要に応じてトークン認証を追加)
問題が発生した場合:
- シリアルモニター/
mpremoteでリアルタイムログを確認(最も確実) debug.logを再有効化している場合は内容をチェック- センサーの配線を再確認
- WiFi設定(
passwords.pyとWIFI_MODE)を確認
作成者: M2_R Project 最終更新: 2025-11-11