0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Excel VBAでESP32のセンサデータをロギングする ~JSON APIで簡単に記録する方法~

0
Last updated at Posted at 2026-07-04

📘 はじめに

この記事では、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_sensors API から JSON を取得
  • BME280 / MPU6050 / VL53L1X など複数センサを Excel にロギング
  • センサ追加しても壊れない「動的ロギング」構造
  • 配列・ネストしたオブジェクトにも対応
  • 長時間のロギングも意識した VBA コード

最終的には、Excelだけで複数センサの時系列ログを取得し、グラフ化まで行えるようになります。


🧱 システム構成

各種センサ(I2C)
        ↓
ESP32IO(get_sensors API)
        ↓
VBA(通信・JSONパース・動的展開)
        ↓
Excel(時系列ログ)

image.png


📡 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本のみです。

image.png


📄 Excel側の準備

1. シート構成

  • DataLog(計測値の時系列ログ)
    • A1: timestamp
    • B1: device
    • C1: key
    • D1: value
  • ErrorLog(通信エラーの記録)

2. JSONライブラリ

ESP32IO の API は JSON 形式でデータを返すため、JSON を扱えるライブラリを使用します。
以下から JsonConverter.bas をダウンロードし、VBA プロジェクトへインポートしてください。

image.png

3. 参照設定

ツール → 参照設定 のMicrosoft Scripting Runtime にチェックを入れます。


🏆 VBAコード

コードは少し長いですが、JSON を再帰的に展開しているため、一度導入すればセンサを追加しても基本的に修正は不要です。

以下の2つのコードを標準モジュールとして作成してください。
操作は Ctrl_Log の StartLoggingStopLogging を実行して行います。

クリックしてコードを表示(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の基本的な操作だけでグラフ化できます。

  1. DataLog シートでフィルターを有効化
  2. device = bme280、key = temp を選択
  3. timestampvalue 列を使って折れ線グラフを作成

約1日分のデータを実際に取ってみた結果がこちらです。
image.png


🔚 まとめ

この方法を使えば、ESP32IO に接続したセンサの計測値を
Excel に時系列データとして簡単に記録できます。

さらに、JSON を動的に展開しているため、
新しいセンサを追加しても VBA を書き換える必要がほとんどありません。

ESP32IO の拡張性をそのまま活かしながら、
Excel を手軽なデータロガーとして利用できます。

ESP32IO は、HTTP で JSON を扱えるソフトウェアであれば同じ API を利用できます。

Excelで始めたシステムを、後から Python や Node-RED、Power BI へ発展させても、利用する API は同じです
用途に応じてソフトウェアを自由に選びながら、同じデバイスを使い続けられることが ESP32IO の大きな特長です。


💬 コメント歓迎

「こんなセンサでも試してみた」「こんな用途で使っている」といった活用例や、「こんな機能があると便利」といったご意見があれば、ぜひコメントで教えてください。

皆さんのアイデアを参考にしながら、ESP32IO をさらに使いやすいプラットフォームへ育てていきたいと思います。


ESP32IO のソースコードやファームウェアは GitHub で公開しています。

GitHub:
https://github.com/noritama-lab/esp32io-firmware

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?