🍉

PCレスでSDカードをバックアップするポータブルデバイスを作った

に公開

概要

私はよく一眼レフで撮影するのですが、RAWで撮っている関係ですぐSDカードがいっぱいになります。出先で一杯になったらPCに接続して中身をコピーしているのですがPCを持ち歩くのが大変なので、「出先で簡単にバックアップできるやつないかなぁー」と思って作ってみました。それっぽい製品は無くはないのですがすでに生産が終わっていて手に入らない感じでした。

そこで今回はそのデバイスと詰まったポイントを紹介します。

基本設計

  • 持ち歩ける大きさである事
  • モバイルバッテリーで稼働できる事

という事で初のRaspberry Piに挑戦しました。そこにファイルをコピーする用のプログラムと操作用の基板を作るという構想で進めました。
ファイルコピー自体もただSSDに移すのではなく、ハッシュ値を計算してコピー後にベリファイをすることでちゃんとコピーできたことを保証する感じにしました。

大変だったポイント

pipでパッケージが入れられない

初のRaspberry Piだったので知らなかったのですがOSの標準パッケージツール(aptとかyum)以外でいれる場合に警告が出るようになったのでpipで外部パッケージを入れられなくて焦りました。
「仮想環境を作るように」という警告が出るのでpython -m venv .envで環境を別に作る事で回避できました。

failed to add edge detectionエラー

ボタンを押したか否かの監視を組む時、signal.pause()をかけているにも関わらず処理が先に進んでしまう現象に遭遇しました。色々探るとGPIO.add_event_detect自体が実行できていない事に気づき、例外をキャッチさせて中身を見るとfailed to add edge detectionというエラーが発生していました。どうやらこの関数はsudoなしでは動いてくれないようです。
なのでプログラムそのものをsudoで実行させようと考えたのですがそうなると今度はPythonの環境もrootで起動することになるのでPythonの仮想環境ではなくシステムの方で動いてしまったり、パスの参照や環境変数なども一般ユーザーと別になってしまってめちゃくちゃ面倒になってしまいました。
なので1つのプログラムで行うことは諦め、ボタン監視のみのスクリプトを別に用意し、コピー自体はpipパッケージでインストールしてコマンドラインから動かせるようにしました。pipパッケージを作る時にpyproject.toml方式で作ってみたのですがすごく簡単でした。なおかつ他のパッケージ設定も同じtomlに書けるので設定ファイルが散らばらずに便利でした。

import os
import signal
import sys
import RPi.GPIO as GPIO
import subprocess

BUTTON_GPIO = 26


def signal_handler(sig, frame):
    GPIO.cleanup()
    sys.exit(0)


def button_pressed_callback(channel):
    cmd = "実行したいコマンド"
    result = subprocess.run(cmd, shell=True, capture_output=True, encoding="utf-8")
    print(result.stdout, end="")
    print(result.stderr, end="")


if __name__ == "__main__":
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(BUTTON_GPIO, GPIO.IN, pull_up_down=GPIO.PUD_UP)

    GPIO.add_event_detect(
        BUTTON_GPIO,
        GPIO.FALLING,
        callback=button_pressed_callback,
        bouncetime=500,
    )

    signal.signal(signal.SIGINT, signal_handler)
    signal.pause()

ボタン監視スクリプトはこんな感じです。このスクリプトをRaspberry Pi起動時に実行するようにサービス化しました。

ディスプレイに表示させすぎてパフォーマンスダウン

進捗表示用にSSD1306の小さいディスプレイを使っていたのですが、ただ進捗を表示しているだけなのにすごい遅くなっていました。
これは単純にディスプレイへの表示命令が多すぎてパンクしていただけでした。IoTに慣れてないが故に普段通りの感じでやってしまっていました。反省。
ここは大人しく更新速度をめちゃくちゃ下げたり、表示したい項目を削ったりする事で回避しました。

基板設計

これは「Dynamic Draw」というアプリを使いました。こんな感じ。

表の方で部品と配線を書き込んだら丸ごとグループ化して左右反転させる事で裏側の配線も確認できるようになります。これは非常に便利でした。

最後に

今回初めてRaspberry Piを使ってみたのですが非常に面白かったです。何より低スペックのPCでも開発できるという所が良いですね。GPUモリモリじゃないとだめだとか、メモリがモリモリじゃないと駄目だとかそういう障壁が無く、普通のノートPCでこういったデバイスを作れるというのが非常に面白かったです。
IoTならではの注意ポイントもあって、ただ自分の欲しいものを作るだけで終わるのではなく勉強にもなりました。これはハマりそう。

Discussion