RaspberryPi[69] GPIOをPWM化して消費電力を下げる(pigpiod経由・sudo不要)
概要
PIO出力を単なるON/OFFではなくPWM駆動にすることで、見た目をほぼ変えずに平均消費電力を下げる方法をまとめた。今回はフォトカプラ+トランジスタ駆動のIOに対して、人にちらつきが見えない周波数でPWMをかけ、省電力化する構成とした。pigpioのデーモンAPI(pigpiod_if2)を使うことで、sudoなしで制御できる。
構成
Raspberry Pi GPIO → フォトカプラ → トランジスタ → 負荷
ポイント:PWMにより平均電流を下げる。ちらつきを見せないため周波数は500Hz以上を使用。フォトカプラの応答速度を考慮し、数kHz以下に抑える。
使用GPIO(BCM番号):13,18,19,12(全てハードPWM対応グループ)
準備:pigpioデーモンを有効化
udo apt install -y pigpio
sudo systemctl enable --now pigpiod確認
ps aux | grep pigpiodデーモンAPIでは pigpio_start() で接続し、set_PWM_* 系関数で制御する。ローカルAPI(gpioPWM等)とは混在できない点に注意。
サンプルコード
// build: gcc pwm_sample.c -o pwm_sample -lpigpiod_if2 -lrt -lpthread
// run : ./pwm_sample
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <pigpiod_if2.h>
#define GPIO_TBO16 13
#define GPIO_TBO17 18
#define GPIO_TBO18 19
#define GPIO_TBO19 12
static volatile int stop = 0;
static void on_sigint(int sig){ (void)sig; stop = 1; }
static void all_off(int pi, const int *pins, int n){
for(int i=0;i<n;i++) set_PWM_dutycycle(pi, pins[i], 0);
}
int main(void){
signal(SIGINT, on_sigint);
int pi = pigpio_start(NULL, NULL);
if (pi < 0) { fprintf(stderr, "pigpio_start failed\n"); return 1; }
int pins[] = { GPIO_TBO16, GPIO_TBO17, GPIO_TBO18, GPIO_TBO19 };
const int n = sizeof(pins)/sizeof(pins[0]);
const unsigned freq = 500;
const unsigned range = 255;
const unsigned duty = 204; // 約80%
for(int i=0;i<n;i++){
set_mode(pi, pins[i], PI_OUTPUT);
set_PWM_range(pi, pins[i], range);
set_PWM_frequency(pi, pins[i], freq);
set_PWM_dutycycle(pi, pins[i], 0);
set_mode(pi, pins[i], PI_OUTPUT);
}
while(!stop){
for(int i=0;i<n && !stop;i++){
all_off(pi, pins, n);
set_PWM_dutycycle(pi, pins[i], duty);
sleep(5);
}
}
all_off(pi, pins, n);
pigpio_stop(pi);
return 0;
}
設定値の目安:周波数500Hzで人の目にちらつきは感じない。dutyは80%程度なら見た目の変化が少なく、約20%の省電力効果が得られる。さらに下げる場合はフォトカプラのCTR余裕とトランジスタのスイッチング損失に注意。
まとめ
GPIOを常時ONで使っている場合、PWM化するだけで簡単に平均消費電力を下げられる。pigpiod経由ならsudo不要で常駐サービスとの併用も安全に行えるため、実運用システムにも組み込みやすい。

