はじめに
メカトラックス株式会社のsaito2です。
当社は、ローム株式会社のエッジAI向けソリューション Solist-AI™ のエコシステムパートナーとして、Raspberry Pi Pico 2向けにSolist-AI™マイコン(ML63Q2557)を搭載した拡張基板を開発中です。
本記事では、試作段階のSolist-AI™マイコン搭載基板と、Raspberry Pi Pico 2互換のLTE通信モジュール一体基板 MicroCat.1を使った、異常振動検知 ⇒ LINE通知のデモシステムについて紹介します。
(※)MicroCat.1は2026年4月現在正式リリース前(プレリリース段階)の製品となります。
Solist-AI™の紹介
Solist-AI™(ソリストエーアイ)は、ロームがエッジコンピューティング分野に向けて提供するオンデバイスAIソリューションです。クラウドサーバーやネットワークに依存せず、エッジデバイス単体でリアルタイムの学習・推論処理を可能にします。
(こちらより引用抜粋)
Solist-AI™は、エッジ側で学習と推論を行えるため、現場ごとの環境差や機器の個体差にも柔軟に対応しやすい点が特徴です。
Solist-AI™マイコン(ML63Q2557)搭載基板
当社で開発しているSolist-AI™マイコン搭載基板はRaspberry Pi Pico 2とスタックして使用できるピンヘッダレイアウトを採用しており、手軽に組み合わせることができます。
拡張基板には、Solist-AI™マイコンのML63Q2557を採用しています。
このマイコンの特徴は、シンプルな3層ニューラルネットワークで構成される独自のハードウェアAIアクセラレータ : AxlCORE-ODLを搭載している点です。
これにより、サーバやクラウドに依存せず、センサの入力からマイコン単体でオンデバイス学習・推論を完結させることができます。
また、マイコン単体ではAI処理実行時の消費電力が約40mWと省電力性能も優れています。
ML63Q2557へのセンサの入力はSolist-AI™マイコン搭載基板に直接I2Cで接続する経路を用意しています。
Pico 2とはUART通信でコマンドの送受信や推論結果のやりとりを行います。
※試作段階のため、開発段階で仕様が変更となる可能性があります。
準備するもの
- Solist-AI™マイコン搭載基板
- MicroCat.1
- nanoSIMカード(本記事ではSORACOM SIMを使用)
- 加速度センサ(弊社から先日リリースいたしました。)
- 検知対象のファン(市販品)
MicroCat.1については以下の記事をご参照ください。
加速度センサについては以下をご参照ください。
システム概要
本記事で構築するシステムの概要は以下のとおりです。
- 市販のファンを稼働させた状態で、Solist-AI™マイコンに加速度センサの正常な振動パターンを学習させる
- 学習完了後、推論モードに切り替え、ファンの振動から出力される推論結果をMicroCat.1がLTE通信でクラウドに送り、常時監視する
- ファンの羽根に外乱を加えることで異常振動を発生させる
- Solist-AI™マイコンが異常を検知すると、LINEに通知する
データの送信先には SORACOM Harvest Data を使用し、異常発生時の通知先には LINE を使用します。
SORACOM Beamへの推論結果のデータ送信にはMQTTプロトコルを使用します。HTTPでもデータの送信自体は可能ですが、以下の理由からMQTTを使います。
- MicroCat.1が搭載するRP2350Bのような、リソースが限られたマイコンと相性が良い
- Pub/Subによる双方向通信が可能なため、将来的に遠隔からのMicroCat.1の制御にも応用しやすい
ハードウェアの準備
まずは、加速度センサについてOMRON XS3F コネクタをセンサに接続します。
接続の際はネジを十分に締めこんでください。
次に、Solist-AI™マイコン搭載基板のCN4にセンサーを接続し、CN1にDCジャック - XHP-2コネクタ変換ハーネスをCN1に取り付け、ACアダプタから電源を投入します。

