白執事の徒然なる日々


主にコンピュータ関係の記事を書いています。

プロフィール

白執事☆

こんにちは、白執事です。
PC関係の記事を書いていきますので
よろしくお願いします。

Raspberry Pi で冷却ファンをPWM制御してみよう

このページの目標

Raspberry Pi に冷却ファンを取り付けると、基本的にはフルパワーで回りっぱなしだと思います。
このページでは トランジスタPWM という仕組みを使って、冷却ファンの回転数を制御してみます。
また、Raspberry Pi 起動時に自動で冷却ファンの制御が働くようにします。

今回は Raspberry Pi と各部品を直接つないでみようと思います。
その為、ブレッドボードは使いません。


必要な物

Raspberry Pi 本体
今回は Raspberry Pi 2 を使って説明します。


ケース
冷却ファンに対応した Raspberry Pi のケースを用意しましょう。
GPIOピンの所にスペースがあいている物が使いやすくて良いと思います。



冷却ファン
下記のようにケーブルが分かれている方が使いやすいのでおすすめです。
5Vの電圧に対応した物を用意しましょう。
また、ケースの取り付け部分に合う大きさの物を選んで下さい。



トランジスタ
2SC1815-GR という製品を使って、この先の説明をします。



ジャンプワイヤー
(メス-メス)のケーブルを用意しましょう。 ここでは2本使う予定です。
トランジスタGPIOピン をつなげるのに使います。
1本1本、独立している物を選んで下さい。
複数本がひっついている製品もありますが、それは使いません。



用語の解説

PWM
  • Pulse Width Modulation の略。

    電子部品に電気を流す場合、通常は電圧を一定にします。
    そこで、意図的に電源のオン・オフを高速で繰り返し、オンのパルス幅を増減することで
    見かけ上の電圧を変化させるのが PWM です。

    この仕組みを利用すると、モーターの回転数やLEDの輝度などを制御できます。




トランジスタ
  • 半導体でできた電子部品で、電気の流れを制御します。
    大まかには下記の働きがあります。

    (1)電気信号の増幅
    (2)電子回路のONとOFFを切り替える ← 今回はこのスイッチ機能を使って、PWMを実現します。

    トランジスタの各名称と電流の向きは次のようになります。



    2SC1815-GR という製品が安価で手に入るようなので、これを使います。
    丸みのある部分が後ろ、平らな部分が前になります。




    ベースから電気が流れると、コレクタ - エミッタ間の電気が流れるようになります。
    ベースの電流が止まると、コレクタ - エミッタ間の電流が止まります。


Raspberry Pi 2 の GPIOピンについて

※Raspberry Pi のバージョンによって、GPIOピンの数や働きが違うようなので注意して下さい。


・・・ 電源です。3.3V と 5V があるので、必要に応じてお好きな方を選んで下さい。
・・・ Ground。接地、アースのようなもの。配線のマイナス極をここにつなぐ。
・・・ Raspberry Pi では GPIO18 だけに PWM の機能があるようです。トランジスタのベースをここにつなぐ。



接続例



Python のライブラリをインストール ※追記しました

これから作る Python のプログラムは、環境によってライブラリが不足していて動かない場合があります。
そのため、事前にインストールしておきます。
sudo apt-get install python-daemon


Pythonで冷却ファンの制御プログラムを作成

Raspberry Pi の /home/pi ディレクトリに移動。
cd /home/pi

PWM_FanCooler ディレクトリを作成。
sudo mkdir PWM_FanCooler

/home/pi/PWM_FanCooler に移動。
cd /home/pi/PWM_FanCooler

PWM_FanCooler_d.py を作成して編集する。
sudo nano PWM_FanCooler_d.py
#!/usr/bin/python
# coding: utf-8

# モジュールをインポート
import RPi.GPIO as GPIO
import time

# daemon化に必要
from daemon import daemon
from daemon.pidlockfile import PIDLockFile

# GPIOのピン番号を定義
GPIO18 = 18

# 周波数を定義
Hz = 60

