メインコンテンツへスキップ
三田工場 技術サイト
複数のRaspberry Piを中継機で束ねてOracle DBにデータを送る

複数のRaspberry Piを中継機で束ねてOracle DBにデータを送る

HowTo15分で読めます

このシリーズ: 全5回

  1. 第1回: MQTTとは?IoT時代の「伝言板」を初心者向けに解説
  2. 第2回: Pub/Subモデルとトピックの仕組み
  3. 第3回: 実践:Raspberry Piで設備監視システムを作る
  4. 第4回: 複数のRaspberry Piを中継機で束ねてOracle DBにデータを送る ← 今ここ
  5. 第5回: MQTTで双方向通信!Oracleのデータを子機に配信する

はじめに

「Raspberry Piを何台も使いたいけど、どうやって繋げばいいの?」

この記事では、1台の中継機(親機)複数のカメラ(子機) を束ねて、 データをOracle Cloud Databaseに送る方法を、ステップバイステップで解説します。


完成イメージ

text
┌─────────────────────────────────────────────────────────────────┐
│                                                                 │
│   【子機たち】カメラ付きRaspberry Pi                             │
│                                                                 │
│   ┌─────────────┐  ┌─────────────┐  ┌─────────────┐           │
│   │  子機① Pi   │  │  子機② Pi   │  │  子機③ Pi   │           │
│   │  📷 カメラ   │  │  📷 カメラ   │  │  📷 カメラ   │           │
│   │  設備EQ001  │  │  設備EQ002  │  │  設備EQ003  │           │
│   │ .32.100    │  │ .32.101    │  │ .32.102    │           │
│   └──────┬──────┘  └──────┬──────┘  └──────┬──────┘           │
│          │               │               │                    │
│          │    Wi-Fi (ローカルネットワーク)  │                    │
│          └───────────────┼───────────────┘                    │
│                          │                                     │
│                          ▼                                     │
│   【親機】中継機 Raspberry Pi                                    │
│   ┌──────────────────────────────────────────────────┐        │
│   │  🖥️ 中継機 (192.168.32.213)                      │        │
│   │                                                  │        │
│   │  ┌────────────────┐  ┌────────────────┐        │        │
│   │  │  Mosquitto     │  │  ブリッジ       │        │        │
│   │  │  (MQTT Broker) │→│  (Python)      │        │        │
│   │  │  ポート1883    │  │                │        │        │
│   │  └────────────────┘  └───────┬────────┘        │        │
│   └──────────────────────────────┼───────────────────┘        │
│                                  │                             │
│                                  │ インターネット               │
│                                  ▼                             │
│   【クラウド】                                                   │
│   ┌──────────────────────────────────────────────────┐        │
│   │  ☁️ Oracle Cloud Database                        │        │
│   │     EQUIPMENT_STATUS テーブル                    │        │
│   └──────────────────────────────────────────────────┘        │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

登場人物の役割

text
┌─────────────────────────────────────────────────────────────────┐
│                     それぞれの役割                               │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   【子機(カメラ側)】                                            │
│   ┌─────────────────────────────────────────────────┐          │
│   │  役割: センサーデータを送る(Publisher)          │          │
│   │                                                 │          │
│   │  やること:                                       │          │
│   │  ① カメラで設備のランプを撮影                     │          │
│   │  ② 色を判定(緑→稼働、赤→停止、黄→異常)          │          │
│   │  ③ MQTTで中継機に送信                            │          │
│   │                                                 │          │
│   │  必要なもの:                                     │          │
│   │  ・Raspberry Pi + カメラ                         │          │
│   │  ・color_detector.py(色検知プログラム)          │          │
│   │  ・paho-mqtt(MQTTライブラリ)                   │          │
│   └─────────────────────────────────────────────────┘          │
│                                                                 │
│   【親機(中継機)】                                              │
│   ┌─────────────────────────────────────────────────┐          │
│   │  役割: メッセージを集めて転送(Broker + Bridge)  │          │
│   │                                                 │          │
│   │  やること:                                       │          │
│   │  ① 子機からのMQTTメッセージを受け取る             │          │
│   │  ② データをOracle Cloudに保存                   │          │
│   │                                                 │          │
│   │  必要なもの:                                     │          │
│   │  ・Raspberry Pi(カメラ不要)                    │          │
│   │  ・Mosquitto(MQTTブローカー)                   │          │
│   │  ・mqtt_oracle_bridge.py(ブリッジ)             │          │
│   │  ・Oracle接続情報                                │          │
│   └─────────────────────────────────────────────────┘          │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

