2
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?

Raspberry Pi PicoとAIを繋ぐ—IoTセンサー(CO₂)をLLMで使う

Last updated at Posted at 2025-03-11

はじめに

Raspberry Pi Picoのようなデバイスへセンサーを取り付け、その情報をLLM(大規模言語モデル)のAIで利用できるか試した。
MCP(Model Context Protocol)サーバーがどのような役割を果たすのか学びながら構築した。

Claude Desktopでの動作
ezgif-556ef5a3169789.gif

デバイスの外観
IMG_2216.jpg
IMG_2217.jpg

Raspberry Pi PicoとCO₂センサー実装

今回は、Raspberry Pi Picoの無線が搭載されていないシンプルなボードを利用し、事例の多数あるセンサー読み取りのファームウェアを作成した。

CO₂センサーは、手元にあったMH-Z19Bを利用した。

MH-Z19Bの特徴

非分散型赤外線方式(NDIR)で動作し、比較的精度が高く安定している
測定範囲は0〜5000ppm、測定誤差は±50ppmまたは±5%(大きい方を採用)
センサー内部での自己校正機能(ABC:Automatic Baseline Correction)を備える
UART通信を使用して簡単に接続が可能

回路図・接続時の注意点

MH-Z19BのVCCピンは5V、GNDピンは共通GNDへ接続
Raspberry Pi PicoのGPIOは3.3Vであるため、MH-Z19Bからの出力は3.3V対応(内部回路)で直接接続可能
RX、TXの接続ミスに注意(MH-Z19BのTXをPicoのRXに、MH-Z19BのRXをPicoのTXに接続)

PicoとCO₂センサーのコード実装

PicoとCo2センサーはシリアルを利用した通信を行うため、下記のようなコードを使い、デバイスを準備した。
これで、PC側へ、CO₂センサーの値がおよそ1秒ごとに送信される。

from machine import Pin, UART
import utime

mhz19c = UART(0, baudrate=9600, tx=Pin(16), rx=Pin(17))
led = Pin(25, Pin.OUT)

while True:
    led.toggle()
    utime.sleep(0.1)
    led.toggle()
    data = bytearray([0xff, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79])
    mhz19c.write(data)
    mhz19c.readinto(data,len(data))
    co2 = data[2] * 256 + data[3]
    print('CO2 (ppm):'+str(co2))

    utime.sleep(1)

接続としては以下の通り。

[PC]  <--USB-->  [Pico]
                   |
                   | シリアル (UART)
                   |
               [MH-Z19B]

MCPサーバーによるIoT環境構築

MCPサーバーの基本概念と仕組み

MCP(Model Context Protocol)は、デバイスのセンサーデータや状態情報を標準化されたJSON形式でLLMへ渡す役割を持つ。

MCPはOpenAPIが定めた規格であり、JSON-RPC形式を使い、統一されたフォーマットでデータをリクエスト・レスポンスとしてやり取りする。

センサー情報をJSONに変換した後、MCPサーバーがその情報をHTTPまたはWebSocket経由でAIモデルへ伝える。

MCPプロトコルが持つ主な要素

  1. Resource(リソース): センサーやデバイスの状態情報を保持・管理するオブジェクトで、LLMへのプロンプト文脈として利用できるもの。今回のケースだと、温度センサーのデータなど

  2. Tool(ツール): 特定の機能(センサー値取得、状態変更、イベント通知など)を提供するためのAPI。今回のケースだと、温度センサーを呼び出すコマンド、デバイス状態を返すコマンドなど

  3. Prompt(プロンプト): ユーザーや他のLLMへ提示する指示や対話フローテンプレート。今回のケースでは使っていないが、例えば、ChatGPTで「あなたはXXの専門家です、その視点でXXをアドバイスしてください」などのプロンプトがそれにあたるという理解。

センサーデータ取得とMCPサーバーへの送信のコード実装

今回のMCPサーバーの構成は下記となる。

[センサーデータ]
       │
       │ シリアル通信
       ↓
[MCPサーバー]
       │
       │ 標準入出力(stdio)
       ↓
[MCPクライアント(Claude Desktop)]

MCPサーバーは実際は、Claude Desktopが起動するnode.jsの実行プロセスとして動作する。
そこへ標準入出力(stdio)でアクセスする形となる。
MCPサーバーとClaude DesktopなどのMCPクライアントとの間はほかにHTTP with SSE(Server-Sent Events)というリモートに対応できる接続方式もある。後日調査したい。

実装コードはGithubに配置した。

コードは大まかに下記の構成となった:

  • SerialPortライブラリを使ったシリアル通信の初期化
  • シリアルポートが利用可能でない場合のセンサー値シミュレーション
  • JSON-RPCリクエストによるデータ送信とエラー処理
  • 定期的なセンサーデータ更新の仕組み
  • センサー値(CO₂濃度)の取得と解析方法
  • エラーコード管理とロギング(ログファイルへの書き込み処理)

AI(LLM)連携による可能性と応用事例

リアルタイム換気制御:CO₂濃度が一定値(例:1000ppm)を超えたら、LLMが換気を推奨または自動で換気装置をオンにする。その他イベントドリブンで他のMCPサーバーと連携し制御の提案も行う。

環境快適性向上:オフィスや住宅内の快適度をLLMが評価し、アドバイスを提供。
などなど、Alexaのようなホームアシスタントが作れるのではないか。

課題と今後の展望

セキュリティやプライバシー保護の注意点
ローカルで遊ぶ分には問題はないだろうが、リモート環境のセンサーとの疎通などは配慮する必要がありそう。

2
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
2
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?