ラズパイ+Picoの低電力IoTシステムを自作(1)

太陽電池と鉛蓄電池の電源で屋外にIoTシステムを構築したいと思います。電源については別途シリーズで記事を書きますので、そちらを参照ください。ラズパイは小型ながら高性能コンピュータでIoTシステムを組むのに非常に威力を発揮するのですが、屋外の心細い電源環境で使用するには電力を食い過ぎるのかもしれません。ちなみにラズパイのスタンバイ電力が2.7Wとのことですので、例えば12V5Vhの鉛蓄電池では一日も持たないことになります。

一方でラズパイの弟分(?)のラズパイPicoはスタンバイ状態で0.15W、ディープスリープ状態では0.01W程度のようです(ディープスリープでRaspberry Pi Pico Wを低電力化する)。この2つを組み合わせることで低電力かつ高性能なIoTシステムが構築できるのではないか、というのが今回の話題のモチベーションです。例えばラズパイPicoで赤外線センサーを監視し、何かを検知したときにラズパイを起動してカメラ撮影して、撮影が終わったらラズパイをシャットダウンする、というような仕組みです。このシステムを以下の順番で構築してみます。

  • ラズパイの設定:ラズパイの2番ピンに5V電圧が供給されたらラズパイが起動し、カメラで写真撮影・クラウド(GCP CloudStorage)に保存後、シャットダウン
  • Picoの設定:人感センサーでディープスリープを抜けるように設定。復帰したらラズパイ用の電源を供給。指定時間後、ラズパイ用電源を切断の上ディープスリープに入る。

起動時にプログラムを実行する方法はラズパイには複数用意されていますが、現在推奨されているsystemdサービスを使う方法を使います。以下のファイルをラズパイの「/etc/systemd/system/」フォルダ下に 「capture.service」として保存します。

[Unit]
Description=Camera Capture and Shutdown Service
After=network.target

[Service]
Type=oneshot #起動時に1回だけ実行
User=root
ExecStart=/usr/bin/python3 /path/to/your/camera_script.py #起動時に実行したいファイル
ExecStartPost=/sbin/shutdown -h now
StandardOutput=append:/home/pi/camera_capture.log
StandardError=append:/home/pi/camera_capture_error.log

[Install]
WantedBy=multi-user.target

その後ターミナルにて以下を実行することで、起動時に「camera_script.py」が実行されるようになります。

sudo systemctl enable capture.service
sudo systemctl start capture,service

サービスを停止するには以下を実行します。

sudo systemctl stop capture.service
sudo systemctl disable capture.service

camera_script.pyは以下です。

from picamera2 import Picamera2
import time
import os

def capture_and_shutdown():
    try:
        picam2 = Picamera2()
        config = picam2.create_still_configuration()
        picam2.configure(config)
        picam2.start()
        time.sleep(2) #カメラの安定化を待機
        timestamp = time.strftime("%Y%m%d_%H%M%S")
        filename = f"/home/pi/images/capture_{timestamp}.jpg"
        picam2.capture_file(filename)

        picam2.stop()
        picam2.close()
        
        # 画像撮影後にシャットダウン
        os.system("sudo shutdown -h now")
    
    except Exception as e:
        # エラーログ
        with open("/home/pi/camera_error.log", "w") as log:
            log.write(str(e))
        
        # エラー時も強制シャットダウン
        os.system("sudo shutdown -h now")

if __name__ == "__main__":
    capture_and_shutdown()

これでラズパイの設定は終了。次回はPicoと電気回路についてです。