STEP 1: 親機(中継機)のセットアップ

1-1. Mosquittoのインストール

text
┌─────────────────────────────────────────────────────────────────┐
│  親機のターミナルで実行                                          │
└─────────────────────────────────────────────────────────────────┘

# Mosquittoをインストール
sudo apt update
sudo apt install mosquitto mosquitto-clients -y

# 自動起動を有効化
sudo systemctl enable mosquitto

# 起動確認
sudo systemctl status mosquitto

1-2. Mosquittoの設定

text
┌─────────────────────────────────────────────────────────────────┐
│  /etc/mosquitto/conf.d/local.conf を作成                        │
└─────────────────────────────────────────────────────────────────┘

# 設定ファイルを作成
sudo nano /etc/mosquitto/conf.d/local.conf

# 以下の内容を書く
─────────────────────────────────
listener 1883
allow_anonymous true
─────────────────────────────────

# 保存して終了(Ctrl+X → Y → Enter)

# Mosquittoを再起動
sudo systemctl restart mosquitto

設定の意味:

text
┌────────────────────────────────────────────────────┐
│  listener 1883                                     │
│  → ポート1883で接続を待ち受ける                     │
│                                                    │
│  allow_anonymous true                              │
│  → パスワードなしで接続を許可                       │
│    (テスト環境用、本番では認証を設定推奨)          │
└────────────────────────────────────────────────────┘

1-3. 動作確認

text
┌─────────────────────────────────────────────────────────────────┐
│  親機でテスト(2つのターミナルを開く)                            │
└─────────────────────────────────────────────────────────────────┘

【ターミナル1】購読者になる
─────────────────────────────────
mosquitto_sub -t "test/#" -v
─────────────────────────────────
→ メッセージが来るのを待機...


【ターミナル2】発信者になる
─────────────────────────────────
mosquitto_pub -t "test/hello" -m "こんにちは!"
─────────────────────────────────


【ターミナル1に表示される】
─────────────────────────────────
test/hello こんにちは!
─────────────────────────────────

✅ これが表示されたら成功!

1-4. 親機のIPアドレスを確認

text
┌─────────────────────────────────────────────────────────────────┐
│  親機のIPアドレスを確認(子機の設定で使う)                        │
└─────────────────────────────────────────────────────────────────┘

hostname -I

# 例: 192.168.32.213
# このIPアドレスをメモしておく!

STEP 2: 子機(カメラ側)のセットアップ

2-1. 必要なライブラリをインストール

text
┌─────────────────────────────────────────────────────────────────┐
│  子機のターミナルで実行                                          │
└─────────────────────────────────────────────────────────────────┘

# paho-mqttをインストール
pip install paho-mqtt

# (カメラ関連も必要に応じて)
pip install opencv-python picamera2

2-2. 設定ファイルを作成

text
┌─────────────────────────────────────────────────────────────────┐
│  子機の config/settings.json                                    │
└─────────────────────────────────────────────────────────────────┘

{
    "mqtt": {
        "broker": "192.168.32.213",   ← 親機のIPアドレス
        "port": 1883,
        "topic_prefix": "equipment/status"
    },
    "equipment": {
        "sta_no1": "FACTORY01",       ← 工場コード
        "sta_no2": "LINE01",          ← ラインコード
        "sta_no3": "EQ001"            ← 設備コード(子機ごとに変える!)
    }
}

子機ごとに変える部分:

text
┌─────────────────────────────────────────────────────────────────┐
│                                                                 │
│   子機①: "sta_no3": "EQ001"                                     │
│   子機②: "sta_no3": "EQ002"                                     │
│   子機③: "sta_no3": "EQ003"                                     │
│                                                                 │
│   ※ sta_no3だけ変えれば、他の設定は同じでOK!                    │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

