📘 はじめに
この記事では、Excel と ESP32-S3 デバイスだけで温度・距離・加速度など複数のセンサをCSV記録する方法 を紹介します。センサを変えてもVBAを書き換えることなく自動でロギングできます。
この記事では ESP32IO という、ESP32-S3 をベースにした HTTP API でセンサやI/Oを操作できるリモートI/Oプラットフォーム(自作プロジェクト)を使用します。
Excel・Python・Node-RED・Power BI など、さまざまなソフトウェアから同じ方法で利用できます。
まずはこちらのまとめ記事で ESP32IO の全体像を確認しておくと理解がスムーズです:
🔗 https://qiita.com/Noritama-Lab/items/cae87dc4cd67fe438c82
なお、この記事の内容は ESP32-S3-DevKitC-1 にファームウェアを書き込むだけでも動作します。自作基板がなくても試せるので、まずは手元の開発ボードで動かしてみてください。
🎯 ゴール
- ESP32IO の
get_sensorsAPI から JSON を取得 - BME280 / MPU6050 / VL53L1X など複数センサを Excel にロギング
- センサ追加しても壊れない「動的ロギング」構造
- 配列・ネストしたオブジェクトにも対応
- 長時間のロギングも意識した VBA コード
最終的には、Excelだけで複数センサの時系列ログを取得し、グラフ化まで行えるようになります。
🧱 システム構成
各種センサ(I2C)
↓
ESP32IO(get_sensors API)
↓
VBA(通信・JSONパース・動的展開)
↓
Excel(時系列ログ)
📡 ESP32IO の API(get_sensors)
ESP32IO の get_sensors は次のような JSON を返します:
{
"status": "ok",
"inventory": {
"bme280": true,
"mpu6050": true,
"vl53l1x": false,
"oled": false
},
"bme280": {
"temp": 25.1,
"hum": 60.0,
"press": 1013.2
},
"mpu6050": {
"accel": [0.01, -0.02, 0.98],
"gyro": [0.1, 0.2, 0.3]
}
}
🔧 センサの接続
今回は BME280 を例に説明しますが、ESP32IO が対応している他のセンサでも 同じ仕組みでそのまま利用できます。複数同時接続も可能です。
I2C センサの接続は 3.3V、GND、SDA、SCL の4本のみです。
📄 Excel側の準備
1. シート構成
-
DataLog(計測値の時系列ログ)
- A1:
timestamp - B1:
device - C1:
key - D1:
value
- A1:
- ErrorLog(通信エラーの記録)
2. JSONライブラリ
ESP32IO の API は JSON 形式でデータを返すため、JSON を扱えるライブラリを使用します。
以下から JsonConverter.bas をダウンロードし、VBA プロジェクトへインポートしてください。
3. 参照設定
ツール → 参照設定 のMicrosoft Scripting Runtime にチェックを入れます。
🏆 VBAコード
コードは少し長いですが、JSON を再帰的に展開しているため、一度導入すればセンサを追加しても基本的に修正は不要です。
以下の2つのコードを標準モジュールとして作成してください。
操作は Ctrl_Log の StartLogging と StopLogging を実行して行います。
クリックしてコードを表示(Logging)
Option Explicit
Const ESP32_URL As String = "http://192.168.0.20/api"
Dim http As Object
Private Sub InitHttp()
If http Is Nothing Then
Set http = CreateObject("WinHttp.WinHttpRequest.5.1")
http.SetTimeouts 1000, 1000, 3000, 3000
End If
End Sub
Sub LogSensors()
On Error GoTo ErrHandler
InitHttp
http.Open "POST", ESP32_URL, False
http.SetRequestHeader "Content-Type", "application/json"
http.Send "{""cmd"":""get_sensors""}"
If http.status <> 200 Then
LogError "HTTP Error: " & http.status
Exit Sub
End If
Dim js As Object
Set js = JsonConverter.ParseJson(http.ResponseText)
Dim ts As Variant
ts = Now
If Not js.Exists("inventory") Then
LogError "inventory missing"
Exit Sub
End If
Dim inv As Object
Set inv = js("inventory")
Dim dev As Variant
For Each dev In inv.Keys
If inv(dev) = True And js.Exists(dev) Then
Call LogJsonObject(ts, dev, js(dev))
End If
Next dev
Exit Sub
ErrHandler:
LogError Err.Description
End Sub
' ============================================================
' 汎用 JSON 展開ロガー(再帰対応)
' ============================================================
Private Sub LogJsonObject(ts As Variant, device As Variant, obj As Variant)
Dim ws As Worksheet
Set ws = Sheets("DataLog")
Dim r As Long
r = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1
Dim key As Variant
' --- 配列(Collection) ---
If TypeName(obj) = "Collection" Then
Dim i As Long
For i = 0 To obj.Count - 1
ws.Cells(r, 1).Value = ts
ws.Cells(r, 2).Value = device
ws.Cells(r, 3).Value = device & "_" & i
ws.Cells(r, 4).Value = obj(i)
r = r + 1
Next i
Exit Sub
End If
' --- オブジェクト(Dictionary) ---
If IsObject(obj) Then
' Dictionary の Keys を安全に列挙
On Error GoTo NotDictionary
For Each key In obj.Keys
Dim v As Variant
v = obj(key)
Select Case TypeName(v)
Case "Collection"
' 配列
Dim j As Long
For j = 0 To v.Count - 1
ws.Cells(r, 1).Value = ts
ws.Cells(r, 2).Value = device
ws.Cells(r, 3).Value = key & "_" & j
ws.Cells(r, 4).Value = v(j)
r = r + 1
Next j
Case "Dictionary", "Object"
' ネストしたオブジェクト
Call LogJsonObject(ts, device & "." & key, v)
Case Else
' 単一値
ws.Cells(r, 1).Value = ts
ws.Cells(r, 2).Value = device
ws.Cells(r, 3).Value = key
ws.Cells(r, 4).Value = v
r = r + 1
End Select
Next key
Exit Sub
NotDictionary:
' Keys が使えない場合は単一値として扱う
ws.Cells(r, 1).Value = ts
ws.Cells(r, 2).Value = device
ws.Cells(r, 3).Value = "(value)"
ws.Cells(r, 4).Value = obj
Exit Sub
End If
' --- 単一値(Double / String / Boolean) ---
ws.Cells(r, 1).Value = ts
ws.Cells(r, 2).Value = device
ws.Cells(r, 3).Value = "(value)"
ws.Cells(r, 4).Value = obj
End Sub
' --- ErrorLog ---
Private Sub LogError(msg As String)
With Sheets("ErrorLog")
Dim r As Long
r = .Cells(.Rows.Count, 1).End(xlUp).Row + 1
.Cells(r, 1).Value = Now
.Cells(r, 2).Value = msg
End With
End Sub
クリックしてコードを表示(Ctrl_Log)
Option Explicit
Public NextTime As Date
Sub StartLogging()
Call LogSensors
NextTime = Now + TimeValue("00:00:10")
Application.OnTime NextTime, "StartLogging"
End Sub
Sub StopLogging()
On Error Resume Next
Application.OnTime NextTime, "StartLogging", , False
End Sub
📊 ログの構造
複数のセンサをつないだ場合、DataLog シートはこうなります:
| timestamp | device | key | value |
|---|---|---|---|
| 09:00 | bme280 | temp | 25.1 |
| 09:00 | bme280 | hum | 60 |
| 09:00 | bme280 | press | 1013 |
| 09:00 | mpu6050 | accel_0 | 0.01 |
| 09:00 | mpu6050 | accel_1 | -0.02 |
| 09:00 | mpu6050 | accel_2 | 0.98 |
| 09:00 | mpu6050 | gyro_0 | 0.1 |
| 09:00 | mpu6050 | gyro_1 | 0.2 |
| 09:00 | mpu6050 | gyro_2 | 0.3 |
| 09:00 | vl53l1x | distance | 123 |
⚠ 長時間ロギングする場合の注意
Excel VBA は Windows がスリープに入ると停止してしまうため、
長時間ロギングする場合は PC の電源設定でスリープを無効化してください。
(設定例)
Windows設定 → システム → 電源とスリープ
・「スリープ」:なし
・「画面オフ」:任意
ESP32IO 側はスリープ機能を使っていないため、
PC が動いている限りロギングは継続されます。
📈 グラフ化
Excelの基本的な操作だけでグラフ化できます。
- DataLog シートでフィルターを有効化
- device = bme280、key = temp を選択
-
timestampとvalue列を使って折れ線グラフを作成
🔚 まとめ
この方法を使えば、ESP32IO に接続したセンサの計測値を
Excel に時系列データとして簡単に記録できます。
さらに、JSON を動的に展開しているため、
新しいセンサを追加しても VBA を書き換える必要がほとんどありません。
ESP32IO の拡張性をそのまま活かしながら、
Excel を手軽なデータロガーとして利用できます。
ESP32IO は、HTTP で JSON を扱えるソフトウェアであれば同じ API を利用できます。
Excelで始めたシステムを、後から Python や Node-RED、Power BI へ発展させても、利用する API は同じです。
用途に応じてソフトウェアを自由に選びながら、同じデバイスを使い続けられることが ESP32IO の大きな特長です。
💬 コメント歓迎
「こんなセンサでも試してみた」「こんな用途で使っている」といった活用例や、「こんな機能があると便利」といったご意見があれば、ぜひコメントで教えてください。
皆さんのアイデアを参考にしながら、ESP32IO をさらに使いやすいプラットフォームへ育てていきたいと思います。
ESP32IO のソースコードやファームウェアは GitHub で公開しています。