※上図の基板は弊社での開発・評価用の試作環境のため、ジャンパ線による配線が含まれています。あらかじめご了承ください。
最後にMicroCat.1とスタックしてください。
ソフトウェアの準備
LINE Messaging APIの設定
本記事ではLINEを通知先として使用します。LINE Messaging APIの設定が必要ですので、以下を参考に設定してください。
LINE以外でも通知は可能ですが、今回は以下の理由からLINEを採用しました。
- Messaging APIがHTTPSのPOSTリクエストで送信でき、実装が容易
- 専用アプリの開発が不要(既存のLINEアプリでそのまま受信できる)
SORACOM Beam / AWS IoT Coreの設定
MQTTについてはSORACOMのBeamをエントリーポイントとして、AWS IoT Coreに転送しています。
SORACOM Beamを使いAWS IoT Coreに接続する手順は以下をご参照ください。
Beamを使う利点として、以下が挙げられます。
- 証明書などの認証情報をデバイスに保持する必要がない
- 通信経路の暗号化をデバイス側で用意する必要がない
- データ可視化用のHarvest Dataとも簡単に連携できる
MicroCat.1のセットアップ
MicroCat.1のセットアップは以下の記事を参考にしてください。
umqttライブラリのインストール
MicroCat.1でMQTTを使用するには、umqttライブラリのインストールが必要です。
インストールは以下のコマンドを実行してください。
import mip
mip.install('umqtt.simple')
以下のような出力が表示されたらインストール成功です。
Installing umqtt.simple (latest) from https://micropython.org/pi/v2 to /lib
Copying: /lib/ssl.mpy
Copying: /lib/umqtt/simple.mpy
Done
インストールはネットワークへの接続が必要です。実行前にネットワークに接続していることをご確認ください。
サンプルプログラム
以下のプログラムをMicroCat.1のmain.pyとして保存します。
from machine import Pin, UART
import json, time, requests, SIM7672, gc
from umqtt.simple import MQTTClient
# --- Solist-AI 動作モード定義 ---
MODE_STOP = 0 # 停止
MODE_LEARN = 1 # 初期学習
MODE_PREDICT = 2 # 推論
MODE_SEQ_LEARN = 3 # 逐次学習
CMD_QSTATE = b'QSTATE\n' # 状態問い合わせ
# --- LINE Messaging API 設定 ---
ACCESS_TOKEN = "YOUR_TOKEN" #ご自身のトークンに変更してください
USER_ID = "YOUR_ID" #ご自身のユーザーIDに変更してください
LINE_HEADERS = {
"Authorization": "Bearer {}".format(ACCESS_TOKEN),
"Content-Type": "application/json",
}
LINE_PUSH_URL = "https://api.line.me/v2/bot/message/push"
# --- MQTT 接続設定 (SORACOM Beam経由) ---
HOST, PORT, CLIENT_ID = "beam.soracom.io", 1883, b"microcat"
MQTT_USER, MQTT_PASSWORD = "sora", "sora"
# --- MQTT トピック定義 ---
STATE_TOPIC = b"topic/state" # 状態データ送信用
# --- Solist-AI基板の電源制御 ---
pw = Pin(2, Pin.OUT, value=0)
pw.value(1)
time.sleep(5)
# --- UART初期化 (Solist-AI基板との通信用) ---
uart = UART(0, baudrate=115200, tx=12, rx=13, timeout=1000, timeout_char=100)
current_mode = MODE_LEARN
last_notify_ms = None
def send_mode(mode, timeout_ms=500):
"""Solist-AI基板にモード切替コマンドを送信する"""
global current_mode
# 受信バッファをクリア
while uart.any():
uart.readline()
uart.write(f"M{mode}\n".encode())
started = time.ticks_ms()
while time.ticks_diff(time.ticks_ms(), started) < timeout_ms:
line = uart.readline()
if not line:
continue
kind = line.decode().strip()
if kind == "@OK_MODE":
current_mode = mode
return True, line
if kind == "@ERR":
return False, line
return False, "timeout"
def send_line_message():
"""LINE Messaging APIで異常検知メッセージを送信する"""
global last_notify_ms
now = time.ticks_ms()
#チャタリング防止のための通知インターバル
if last_notify_ms is not None and time.ticks_diff(now, last_notify_ms) < 5000:
return
last_notify_ms = now
payload = {
"to": USER_ID,
"messages": [{"type": "text", "text": "加速度センサから異常を検知しました!!"}],
}
post = None
try:
post = requests.post(
LINE_PUSH_URL,
headers=LINE_HEADERS,
data=json.dumps(payload).encode("utf-8"),
timeout=10,
)
finally:
if post:
post.close()
def mqtt_connect():
"""MQTTブローカーに接続する"""
c = MQTTClient(
CLIENT_ID, HOST, port=PORT,
user=MQTT_USER, password=MQTT_PASSWORD, keepalive=120,
)
c.connect()
return c
def lte_connect(modem):
"""LTE回線に接続する"""
modem.reset()
modem.active(True)
for _ in range(3):
modem.connect("soracom.io", "sora", "sora")
print("connecting...")
time.sleep(10)
if modem.isconnected():
print("connected")
return True
modem.disconnect()
return False
def run():
"""メインループ"""
modem = SIM7672.modem(debug=True)
modem.poweron()
lte_connect(modem)
mc = mqtt_connect()
# 起動時は学習モードで開始
send_mode(MODE_LEARN)
last_query = time.ticks_ms()
while True:
now = time.ticks_ms()
# 100msごとにSolist-AI基板の状態を問い合わせ
if time.ticks_diff(now, last_query) >= 100:
uart.write(CMD_QSTATE)
last_query = now
# Solist-AI基板からの応答を処理
if uart.any():
text = uart.readline().decode().strip()
print(text)
if text.startswith("@DONE_train"):
# 学習完了 → 推論モードへ自動遷移
send_mode(MODE_PREDICT)
elif text.startswith("@STATE"):
# 状態データをパースしてクラウドに送信
st = dict(t.split("=", 1) for t in text.split()[1:])
bl = int(st["baseline_loss"])
loss = int(st["loss"])
mc.publish(
STATE_TOPIC,
json.dumps({
"mode": int(st["mode"]),
"baseline_loss": bl,
"loss": loss,
}),
)
gc.collect()
# lossがbaseline_lossの102%を超えたら異常と判定
if loss > bl * 102 // 100:
gc.collect()
send_line_message()
time.sleep_ms(10)
if __name__ == "__main__":
run()
補足① Solist-AI™マイコン搭載基板のコマンド
Solist-AI™マイコン搭載基板は以下のコマンドでモードを制御できます。MicroCat.1からUART経由でこれらのコマンドを送信します。
| コマンド | 目的 | 応答 |
|---|---|---|
M0 |
停止モードへ遷移 |
@OK_MODE(成功時) / @ERR(失敗時) |
M1 |
初期学習モードへ遷移 |
@OK_MODE / @ERR / @DONE_train(学習完了時) |
M2 |
推論モードへ遷移 |
@OK_MODE / @ERR
|
QSTATE |
状態問い合わせ | @STATE mode=%u trained=%u baseline=%u infercounts=%u anomaly=%u loss=%d |
サンプルプログラムでは、起動後にまずM1(学習モード)で正常時の振動パターンを学習し、学習完了(@DONE_train受信)後に自動的にM2(推論モード)へ遷移します。推論モードでは100msごとにQSTATEで状態を問い合わせ、lossがbaseline_lossの102%を超えた場合に異常と判定しています。
補足② lossとbaseline_lossについて
変数 loss は、現在の加速度センサの値(振動パターン)が、学習時の正常状態とどれくらい一致しているかを数値化したものです。
loss が小さいほど正常状態に近く、loss が大きいほど学習時とは異なる振動パターンであることを示します。
一方、変数 baseline_loss は、正常状態として学習したときの loss の基準値です。
今回はこの baseline_loss を基準として、baseline_loss の 102% までを正常範囲として許容し、それを超えた場合に異常とみなしています。
動作結果
それでは、電源を投入し動作させます。

グラフの折れ線がlossを表しています。
ファンの羽根に外乱を加えるとlossの値が上昇しているのがわかります。
SORACOM Harvest Dataの最短更新間隔が5秒なので、lossの上昇には時間差があります。
また、lossの値が上昇したのと同時刻にLINE通知も来ていました。
おわりに
本記事では、ローム社のSolist-AI™マイコンを搭載した基板とMicroCat.1を組み合わせ、ファンの振動異常を検知してLINEに通知するシステムを構築しました。Solist-AI™のオンデバイス学習機能により、事前に大量のデータを用意することなく、稼働中の正常パターンをその場で学習させて異常検知を行えるのが大きな利点です。
また、ローム株式会社では、エッジAIを活用したアイデアコンテスト ROHM EDGE HACK CHALLENGE 2026 が開催されます。
弊社は、同コンテストの応募者向けに 今回紹介した基板の提供に協力いたします。(弊社提供基板の詳細はこちらに記載がございます。)オンデバイスAIとRaspberry Pi Pico2を組み合わせた開発に興味のある方は、ぜひ参加を検討してみてください。