2-3. 接続テスト

text
┌─────────────────────────────────────────────────────────────────┐
│  子機から親機に接続できるかテスト                                 │
└─────────────────────────────────────────────────────────────────┘

# 子機のターミナルで実行
mosquitto_pub -h 192.168.32.213 -t "test/from_child" -m "子機から送信!"

# 親機のターミナルで確認
mosquitto_sub -t "test/#" -v

# 「test/from_child 子機から送信!」と表示されたら成功!

STEP 3: 親機にブリッジを設置

3-1. ブリッジの役割

text
┌─────────────────────────────────────────────────────────────────┐
│                  ブリッジが何をするか                             │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   子機からのMQTTメッセージ                                       │
│   ┌─────────────────────────────────────────────────┐          │
│   │  トピック: equipment/status/EQ001               │          │
│   │  データ: {                                      │          │
│   │    "mk_date": "20260205120000",                 │          │
│   │    "sta_no1": "FACTORY01",                      │          │
│   │    "sta_no2": "LINE01",                         │          │
│   │    "sta_no3": "EQ001",                          │          │
│   │    "t1_status": 1                               │          │
│   │  }                                              │          │
│   └─────────────────────────────────────────────────┘          │
│                          │                                      │
│                          ▼                                      │
│   ブリッジの処理                                                 │
│   ┌─────────────────────────────────────────────────┐          │
│   │  ① JSONデータを解析                              │          │
│   │  ② Oracle DBに接続                               │          │
│   │  ③ INSERT文でデータを保存                         │          │
│   └─────────────────────────────────────────────────┘          │
│                          │                                      │
│                          ▼                                      │
│   Oracle Cloud Database                                         │
│   ┌─────────────────────────────────────────────────┐          │
│   │  EQUIPMENT_STATUS テーブル                       │          │
│   │                                                 │          │
│   │  MK_DATE        | STA_NO3 | T1_STATUS           │          │
│   │  ────────────────────────────────────           │          │
│   │  20260205120000 | EQ001   | 1                   │          │
│   │  20260205120001 | EQ002   | 2                   │          │
│   │  20260205120002 | EQ003   | 1                   │          │
│   └─────────────────────────────────────────────────┘          │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

3-2. ブリッジの設定ファイル

text
┌─────────────────────────────────────────────────────────────────┐
│  親機の config/settings.json                                    │
└─────────────────────────────────────────────────────────────────┘

{
    "mqtt": {
        "broker": "localhost",        ← 自分自身(親機)
        "port": 1883,
        "topic": "equipment/status/#" ← すべての子機のデータを受信
    },
    "oracle": {
        "user": "ADMIN",
        "password": "YourPassword123",
        "dsn": "xxxxxxx_high",
        "wallet_path": "/home/pi/wallet"
    }
}

3-3. ブリッジを起動

text
┌─────────────────────────────────────────────────────────────────┐
│  親機でブリッジを起動                                            │
└─────────────────────────────────────────────────────────────────┘

cd /home/pi/color_detector_app
python mqtt_oracle_bridge.py

# ログが流れ始めたら成功
# [INFO] Connected to MQTT broker
# [INFO] Subscribed to equipment/status/#
# [INFO] Waiting for messages...

STEP 4: 全体の動作確認

4-1. データの流れを確認

text
┌─────────────────────────────────────────────────────────────────┐
│                    動作確認の手順                                │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   【準備】3つのターミナルを開く                                   │
│                                                                 │
│   ターミナル1(親機): Mosquittoのログを監視                      │
│   ─────────────────────────────────────────────                │
│   mosquitto_sub -t "equipment/status/#" -v                     │
│   ─────────────────────────────────────────────                │
│                                                                 │
│   ターミナル2(親機): ブリッジを起動                             │
│   ─────────────────────────────────────────────                │
│   python mqtt_oracle_bridge.py                                 │
│   ─────────────────────────────────────────────                │
│                                                                 │
│   ターミナル3(子機): 色検知プログラムを起動                      │
│   ─────────────────────────────────────────────                │
│   python color_detector.py                                     │
│   ─────────────────────────────────────────────                │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