#=================
# CPUの温度を取得
#=================
def get_CPU_Temperature():
	temp = "0"

	f = open("/sys/class/thermal/thermal_zone0/temp", "r")
	for t in f:
		temp=t[:2] + "." + t[2:5]
	f.close()

	return float(temp)

#=========
# PWM実行
#=========
def exec_pwm():
	#--------------------------------------
	# GPIOを物理的なピン番号で指定する場合
	#--------------------------------------
	## GPIOピン番号の定義方法
	#GPIO.setmode(GPIO.BOARD)
	## 出力モードで初期化
	#GPIO.setup(12, GPIO.OUT)
	## PWM初期化
	#p = GPIO.PWM(12, Hz)

	#------------------------
	# GPIO番号で指定する場合
	#------------------------
	# GPIOピン番号の定義方法
	GPIO.setmode(GPIO.BCM)
	# 出力モードで初期化
	GPIO.setup(GPIO18, GPIO.OUT)
	# PWM初期化
	p = GPIO.PWM(GPIO18, Hz)

	try:
		# 100%の出力で、1秒間動かす
		# 最初の出力が小さすぎて、ファンが回らない場合の対策
		Duty = 100
		p.start(Duty)
		time.sleep(1)

		while True:
			# CPUの温度を取得
			CPU_Temp = get_CPU_Temperature()

			# CPUの温度によって出力を変更
			#-------------------------
			#       ~20.0℃ -->  25%
			# 20.0℃~25.0℃ -->  50%
			# 25.0℃~30.0℃ -->  75%
			# 30.0℃~       --> 100%
			#-------------------------
			if CPU_Temp < 20.0:
				Duty = 25
			elif CPU_Temp < 25.0:
				Duty = 50
			elif CPU_Temp < 30.0:
				Duty = 75
			else:
				Duty = 100

			# 出力を変更して、30秒間待機
			p.ChangeDutyCycle(Duty)
			time.sleep(30)

	except Exception as e:
		# 例外処理
		print "[例外発生] PWM_FanCooler_d.py を終了します。"
		print "Exception : " + str(e)
		print "     Type : " + str(type(e))
		print "     Args : " + str(e.args)
		print "  Message : " + e.message
	finally:
		# PWMを終了
		p.stop()

		# GPIO開放
		GPIO.cleanup()

if __name__ == "__main__":
	# PIDファイルの書き込みに失敗してデーモンが動かない事があるので、少し時間をずらす
	time.sleep(1)

	# /etc/init.d/PWM_FanCooler.sh のPIDファイルとは別名にする
	with daemon.DaemonContext(pidfile=PIDLockFile('/var/run/PWM_FanCooler_d.pid')):
		exec_pwm()
Ctrl + O で保存、Ctrl + X でnanoを終了。


解説
Pythonのプログラムを普通に作ってそのまま実行すると、実行中は他のコマンドを入力できない状態になります。
そのため、デーモン化してバックグランドで実行すると、他の作業ができるようになります。
from daemon import daemon
from daemon.pidlockfile import PIDLockFile
	with daemon.DaemonContext(pidfile=PIDLockFile('/var/run/PWM_FanCooler_d.pid')):
		exec_pwm()


変更内容
例外処理でエラー内容を表示するように修正しました (2017/05/05)
	except Exception as e:
		# 例外処理
		print "[例外発生] PWM_FanCooler_d.py を終了します。"
		print "Exception : " + str(e)
		print "     Type : " + str(type(e))
		print "     Args : " + str(e.args)
		print "  Message : " + e.message

PWM_FanCooler_d.py に実行権限を与える。
sudo chmod 755 PWM_FanCooler_d.py


デーモンを実行するスクリプトを作成

Raspberry Pi の /etc/init.d に移動。
cd /etc/init.d

PWM_FanCooler.sh を作成して編集する。
sudo nano PWM_FanCooler.sh
#!/bin/sh

