12
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

pigpioがCPUを浪費している

Last updated at Posted at 2020-08-10

こんにちは。
いよいよ夏本番といった暑さですね。
夏といえばラヂエーター!
ピンク色の車屋さんが気になる季節ですが、ラズパイユーザーとしては木苺が腐らないようにしっかりと冷やしてあげたいところ。
私はpigpiohardware_PWMを用いてCPUファンの回転数制御をしています。

常時稼働させているので極力静かに、そしてエアバンドを聞いているので高周波ノイズを少なく制御するように心がけております。
こちらの制御については追々記事を書くつもりですが、本日は制御に使用している**pigpioのデーモン(pigpiod)がCPUを常時5~7%使い続けている問題**に関してです。

#pigpioの構成
pigpioはpythonとC言語でGPIOを操作するライブラリの決定版的存在のようです。
Raspberry PiのGPIO制御の決定版 pigpio を試す

実際使いやすく、初心者の私でも簡単に実装することができました。
pigpiopigpiodというデーモンがバックグラウンドで起動して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関数ではサンプリングは必要がないのでサンプリングを止めてしまえばよいのです。
夏休みは宿題をする、当たり前のことですね。

#解決策
pigpiodsystemdによってデーモンとして起動しています。
デフォルトではきっと以下のようになっているはず。

/lib/systemd/system/pigpiod.service
[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追記を参照してください。

/lib/systemd/system/pigpiod.service
[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を再起動

  1. sudo systemctl daemon-reload
  2. 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ですが若干重いのが玉に瑕でした。
簡単に改善できたのですが、日本語で情報がなかったのでまとめさせていただきました。
皆様のお役に立てば幸いです。

12
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?