4-2. 期待される結果

text
┌─────────────────────────────────────────────────────────────────┐
│                   正常に動いている場合                            │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   ターミナル1(MQTTログ):                                        │
│   ─────────────────────────────────────────────                │
│   equipment/status/EQ001 {"mk_date":"20260205120000",...}      │
│   equipment/status/EQ001 {"mk_date":"20260205120001",...}      │
│   ─────────────────────────────────────────────                │
│   → 子機からメッセージが届いている                               │
│                                                                 │
│   ターミナル2(ブリッジログ):                                    │
│   ─────────────────────────────────────────────                │
│   [INFO] Received: equipment/status/EQ001                      │
│   [INFO] Saved to Oracle: EQ001, status=1                      │
│   ─────────────────────────────────────────────                │
│   → Oracleに保存している                                        │
│                                                                 │
│   ターミナル3(子機ログ):                                        │
│   ─────────────────────────────────────────────                │
│   [INFO] Detected: GREEN (status=1)                            │
│   [INFO] Published to equipment/status/EQ001                   │
│   ─────────────────────────────────────────────                │
│   → 色を検知して送信している                                     │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

子機を追加するには?

text
┌─────────────────────────────────────────────────────────────────┐
│               子機を追加する手順(超簡単!)                       │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   1. 新しいRaspberry Piを用意                                    │
│                                                                 │
│   2. 同じプログラムをコピー                                       │
│      ─────────────────────────────────────────────             │
│      scp -r pi@子機1:/home/pi/color_detector_app .             │
│      scp -r color_detector_app pi@新しい子機:/home/pi/         │
│      ─────────────────────────────────────────────             │
│                                                                 │
│   3. settings.jsonのsta_no3だけ変更                             │
│      ─────────────────────────────────────────────             │
│      "sta_no3": "EQ004"  ← 新しい設備コード                     │
│      ─────────────────────────────────────────────             │
│                                                                 │
│   4. プログラムを起動                                            │
│      ─────────────────────────────────────────────             │
│      python color_detector.py                                  │
│      ─────────────────────────────────────────────             │
│                                                                 │
│   ※ 親機(中継機)の設定変更は不要!                              │
│   ※ Oracleの設定変更も不要!                                     │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

よくあるトラブルと解決方法

トラブル1: 子機から親機に接続できない

text
┌─────────────────────────────────────────────────────────────────┐
│  症状: Connection refused / Timeout                             │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  確認ポイント:                                                   │
│                                                                 │
│  ① 親機のIPアドレスは正しい?                                    │
│     → hostname -I で確認                                        │
│                                                                 │
│  ② Mosquittoは動いている?                                       │
│     → sudo systemctl status mosquitto                          │
│                                                                 │
│  ③ ファイアウォールでブロックされてない?                         │
│     → sudo ufw allow 1883                                      │
│                                                                 │
│  ④ 同じネットワークにいる?                                      │
│     → 子機から ping 192.168.32.213                              │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

トラブル2: Oracleに保存されない

text
┌─────────────────────────────────────────────────────────────────┐
│  症状: ブリッジのログにエラーが出る                               │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  確認ポイント:                                                   │
│                                                                 │
│  ① Walletのパスは正しい?                                        │
│     → ls /home/pi/wallet で確認                                 │
│                                                                 │
│  ② Oracle接続情報は正しい?                                      │
│     → settings.jsonのuser, password, dsnを確認                 │
│                                                                 │
│  ③ インターネットに接続できる?                                   │
│     → ping google.com                                          │
│                                                                 │
│  ④ テーブルは存在する?                                          │
│     → SQL DeveloperでEQUIPMENT_STATUSを確認                    │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

トラブル3: データが重複して保存される

