LoginSignup
13
8

More than 3 years have passed since last update.

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を付加します。

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

13
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
13
8