RaspberryPiでRTCとボタンでON/OFF
はじめに
RaspberryPiを使用して開発を行っていますが、ネットに繋がらない環境では、RTCが無いので時刻があわなかったり、USB接続で電源入りだったり、切る時もGUIやコマンドの使用が必要だったりで、製品としては足りない点があると思ってました。この辺の対応を行って後に、製品としての作りこみが出来ると思います。
実は、RTCや電源の管理を行ってくれる増設ボードというのは巷に販売してまして、当初はそういった物を使用していましたが、入手が困難であったり、値段が高かったりしたので、RTCだけ購入して後は自前実装をチャレンジしてみました。
構成
今回はRTCを外付けしています。
型名 | 購入元 | URL |
---|---|---|
ds1307 | スイッチサイエンス | https://www.switch-science.com/products/5334 |
選択理由は安かったからです。発注後に2~3日で届きました。
こいつには電池が必要です。CR1225リチウム電池を使用しろと記載されていますが、電気屋さんには売ってませんでした。でも多分CR1220で代用可能と思います(自信無)。
接続
RTC側のピン配置は、スイッチサイエンスさんのページに記載があったので引用
RaspberryPiのピン配置は以下の通りなので、
(RaspberryPi公式ドキュメントから引用)
赤い四角の場所に、RTC基盤を差して下さい。電源が付いてる側がRaspberryPiの中側になる様にして下さい。
GPIOの表記がRTC側では「GPIO07」と記載がある点が、RaspberryPi側では「GPIO3」となっていますが、これはRTC側の記載が間違っていますので、気にしないで下さい。
RTCの設定
RaspberryPi設定にてRTCを有効とする
RaspberryPiを起動して、メニューより「設定」「RaspberryPi設定」を選択してください。表示されたウィンドウ内で「インターフェース」タブにある「I2C」有効として下さい。
必要なパッケージのインストール
sudo apt install i2c-tools -y
sudo apt install ntpdate -y
yオプションは、いちいちYes or Noを聞かれない為の物です
RTCの登録
modulesファイルにRTCを登録します。nanoでもvimでもいいので、「/etc/modules」ファイルを開いて最後に
rtc-ds1307
を追記して下さい。
RTC認識しているかを確認
sudo i2cdetect -y 1
オプションに記載している1は、i2Cの1を確認という意味です。
結果は、
UUは誰かが使用中という意味。私の環境では設定が終わっているので、UU表示となっていますが、未設定の場合には、0x68とかの記載です。
これで認識されている事は分かったので、後はRTCに時間を設定してあげます。
sudo timedetectl set-time "2022-10-01 15:01:01"
最終に時間の確認
sudo timedatectl
電源ONボタン
次に電源ONボタンを実装します。SWは適当なものを使用して下さい。
実はRaspberryPiの標準の機能として電源ONボタンの対応があって、GPIO3とGNDを短絡する事で、電源がONされます。
なので、GPIO3とGND間にSW接続です。
接続
RTCで使用しているi2cとGPIOが同じピンで重なっているので、別のGPIOを使用したい所ですが、ONに関してはGPIO3から変更が出来ないみたいです。
電源OFFボタン
GPIOに接続したSWが押されたら、電源を切る処理を実施するようにします。GPIOのポートを常時監視するので、RTCとの共存は出来ません。なのでRTCで使用していないポートをGPIO使用とします。今回は、どこでも良いのですが、GPIO3のそばにあるGPIO4にします。またボタン1つでON/OFFを行うようにします。
接続
5番と7番を短絡しただけです。これでSWをONとすると、5番pinも7番pinもGNDと短絡されます。電源OFF操作は5版pinがi2c使用している状態で7番pinともどもGNDに短絡するので、多分この瞬間i2cの通信はエラーとなると思いますが、電源切り前に時計合わせする必要も無いでしょうから、良しとしました。
実装
Pythonで記述しています。GPIO4番pinを常時監視して、ONされたら、shutdownコマンドを即時実行、みたいな事してます。
import time
import RPi.GPIO as GPIO
import os
pinnumber = 4
GPIO.setmode(GPIO.BCM)
#GPIO 入力モードとし、pull up設定
GPIO.setup(pinnumber, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.wait_for_edge(pinnumber, GPIO.FALLING)
sw_counter = 0
while True:
sw_status = GPIO.input(pinnumber)
if sw_status == 0:
sw_counter = sw_counter + 1
if sw_counter >= 50:
os.system("sudo shutdown -h now")
else:
sw_counter = 0
time.sleep(0.02)
これをcrontabにでも記載しておいて、RaspberryPi起動した際に、実行するようにすればOK
Discussion