text
┌─────────────────────────────────────────────────────────────────┐
│  症状: 同じデータが何度も保存される                               │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  原因: 子機が1秒に何度もデータを送信している                      │
│                                                                 │
│  解決方法:                                                       │
│                                                                 │
│  ① ブリッジ側で重複チェック(推奨)                               │
│     → 同一秒のデータはスキップする処理を追加                      │
│                                                                 │
│  ② 子機側で送信間隔を調整                                        │
│     → time.sleep(1) で1秒ごとに送信                             │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

全体の構成図(まとめ)

text
┌─────────────────────────────────────────────────────────────────┐
│                                                                 │
│   【子機① EQ001】        【子機② EQ002】        【子機③ EQ003】 │
│   192.168.32.100         192.168.32.101         192.168.32.102 │
│   ┌─────────────┐        ┌─────────────┐        ┌─────────────┐│
│   │📷 color_    │        │📷 color_    │        │📷 color_    ││
│   │  detector.py│        │  detector.py│        │  detector.py││
│   └──────┬──────┘        └──────┬──────┘        └──────┬──────┘│
│          │                      │                      │       │
│          │  Publish             │  Publish             │       │
│          │  equipment/          │  equipment/          │       │
│          │  status/EQ001        │  status/EQ002        │       │
│          │                      │                      │       │
│          └──────────────────────┼──────────────────────┘       │
│                                 │                              │
│                                 ▼                              │
│   【親機(中継機)】192.168.32.213                               │
│   ┌─────────────────────────────────────────────────────┐     │
│   │                                                     │     │
│   │   ┌─────────────────────────────────────────┐     │     │
│   │   │           Mosquitto (Broker)            │     │     │
│   │   │                                         │     │     │
│   │   │  equipment/status/# を受信              │     │     │
│   │   │  → EQ001, EQ002, EQ003... 全部受け取る   │     │     │
│   │   └────────────────────┬────────────────────┘     │     │
│   │                        │                          │     │
│   │                        ▼                          │     │
│   │   ┌─────────────────────────────────────────┐     │     │
│   │   │        mqtt_oracle_bridge.py            │     │     │
│   │   │                                         │     │     │
│   │   │  Subscribe: equipment/status/#          │     │     │
│   │   │  → 受信したデータをOracleに保存          │     │     │
│   │   └────────────────────┬────────────────────┘     │     │
│   │                        │                          │     │
│   └────────────────────────┼──────────────────────────┘     │
│                            │                                │
│                            │ HTTPS (インターネット)          │
│                            ▼                                │
│   ┌─────────────────────────────────────────────────────┐   │
│   │  ☁️ Oracle Cloud Database                            │   │
│   │                                                     │   │
│   │  EQUIPMENT_STATUS テーブル                           │   │
│   │  ┌────────────────────────────────────────────┐    │   │
│   │  │ MK_DATE        | STA_NO3 | T1_STATUS       │    │   │
│   │  │ ────────────────────────────────────────── │    │   │
│   │  │ 20260205120000 | EQ001   | 1 (稼働)        │    │   │
│   │  │ 20260205120000 | EQ002   | 2 (停止)        │    │   │
│   │  │ 20260205120000 | EQ003   | 1 (稼働)        │    │   │
│   │  └────────────────────────────────────────────┘    │   │
│   └─────────────────────────────────────────────────────┘   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

まとめ

構成のポイント

項目 内容
親機(中継機) Mosquitto + ブリッジを動かす
子機(カメラ) 色検知 + MQTT送信だけ
追加方法 sta_no3を変えるだけ
スケール 理論上は数百台まで対応可能

この構成のメリット

text
┌─────────────────────────────────────────────────────────────────┐
│                                                                 │
│  ✅ 子機の設定が簡単(IPアドレスとsta_no3だけ)                   │
│                                                                 │
│  ✅ 親機を1つ設定すれば、子機は何台でも追加可能                   │
│                                                                 │
│  ✅ Oracle認証情報は親機だけ(セキュリティ向上)                  │
│                                                                 │
│  ✅ ローカルネットワーク内で動作(高速・安定)                    │
│                                                                 │
│  ✅ インターネット障害でも子機→親機は動き続ける                   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

関連記事

関連記事