今回設計する基板
ラズベリーパイ用のUPS(無停電電源装置)HAT基板です。
停電等で電源が遮断された場合にバッテリーからラズベリーパイに5Vを供給します。
その間にシャットダウンを実行することで、SDカードやデータの破損を防ぐことが可能です。
ラズパイ工房 RaspberryPi用 UPS(無停電電源)HAT基板 (https://raspikoubou.theshop.jp/items/94650013)
ラズベリーパイの電源をブチ切りすると壊れることがある
ラズベリーパイでシャットダウンをせず電源をブチ切りすると、稀にSDカードが壊れることがあります。
自分が経験したのは、SDカード自体が壊れたのではなく、OS起動に大事なファイルが壊れたことで起動しないことがありました。
色々調べましたが、SDカードに新たにOSを焼き直すしかありませんでした...(windowsのセーフモードみたいなうやつ無いんですかね?)
そこで、今回はラズパイで簡易UPS基板を作成し、うっかりブチ切りしたしまった場合や停電した場合に、ラズベリーパイが安全にシャットダウンを行えるようにしようと思います。
UPS(無停電電源装置)とは
UPSとは無停電電源装置の略称です。
工場で生産した製品のデータを収集しているサーバーなど、データ壊れてしまうと困る物に使用します。無停電電源装置(UPS)を使うと、停電や電圧の変動が起きた際に電力を一時的に供給し、機器を安全にシャットダウンする時間を確保できます。これにより、作業中のデータが失われたり、機器が故障するリスクを軽減でき、重要なデータや機器を守ることができます。
下図のようなしっかりした物だと、ピンキリですが、うん十万円します。
NTTファシリティーズ(https://www.ntt-f.co.jp/service/ups/about/)
今回作った回路図
いきなりですが、今回作成した回路概要を下図に載せます。
一般的なUPSだと、電源正常時の電源ルートと、電源異常時の電源ルートを作成して、電源遮断時に即座に電源異常時のルートに切り替えるような回路だと思いますが、今回はできる限り簡素な構成にして、安価なUPS回路を目指しました。
今回作成した回路では、電源正常時と電源異常時のルートを共通にしています。そうすることで、電源異常時にFET等でルートを切り替える必要がなく部品点数が減っています。また、切替時の瞬間的な電源遮断が起こりません。
また、常にバッテリからの電力供給が可能なので、数秒間であれば入力電源の出力可能電力以上の電力を供給できたり、電源安定の効果も期待できます。
ですが、その代わりに常に昇圧回路が働いているなど、無駄な消費電力が増えてしまっています。
では、以下回路の各ブロックの設計を説明していきます。
OMRON UPS回路(https://www.fa.omron.co.jp/products/family/3450/network.html)
今回作成した回路概要
バッテリは電気二重層コンデンサ
普段スマホをよく使う皆さんが"バッテリー"と聞いてイメージするのはスマホを充電するモバイルバッテリーじゃないでしょうか。あれはリチウムイオン電池という電池を使っています。リチウムイオン電池は他には電気自動車やノートPCにも使われていますね。
ですが、今回はリチウムイオン電池ではなく、電気二重層コンデンサを使うことにしました。電気二重層コンデンサはパソコンのマザーボードや商業用電源についているアルミ電解コンデンサの大容量版のような物です。
電気二重層コンデンサ
日本ケミコン株式会社 電気二重層キャパシタの基礎知識(https://www.chemi-con.co.jp/products/edlc/knowledge.html)
今回は下記の理由で電気二重層コンデンサを使うことにしました。
・ラズパイのシャットダウンの時間稼ぎができればよいので、コンデンサのエネルギー密度で十分。
・コンデンサの方が短絡等が発生した時に発火や爆発のリスクが少ない。
・寿命が来てUPSが働かなかったなんてことが無いようにしたい。コンデンサなら5~10年持つ。
・コストが低い。
・充電が間に合わずUPSが働かなかったなんてことは避けたい。コンデンサなら充電が早い。
UPS回路
充電電流制限抵抗
電気二重層コンデンサの充放電カーブは下図のようになります。電源投入時のコンデンサは空で0Vとなります。
ですので、下図の回路図で電流制限抵抗が無いと、入力電源(ACアダプタ等)の5Vが0Vのコンデンサに直結するので、大きな突入電流が流れ、さらに充電が溜まるまでラズベリーパイへの電源が5V未満になってしまいます。
電流制限抵抗は20Ωとしました。コンデンサが空の時の充電電流は 5V/20Ω = 250mA となります。コンデンサの電圧は充電されるにつれて上がっていきますので、(5V-Vc)/20Ω と充電電流は小さくなっていきます。
この充電に必要な電力に加え、同時にラズベリーパイへの電力も必要ですので、入力電源は多少余力のある物を選ぶ必要があります。
入力電源遮断時にこのコンデンサから電力供給する場合、この電流制限抵抗が出力抵抗になってしまうのでまともに電力供給ができなくなってしまいます。
ですので、出力用にショットキーバリアダイオードを実装しています。ダイオードでの損失は避けられませんが、FET等で制御する必要が無いので楽ちんです。
回路概要 再UP
昇圧回路
コンデンサは満充電時に約5Vとなりますが、入力電源遮断時にコンデンサから電力供給するにつれて電圧が下がっていきます。ですので、単純にコンデンサをラズベリーパイの電源に繋ぐだけではすぐにラズベリーパイの必要電圧未満になりシャットダウンまでの時間を稼ぐことが出来ません。
そこで昇圧回路を実装しています。これでコンデンサが5V未満になっても電力を引き出してラズベリーパイに5Vを供給することができます。ですが、前述した通り、簡素化のため入力電源正常時も常にこの昇圧回路が働くような回路にしているため損失が発生し、定常的な消費電力が少し大きくなってしまっています。
昇圧回路にはTexas InstrumentsのTPS61230Aを使用しています。
これなら入力電源正常時は最大5V6A、電源遮断時はコンデンサが2.5Vでも2.4A供給することが出来ます。ラズベリーパイには十分でしょう。
データシートより
このIC、TPS61230Aは下図の通りデータシートに推奨部品の型式が載っており、推奨パターンまで載っています。
この通りに作ればいいだけ...なんて楽なんだ。
この型式の部品が入手できなくても、データシートにそれぞれの部品をどのように選定すればよいかが記載されていますので、しっかり読んで代替品を選べば問題ありません。
データシートより 推奨部品
データシートより 推奨パターン
電源遮断検知
UPS回路があっても、電源遮断を検知してシャットダウンを実行することができなければ意味がありません。
この基板では下図のようにGPIO27で電源が入っているか入っていないかを知ることができるようにしてあります。
GPIOの定格は3.3Vですので、5VをR8,9(下図回路図参照)で分圧してGPIOに入力しています。C11は瞬間的な電源のブレでシャットダウンしないようにするための対策(おまじない)です。
D2は電源遮断を検知するための大事なショットキーバリアダイオードです。このダイオードが無いと、電源遮断が起きてもUPS回路が働き5Vが維持されてしまい、GPIO27にHIGHが入力され電源遮断を検知することができません。このダイオードがあることで、電源遮断時にGPIO27がLOWになります。
ショットキーバリアダイオードは順方向電圧が低く損失が小さいですが、リーク電流が大きいデメリットがあります。ですので分圧抵抗には2kΩと少し小さめの抵抗にしています。大きい抵抗値にしてしまうとリーク電流で電圧が発生し電源遮断を検知できなくなってしまいます。
ダイオードには他にもいくつか役割があります。
・電源の逆接続防止
・電圧降下することで電気二重層コンデンサの定格に対して余裕ができる(蓄積できるエネルギーも小さくなるが)
・昇圧ICの推奨入力電圧が4.5Vなので電圧を下げる
回路図の電源遮断を検知する部分
完成した回路図
作成した詳細の回路図が下図になります。
今まで説明した各要素を組み合わせたものになります。興味あればご覧ください。
完成した回路図
完成した基板で色々実験
完成した基板が下図になります。大分簡素になったかなと思います。
電気二重層コンデンサは立てると邪魔なので、横に曲げて実装しています。
電源用の端子は利便性のためにネジ端子とUSB-Cの2つを付けました。もちろん使うのは片方だけです。USB-Cの方はPDには対応していませんので、電源によっては5V給電できないので注意です。
ネジ端子とUSB-Cの間のパッドは何かって?ただのオシャレですよ(白目)。
これから下記の実験をしてみようと思います。
・UPS基板有り無しでの消費電力の差
・電源正常時/遮断時の出力電圧
・バックアップ可能時間
・充電にかかる時間
・電源遮断を検知してシャットダウンを実行
完成した基板をラズベリーパイ5に載せた写真
UPS基板有り無しでの消費電力の差
ラズベリーパイ5にUPS基板を載せた場合と載せない場合(つまりどノーマル)で、直流安定化電源から5Vを供給し、直流安定化電源に表示される消費電力を比較しました。
UPS基板ありの場合は、バッテリーの電気二重層コンデンサが満充電になるまで待機し、コンデンサへの充電電力は除いています。
結果が下図です。予想通り、昇圧回路が常に働いていたりダイオードでの損失があるため、UPS基板ありですと10~20%程度消費電力が大きくなってしまっています。
UPS基板使った場合とノーマルラズベリーパイ5の消費電力
電源正常時/遮断時の出力電圧
ちゃんと安定した5V電源が昇圧回路から出力されているか調べてみました。
下図は電源正常時と遮断時の出力電圧をオシロスコープで見てみた結果です。
電源正常時に高周波のスイッチングノイズのようなものが見られますが、バックアップ時には見られないので、恐らくUPS基板に5Vを入力している直流安定化電源からのノイズかと思われます。
電源遮断時の波形は、直流安定化電源をOFFにしてかつラズベリーパイがデスクトップ画面を映している時に取った波形です。安定して5Vを出力できていて、大きなノイズも見られません。
電源正常時の昇圧回路の出力電圧波形
電源遮断(バックアップ)時の出力電圧波形
バックアップ可能時間
電源遮断時にどの程度の時間ラズベリーパイが動作し続けられるかストップウォッチで測定してみました。
特に何もアプリを立ち上げずデスクトップ画面を映しているだけの状態、CPU負荷を100%にした状態で測定しました。
UPS基板に繋がっている直流安定化電源をOFFにしたらストップウォッチをスタートし、ラズベリーパイが死んで画面が真っ暗になったら停止します。
写真では分かりにくいですが、下図のようにUPS基板の電力だけでラズパイが動いています。
UPSが切れると電源ランプが赤に変わります。
UPS基板の電力だけで動いている写真 ラズパイにはHDMIしか繋がっていません。
あ、死んだ
結果は下表です。
CPU100%だと2secです。間に合うかちょっと不安かなという感じでしょうか?即座にシャットダウンすれば間に合いそうですが、シャットダウンする前にデータの保存とか処理をしてたら間に合わないかもしれませんね。
デスクトップ表示だけの5secでしたら色々処理をしても余裕で間に合いそうです。
ラズベリーパイが動作停止した後バッテリのコンデンサには2.73V残っていました。バッテリ放電時はダイオードを通るので昇圧ICに入る電圧はおよそ 2.73V-0.5V = 2.13Vとなってしまい昇圧の限界になってしまった様です。
しばらくキャパシタ電圧を見ていましたが、完全放電には時間がかかりそうでしたのでキャパシタの残存電圧には注意ですね。
ちなみにキャパシタを完全放電したい場合はキャパシタの両端を短絡させればできます。
UPS基板の電力でどれだけ持つかの実験結果
充電にかかる時間
バッテリーのキャパシタを空の状態から充電するのにかかる時間も測定してみました。
5Vの入力電源がダイオードで電圧降下するので、キャパシタは最大約4.5Vまで充電されます。
測定した結果が下表です。充電開始時が最も充電速度が速く、段々と遅くなっていきます。
4Vまでは約170秒で充電できるのですが、そこからは大分遅くなり、4.4Vのほぼフル充電までには390秒かかりました。
充電にかかる時間
電源遮断を検知してシャットダウンを実行
下記のようなPRGで実験を行いました。
GPIO27を監視し、GPIO27がLOWになったらシャットダウンを実行します。シャットダウンを実行した証拠にlogを残しています。
UPS基板に直流安定化電源から5Vを供給し、PRGを実行したら電源をOFFにします。
from gpiozero import DigitalInputDevice
from time import sleep
import logging
import os
import subprocess
# ログ設定
logging.basicConfig(
filename="/var/log/power_monitor.log", # ログの保存先
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s"
)
# GPIO27 を入力ピンとして設定
input_pin = DigitalInputDevice(27)
def shutdown_system():
"""システムをシャットダウンする"""
logging.info("シャットダウンを実行します。")
try:
subprocess.run(["sudo", "shutdown", "-h", "now"], check=True)
except Exception as e:
logging.error(f"シャットダウン中にエラー: {e}")
print("Monitoring GPIO27...")
try:
while True:
# 現在の状態を取得
if input_pin.value: # HIGH の場合
print("電源正常")
else: # LOW の場合
logging.warning("電源遮断検知、シャットダウン開始")
shutdown_system()
break # シャットダウンプロセスを開始後、ループ終了
sleep(1) # 1秒待機
except KeyboardInterrupt:
print("Program terminated.")
実験の様子
結果が下図です。
電源をOFFしてラズベリーパイがシャットダウンを実行してOFFになったことを確認した後、再度ラズベリーパイを起動してみると、下図のようにちゃんとログが残っていることが確認できました。
CPU負荷100%でも同様に実験を行い、ログが残っていることが確認できました。
ちなみに、シャットダウン後に再度電源供給をしただけではラズベリーパイは起動しません。UPSが5Vを供給し続けているため、ラズパイからして見ると電源の立ち上がりが見えないからです。
電源供給した後に、ラズベリーパイの電源ボタンを押す必要があります。ラズベリーパイ5以外には電源ボタンが無いので、3,4だとこのUPS基板は大分扱いにくいです。
ちなみに起動時に「低電力イベント~」という電源の警告が表示されてしまいますが、「vcgencmd get_throttled」で調べられる電源のエラーコードをみると「0x0」と表示されるので問題は無さそうです。
電源正常時
ちゃんとログが残ってました
最後に
ご覧いただきありがとうございました。
この記事で設計した基板は「らずぱい工房」HPで販売しています。
興味がありましたら是非ご覧ください。
https://raspikoubou.theshop.jp/items/94650013