### BEGIN INIT INFO
# Provides:          PWM_FanCooler
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Example initscript
# Description:       This file should be used to construct scripts to be
#                    placed in /etc/init.d.  This example start a
#                    single forking daemon capable of writing a pid
#                    file.  To get other behavoirs, implemend
#                    do_start(), do_stop() or other functions to
#                    override the defaults in /lib/init/init-d-script.
### END INIT INFO

#-------------------
# PWM制御スクリプト
#-------------------

# Change the next 3 lines to suit where you install your script and what you want to call it
DIR=/home/pi/PWM_FanCooler
DAEMON=$DIR/PWM_FanCooler_d.py
DAEMON_NAME=PWM_FanCooler

# Add any command line options for your daemon here
DAEMON_OPTS=""

# This next line determines what user the script runs as.
# Root generally not recommended but necessary if you are using the Raspberry Pi GPIO from Python.
DAEMON_USER=root

# The process ID of the script when it runs is stored here:
PIDFILE=/var/run/$DAEMON_NAME.pid

. /lib/lsb/init-functions

do_start () {
	log_daemon_msg "Starting system $DAEMON_NAME daemon"
	start-stop-daemon --start --background --pidfile $PIDFILE --make-pidfile --user $DAEMON_USER --chuid $DAEMON_USER --startas $DAEMON -- $DAEMON_OPTS
	log_end_msg $?
}

do_stop () {
	log_daemon_msg "Stopping system $DAEMON_NAME daemon"
	start-stop-daemon --stop --pidfile $PIDFILE --retry 10
	log_end_msg $?
}

case "$1" in

	start|stop)
		do_${1}
		;;

	restart|reload|force-reload)
		do_stop
		do_start
		;;

	status)
		status_of_proc "$DAEMON_NAME" "$DAEMON" && exit 0 || exit $?
		;;
	*)
		echo "Usage: /etc/init.d/$DAEMON_NAME {start|stop|restart|status}"
		exit 1
		;;

esac
exit 0
Ctrl + O で保存、Ctrl + X でnanoを終了。


解説
### BEGIN INIT INFO
# Provides:          PWM_FanCooler
4行目: スクリプトをシステムに登録する時に使われるサービス名のようなもの。
既にこの名前が使われていると、システム登録時に失敗します。
他と重ならないような名前をつけて下さい。
# Change the next 3 lines to suit where you install your script and what you want to call it
DIR=/home/pi/PWM_FanCooler
DAEMON=$DIR/PWM_FanCooler_d.py
DAEMON_NAME=PWM_FanCooler
23行目: Pythonプログラムが保存されているディレクトリを指定。
24行目: Pythonプログラムのファイル名を指定。
25行目: デーモンの名前を指定。
# This next line determines what user the script runs as.
# Root generally not recommended but necessary if you are using the Raspberry Pi GPIO from Python.
DAEMON_USER=root
32行目: デーモンを実行するユーザー名を指定。


PWM_FanCooler.sh に実行権限を与える。
sudo chmod 755 PWM_FanCooler.sh


スクリプト経由でデーモンを起動・停止する場合

開始。
sudo /etc/init.d/PWM_FanCooler.sh start

動作状況を確認。
sudo /etc/init.d/PWM_FanCooler.sh status

停止。
sudo /etc/init.d/PWM_FanCooler.sh stop


スクリプトが自動起動するよう、システムに登録

スクリプトの登録方法

Raspberry Pi の /etc/init.d に移動。
cd /etc/init.d

スクリプトを登録する。
sudo update-rc.d PWM_FanCooler.sh defaults

スクリプトが登録されたか確認する。
ls -l /etc/rc?.d/*PWM_FanCooler.sh
※PWM_FanCoolerに関するファイルが表示されたらOK。

変更を加えたら更新する。
sudo systemctl daemon-reload

Raspberry Pi を再起動する。
sudo reboot


再起動時に冷却ファンが自動的に回るようになれば成功です!


スクリプトの登録を削除する場合

sudo update-rc.d -f /etc/init.d/PWM_FanCooler.sh remove

スポンサーサイト




カテゴリー:Raspberry Pi | タグ:
コメント(2)トラックバック (0) | 2017年04月23日 (日)05時11分