今回はRaspberry PiのGPIOでリレーを切り替えてPCの電源を遠隔操作を解説して行きたいと思います。
PCの電源の切り替えの方法は色々あると思いますが、今回はリレー回路を作りPCの電源を遠隔地からON OFFできるようにしました。ちなみにリレー回路を用いいる方法以外の方法には以下の様な方法があると思います。
1. Wake on Lan(WoL)を使う
2. リレー回路を使って電源を電気的に付ける (リレーの方法にもさまざまあります)
3. モータの制御で物理的に電源ボタンを押す
方法1はWoLという方法なのですが、マザーボードが対応している必要があります。私のXeonのサーバーはWoLに対応していませんでしたが、WoLに対応している場合は、WoLを使えば無料で起動可能です。普通はこちらの方法を採用するのが良いと思います。
方法2は150円ぐらいから400円ぐらいで作ることができます。電気的にPCの電源をONにするのでやや配線が煩雑になります。方法3の方法はモータの設計をする必要があり、モータも大きなトルクが必要なので費用も高くなります。
今回はこの中の方法2について解説していきます。
PCの電源スイッチの仕組み
回路を設計するためにPCスイッチの仕組みを説明します。しかし、仕組みを知らなくても記事のようにやれば回路を作ることができるので読み飛ばして頂いても大丈夫です。
今回は「ASUS PRIME H310M-A R2.0」を例に説明します。マザーボードにはシステムパネルコネクタというピンの集まりがあります。システムパネルコネクタは電源ボタンとつながっており、この端子を通じてPCの電源を入れることができます。以下にコントロールパネルコネクタのピンの構成図を示します。
通常、電源ボタンは並進運動をします。電源スイッチが押し込まれると電源ボタン(Power Button)とコントロールパネルのPower Buttonを結ぶ閉回路ができます。そして、閉回路ができるとPCの電源が入る仕組みになっています。
回路図を作るための部品
最初に回路を作成するための部品を挙げます。すでに持っているものはそれを使っていただいて大丈夫です。下に挙げたはんだごては非常に使いやすかったのでおすすめです。(数百円のはんだごてから乗り換えたのですが、使いやすさが段違いでした。)
リレーモジュールの説明
先ほど挙げたものの中でリレーモジュールが回路を作成するうえで大切なのでリレーモジュールについて説明します。以下にリレーモジュールのピン配置を示します。今回使用するリレーモジュールはINPUTピンに5V(実際には3V以上)の電圧をかけるとNO-COMの間が繋がります。そのため、Raspberry Piの方でGPIO17番に3.3V印加することで NO-COM の間をつなげることができます。
また、細かい話になりますが、リレーが作動する際に逆起電力という電圧が生じるのですが、このリレーモジュールにはフォトカプラというRaspberry Piとリレーモジュールを回路的に絶縁する素子が入っているのでRaspberry Piが損傷するのを防げます。
この回路を システムパネルコネクタに接続することで電源ボタンと同じことが実現できます。以下にGPIOに3.3V印加した場合の回路図を示します。 GPIOに3.3V印加すると、リレーモジュールが電源ボタンと同じ機能をしていることがわかると思います。
回路図を作成する
回路図を作成します。先程、リレーモジュールを説明するために示した回路でも電源を入れられるのですが、電源ボタンが使えなくなってしまうので、その問題を解決します。
その問題を解決した回路を以下に示します。ブレッドボードでの配線を示しました。ポイントはマザーボードに刺さっていた押し電源ボタンの配線をブレッドボードに移すことです。
この回路をユニバーサルに移植したい場合は先程のジャンパー線などを使い、同様な回路を作成してください。
実際に配線した画像はこのようになります。
GPIOに3.3V印加するプログラムを作成
GPIOに3.3V印加するプログラムはOSによって使うPythonのライブラリが異なるのですが、本記事の場合はUbuntuに対応したlgpioというライブラリを使用しました。
本記事の環境
PRETTY_NAME="Ubuntu 21.10"
NAME="Ubuntu"
VERSION_ID="21.10"
VERSION="21.10 (Impish Indri)"
VERSION_CODENAME=impish
ID=ubuntu
ID_LIKE=debian
Pythonのプログラム
プログラムはUbuntuのチュートリアルを参考にしました。
# wake.py
import time
import lgpio
WAKE = 17
def wake():
try:
h = lgpio.gpiochip_open(0)
lgpio.gpio_claim_output(h, WAKE)
lgpio.gpio_write(h, WAKE, 1)
time.sleep(1)
except Exception as e:
print(e)
finally:
lgpio.gpio_write(h, WAKE, 0)
lgpio.gpiochip_close(h)
def main():
wake()
if __name__ == "__main__":
main()
sudo python3 wake.py