こんにちは。
いよいよ夏本番といった暑さですね。
夏といえばラヂエーター!
ピンク色の車屋さんが気になる季節ですが、ラズパイユーザーとしては木苺が腐らないようにしっかりと冷やしてあげたいところ。
私はpigpio
のhardware_PWM
を用いてCPUファンの回転数制御をしています。
常時稼働させているので極力静かに、そしてエアバンドを聞いているので高周波ノイズを少なく制御するように心がけております。
こちらの制御については追々記事を書くつもりですが、本日は制御に使用している**pigpio
のデーモン(pigpiod
)がCPUを常時5~7%使い続けている問題**に関してです。
#pigpioの構成
pigpio
はpythonとC言語でGPIOを操作するライブラリの決定版的存在のようです。
Raspberry PiのGPIO制御の決定版 pigpio を試す
実際使いやすく、初心者の私でも簡単に実装することができました。
pigpio
はpigpiod
というデーモンがバックグラウンドで起動してGPIOへの指示を処理してくれます。
ソケットで待ち受けてうんぬんかんぬんと難しいことをしてくれているようですが、そんなことは意識せず関数を呼び出すだけでGPIOを操作できます。
また、指示を与えるだけでなく常にGPIOの入力電圧などをモニターしていて、その変化をトリガーとすることもできるようです。
#pigpiodの憂鬱
さて、こちらのpigpiod
ですがCPU使用率が常時5~7%と高止まりになっており、Google先生にお尋ねしたところ事例によっては15%食うこともあるようです。
原因について簡単に書かせていただきますと、pigpiod
は前述の「GPIOの入力をトリガーにする機能」のため常にGPIOの状態をサンプリングしており、そちらの処理がCPUを消費しているということのようです。
(ソフトウェアPWMもこちらのサンプリングに基づいて行われていると思われます。)
サンプリングはデフォルトで5μsという結構早いレートで行われており、CPUを食うのも納得なのですが私が使用しているのはhardware_PWM
関数のみ、感度ビンビンのサンプリングなんて必要ありません。
#エンドレス∞
見出しに意味なんてありません。
CPUを冷やすための制御がCPUを浪費するなんて悪循環は止めてしまいたい。
喫茶店で言うべきセリフを探すため、ドキュメントを漁りました。
pigpio Daemon
簡単なことですがhardware_PWM
関数ではサンプリングは必要がないのでサンプリングを止めてしまえばよいのです。
夏休みは宿題をする、当たり前のことですね。
#解決策
pigpiod
はsystemd
によってデーモンとして起動しています。
デフォルトではきっと以下のようになっているはず。
[Unit]
Description=Daemon required to control GPIO pins via pigpio
[Service]
ExecStart=/usr/bin/pigpiod -l
ExecStop=/bin/systemctl kill pigpiod
Type=forking
[Install]
WantedBy=multi-user.target
起動時に実行されるExecStart
の部分を編集してpigpiod
のサンプリング機能を無効にするオプション-m
を付加します。
2024/10/31追記
編集方法を改めました。
ユニットファイルを直接編集するとしていましたが、直接編集してはいけません!
アップデートなどの際にリセットされてしまい困ることになります。
幸い、便利な上書き方法があるのでそちらで編集しましょう。
sudo systemctl edit pigpiod.service
このコマンドで、オーバーライドファイルの作成と、編集が一気にできます。
そしてdaemon-reload
までやってくれる優れものです。
立ち上がった編集画面に下記を入力してください。
[Service]
ExecStart=
ExecStart=/usr/bin/pigpiod -l -m
引っ掛かりポイントとしては、ExecStart=
を入れていったんリセットしないと、重複と言われてエラーになることです。
編集が完了したらsudo systemctl restart pigpiod
で再起動して作業は完了です。
systemctl status pigpiod
から起動コマンドに-m
がついていることを確認しましょう。
更新前の編集方法
2024/10/31追記を参照してください。
[Unit]
Description=Daemon required to control GPIO pins via pigpio
[Service]
ExecStart=/usr/bin/pigpiod -l -m #Disable alerts
ExecStop=/bin/systemctl kill pigpiod
Type=forking
[Install]
WantedBy=multi-user.target
以下を実行してサービスを再読み込み→pigpiod
を再起動
sudo systemctl daemon-reload
sudo systemctl restart pigpiod
こちらの操作でpigpiod
のCPU使用率はほぼゼロになりました。
もちろんhardware_PWM
は問題なく使えてます。
ちなみにExecStart
にデフォルトでついていた-l
オプションはpigpiod
のリモート待ち受けを無効化するオプションです。
デフォルトでは8888ポートでGPIOへの操作を待ち受けるようになっているそうですが、なんかセキュリティ的にも気持ち悪いですしローカルだけの使用なのでつけたままにしておきます。
#Samplingを無効化したくない人
ソフトウェアPWMを使用している人や入力トリガーを使用している人向けの代替案です。
以下のように記述することでサンプリングの回数を抑えることができますので、当方の環境では7%から5%ほどに変化し、やや抑えめとなりました。
ExecStart=/usr/bin/pigpiod -l -s 10
こちらの設定では10μsとなっています。
どうやらこの値が大きすぎると高い周波数におけるソフトウェアPWMの精度に影響するようですので設定する際はお気を付けください。
設定可能な値は1, 2, 4, 5, 8, or 10 microseconds
とのことです。
#まとめ
大変便利なpigpio
ですが若干重いのが玉に瑕でした。
簡単に改善できたのですが、日本語で情報がなかったのでまとめさせていただきました。
皆様のお役に立てば幸いです。