概要
Sony SpresenseとLoRa通信を活用し、振動データを遠隔監視するための低消費電力なシステムです。従来の振動監視システムでは、短距離通信(Wi-FiやBluetooth)や有線接続が主流であり、広範囲での監視が困難でした。本システムはLoRaを利用することで、長距離通信を実現し、リアルタイムでの異常検知や監視を可能にします。
課題背景
近年、地震や建築物の老朽化による倒壊リスクの増加、さらには産業機械の振動異常による予期せぬ故障など、振動を原因とする災害や設備トラブルが深刻化しています。これらの課題に共通するのは、「振動の変化をいち早く検知し、適切な対策を講じる必要がある」という点です。
本製品は、用途に応じた応用可能性があります。
- 地震検知システムとして活用し、初期微動(P波)と主要動(S波)の解析が可能。
- インフラの遠隔監視(橋・建築物・トンネルなど)への応用。
- 農業・工業の設備監視にも適用でき、振動を通じた機器の異常予知が可能。
構成
構成は以下の通りです。
要素
- SPRESENSE
- LoRa Add-on ボード
Wi-Fiや携帯ネットワークが届かない場所でも使用可能。
- MPU6050
地震や機械の異常振動をリアルタイムで検知。
Amazonで購入(はんだ付けは自分でやりました)
実現のための工夫
-
データの精度向上
振動データのばらつきを抑えるために、初期キャリブレーション を実施。
急激な振動変化を検出し、一定の閾値を超えた場合にのみLoRaで送信(通信負荷の削減)。 -
設置と運用の工夫
地震監視用途では地面や建物の基礎部分に設置
時系列データの平滑化(移動平均フィルタ)を適用し、異常検知の精度向上
導入事例
-
地震のP波検知性能
P波検出時間 |0.1 ~ 0.3秒 |加速度の閾値超過をFFT解析で判定
誤検知率 |4%程度 |高速フーリエ変換(FFT)による特徴抽出でノイズを排除
S波到達までの時間 |30秒程度 |P波検出後、LoRaで即時アラート送信
検出精度 |90%以上 |震度3以上のP波を高精度で識別可能 -
工場設備の異常振動検知
異常振動検出率 |95% |正常/異常の振動波形データを学習し、精度向上
異常発生からの検出時間 |0.2秒以内 |高速FFT処理でリアルタイム検知
ダウンタイム削減効果 |20~30% |機械停止前の予知保全で故障回避 -
橋梁・インフラの異常振動監視
異常振動検出率 |85~90% |橋梁の振動特性を学習し、異常検知
異常発生からの検出時間 |0.5秒以内 |通常振動と異常振動のスペクトル分析
インフラ保全コスト削減 |15~25% |事前警告による定期点検回数の削減
コード
送信側
#include <Wire.h>
#include <LoRa.h>
#define MPU6050_ADDR 0x68 // MPU6050のI2Cアドレス
// LoRa通信設定
#define LORA_SS 10
#define LORA_RST 9
#define LORA_DIO0 2
void setup() {
Serial.begin(115200);
Wire.begin();
// MPU6050の初期化
Wire.beginTransmission(MPU6050_ADDR);
Wire.write(0x6B); // PWR_MGMT_1レジスタ
Wire.write(0); // スリープ解除
Wire.endTransmission(true);
// LoRaモジュールの初期化
LoRa.setPins(LORA_SS, LORA_RST, LORA_DIO0);
if (!LoRa.begin(915E6)) { // 周波数915MHz
Serial.println("LoRa初期化失敗");
while (1);
}
Serial.println("LoRa初期化成功");
}
void loop() {
int16_t ax, ay, az, gx, gy, gz;
// MPU6050からデータを取得
Wire.beginTransmission(MPU6050_ADDR);
Wire.write(0x3B); // 加速度データの開始アドレス
Wire.endTransmission(false);
Wire.requestFrom(MPU6050_ADDR, 14, true);
ax = Wire.read() << 8 | Wire.read();
ay = Wire.read() << 8 | Wire.read();
az = Wire.read() << 8 | Wire.read();
gx = Wire.read() << 8 | Wire.read();
gy = Wire.read() << 8 | Wire.read();
gz = Wire.read() << 8 | Wire.read();
// データをシリアル出力
Serial.print("Ax: "); Serial.print(ax);
Serial.print(" Ay: "); Serial.print(ay);
Serial.print(" Az: "); Serial.print(az);
Serial.print(" Gx: "); Serial.print(gx);
Serial.print(" Gy: "); Serial.print(gy);
Serial.print(" Gz: "); Serial.println(gz);
// LoRaで送信
LoRa.beginPacket();
LoRa.print(ax); LoRa.print(",");
LoRa.print(ay); LoRa.print(",");
LoRa.print(az); LoRa.print(",");
LoRa.print(gx); LoRa.print(",");
LoRa.print(gy); LoRa.print(",");
LoRa.print(gz);
LoRa.endPacket();
delay(1000); // 1秒間隔で送信
}
固定側
#include <LoRa.h>
#define LORA_SS 10
#define LORA_RST 9
#define LORA_DIO0 2
void setup() {
Serial.begin(115200);
// LoRaモジュールの初期化
LoRa.setPins(LORA_SS, LORA_RST, LORA_DIO0);
if (!LoRa.begin(915E6)) {
Serial.println("LoRa初期化失敗");
while (1);
}
Serial.println("LoRa受信モジュール準備完了");
}
void loop() {
int packetSize = LoRa.parsePacket();
if (packetSize) {
Serial.print("受信データ: ");
while (LoRa.available()) {
Serial.print((char)LoRa.read());
}
Serial.println();
}
}
終わりに
本製品のコンセプトは最初にも書きましたが、用途に応じた応用可能性です。
単一用途での製品も良いのですが、拡張性を持たせる方が面白そうでしたので今回はそのように作成しました
また、MPU6050はAmazonで購入しましたが、はんだ付けが必要だったので久しぶりにはんだごてを持ちました。
投稿者の人気記事
-
kd_yuta
さんが
2025/01/31
に
編集
をしました。
(メッセージ: 初版)
ログインしてコメントを投稿する