「市販のホームセキュリティは月額費用がかかる」「IoTカメラは海外製で信頼性が不安」——そんな理由で自分で防犯システムを作れないかと考えていたところ、M5Cardputerという小型デバイスに出会いました。手のひらサイズのキーボード付き端末と、Raspberry Piのセンサー検知能力を組み合わせることで、リアルタイムの見守り・防犯アラートシステムが自作できます。この記事では、システムの設計思想から実装コード、数日間の運用で見えてきた課題まで、実体験をベースに全手順を解説します。
システムの設計思想と全体構成
このプロジェクトを始めた動機は「安価で、カスタマイズ性が高く、クラウドに依存しない防犯システム」を作りたいという一点でした。既製品のIoTカメラはクラウドサーバーにデータが送られる仕組みのものが多く、プライバシー面で気になる点があります。自作すれば、データをローカルネットワーク内で完結させることができます。
システムは以下の2つのデバイスで構成されています。
- Raspberry Pi(サーバー側):人感センサーやカメラで動きを検知し、ログを記録・通知を送出する「検知・通知ハブ」
- M5Cardputer(クライアント側):手元の端末でリアルタイムに通知を受け取り、内蔵キーボードから特定コマンドを送り返してアラートを解除・制御する「操作端末」
2台のデバイスは同一Wi-Fiネットワーク内でHTTPリクエストを使って通信します。外部クラウドを使わないシンプルな設計のため、インターネット接続がなくても自宅のローカルネットワーク内であれば動作します。
必要な機材・環境
- M5Cardputer(M5Stack製のミニキーボード付きデバイス)
- Raspberry Pi 4 または 5(Raspberry Pi OS 導入済み)
- Python 3.10以上
- PIRモーションセンサー(HC-SR501などのパッシブ赤外線センサー)
- ジャンパーワイヤー・ブレッドボード(センサー接続用)
- Arduino IDE または PlatformIO(M5Cardputerのファームウェア開発用)
Raspberry Pi側の検知スクリプトを実装する
PIRセンサーの接続
HC-SR501はGPIOピンに直接接続できます。配線は以下のとおりです。
- VCC → Raspberry Pi 5V ピン(Pin 2)
- GND → Raspberry Pi GND ピン(Pin 6)
- OUT → Raspberry Pi GPIO18(Pin 12)
センサーの感度と遅延時間は、HC-SR501の基板上のポテンショメータで調整できます。私は感度を最大付近に設定し、検知後の待機時間を5秒程度に設定しました。
Python検知スクリプト
以下がRaspberry Pi側のモーション検知スクリプトです。
import RPi.GPIO as GPIO
import time
import requests
# センサーの設定
SENSOR_PIN = 18
M5CARDPUTER_IP = "192.168.1.XXX" # M5CardputerのIPアドレスに変更
M5CARDPUTER_PORT = 8080
GPIO.setmode(GPIO.BCM)
GPIO.setup(SENSOR_PIN, GPIO.IN)
def notify_m5cardputer():
"""M5CardputerにHTTP POSTで通知を送る"""
try:
payload = {
"event": "motion_detected",
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S"),
"location": "front_door"
}
resp = requests.post(
f"http://{M5CARDPUTER_IP}:{M5CARDPUTER_PORT}/alert",
json=payload,
timeout=5
)
print(f"通知送信: {resp.status_code}")
except Exception as e:
print(f"通知失敗: {e}")
def detect_motion(channel):
print(f"動きを検知しました! {time.strftime('%H:%M:%S')}")
notify_m5cardputer()
# ログをファイルに記録
with open("/home/pi/motion_log.txt", "a") as f:
f.write(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - Motion detected\n")
GPIO.add_event_detect(SENSOR_PIN, GPIO.RISING, callback=detect_motion, bouncetime=3000)
print("監視を開始します。Ctrl+Cで終了。")
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
GPIO.cleanup()
bouncetime=3000は同じ検知イベントが3秒以内に重複しないようにするデバウンス設定です。センサーの感度が高いと、1回の動きで複数の割り込みが発生することがあるため重要な設定です。
M5Cardputer側のUI・通知処理を実装する
M5CardputerはArduino(C++)でプログラミングします。内蔵のLCD画面に「ALERT」を表示し、内蔵スピーカーでアラート音を鳴らす処理を実装します。
#include <M5Cardputer.h>
#include <WiFi.h>
#include <WebServer.h>
#include <ArduinoJson.h>
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
WebServer server(8080);
// アラート表示フラグ
bool alertActive = false;
String alertTime = "";
String alertLocation = "";
void handleAlert() {
if (server.hasArg("plain")) {
DynamicJsonDocument doc(256);
deserializeJson(doc, server.arg("plain"));
alertTime = doc["timestamp"].as<String>();
alertLocation = doc["location"].as<String>();
alertActive = true;
server.send(200, "application/json", "{\"status\":\"received\"}");
}
}
void handleClear() {
alertActive = false;
server.send(200, "application/json", "{\"status\":\"cleared\"}");
}
void displayAlert() {
M5Cardputer.Display.fillScreen(RED);
M5Cardputer.Display.setTextColor(WHITE);
M5Cardputer.Display.setTextSize(2);
M5Cardputer.Display.setCursor(10, 20);
M5Cardputer.Display.println("!! ALERT !!");
M5Cardputer.Display.setTextSize(1);
M5Cardputer.Display.println(alertTime);
M5Cardputer.Display.println(alertLocation);
M5Cardputer.Display.println("[C]lear Alert");
// アラート音
M5Cardputer.Speaker.tone(1000, 500);
}
void setup() {
M5Cardputer.begin();
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
server.on("/alert", HTTP_POST, handleAlert);
server.on("/clear", HTTP_POST, handleClear);
server.begin();
M5Cardputer.Display.setTextColor(GREEN);
M5Cardputer.Display.println("Monitoring...");
M5Cardputer.Display.println(WiFi.localIP().toString());
}
void loop() {
M5Cardputer.update();
server.handleClient();
if (alertActive) {
displayAlert();
// 'C'キーでアラート解除
if (M5Cardputer.Keyboard.isKeyPressed('c')) {
alertActive = false;
M5Cardputer.Display.fillScreen(BLACK);
M5Cardputer.Display.setTextColor(GREEN);
M5Cardputer.Display.println("Monitoring...");
}
}
delay(100);
}
M5Cardputerの内蔵キーボードで「c」キーを押すと、アラートが解除されてモニタリング状態に戻ります。これが「自作ならではの操作性」で、市販のスマホアプリ連動型セキュリティシステムにはない、物理デバイスならではの即時性があります。
運用してみて分かったこと——実際の使い心地と課題
このシステムを実際に数日間、玄関前の廊下に設置して運用してみました。率直な感想を書きます。
良かった点
- レスポンスの速さ:センサー検知からM5Cardputerへの通知まで1〜2秒以内。スマートフォンのプッシュ通知よりも速い
- 物理デバイスの直感性:テーブルに置いてあるM5Cardputerが光ってアラート音が鳴る、という体験は手元のスマホをいちいち確認するより気づきやすい
- ローカル完結の安心感:データがクラウドに上がらないため、プライバシーの不安がない
- カスタマイズの自由度:コードを直接触れるので、「特定の時間帯だけ監視する」「ログをCSVで記録する」などの改造が自由にできる
改善が必要な点と今後の計画
- 誤検知問題:日中の日差しの変化やペットの動きでも反応することがある。PIRセンサーの感度調整と、カメラ画像との組み合わせで改善予定
- 電源周り:Raspberry Piを常時起動しておく必要があるため、消費電力が気になる。Raspberry Pi Zeroへの移行を検討中
- 外出先からのアクセス:現状はローカルネットワーク内でしか動作しない。VPNかngrokを使って外部からもアクセスできるようにしたい
- カメラ連携:検知時の静止画をRaspberry Pi Cameraで撮影してM5Cardputerに表示する機能を追加予定
- LoRaによる長距離通信:Wi-Fiが届かない庭先や駐車場への展開のため、LoRaモジュールの活用を検討
まとめ——DIY防犯システムのリアルな評価
M5Cardputerを活用した見守り・防犯アラートシステムの構築手順をまとめます。
- Raspberry Pi + PIRセンサーで動き検知スクリプト(Python)を実装
- 検知時にHTTP POSTでM5Cardputerのローカルサーバーに通知
- M5CarpduterでWebServerを立ち上げ、LCD表示・アラート音・キー操作での解除を実装
- 同一Wi-Fiネットワーク内で両デバイスを接続して運用開始
総材料費はRaspberry Pi、M5Cardputer、PIRセンサーを合わせて1万5千円前後です。月額費用ゼロで、自分仕様にカスタマイズできる防犯システムとしては十分なコストパフォーマンスだと感じています。
詳しいコードや配線図はGitHubで公開予定です。質問・要望はコメントかX(@miyoshitan)にどうぞ。
#M5Cardputer #RaspberryPi #IoT #防犯システム #自作セキュリティ #Python #Arduino #DIY電子工作