Raspberry PiでIoTなシステム開発:ハードウェアPWM
Raspberry Pi歴3年目にして今頃ですがハードウェアPWMが備わっていることに気づきました。今までWiringPiのソフトウェアPWMを無理して使っていて音程のズレとか雑音に悩まされていたのですが、これで一挙解決できそうです。参考にしたのはこちら。RaspberryPiとWiringPiでサーボを動かす – Qiitaたしかに本家の記述は簡潔すぎてわかりにくいですね。百分率で設定する方が比率がわかりやすいのでRangeを100に決め打ちすると、周波数計算は以下の通りとなります。
clock = 192000 / freq
早速コードを書いてみます。
#include #include #include #include void setSignal(int p_signame);void signalHandler(int p_signame);int main(void){ setSignal(SIGINT); wiringPiSetup(); pinMode(1,PWM_OUTPUT); // pwmSetMode (PWM_MODE_BAL); pwmSetMode (PWM_MODE_MS); pwmSetRange(100);//百分率がわかりやすいので100 pwmSetClock(218);//Rangeが100の場合、192,000÷目標の周波数 int i = 0; while(1){ for(i=0;i<=100;i++) { pwmWrite(1,i); usleep(30000); } /* for(i=100;i>0;i--) { pwmWrite(1,i); usleep(100000); }*/ }}//シグナルの設定void setSignal(int p_signame){ if (signal(p_signame, signalHandler) == SIG_ERR) { //エラー printf(""Could not set signal handler\n""); exit(1); } return;}//シグナル受信/処理void signalHandler(int p_signame){ printf(""I got signal. Number is %d.\n"", p_signame); pinMode(1,INPUT); exit(0);}最初はpwmSetMode (PWM_MODE_BAL);を使っていたのですが、これだとpwmWriteをしたときに周波数まで変わってしまいました。設定する基準が違うのだと思います。12VのLEDをFETを介して駆動してみました。 [埋め込み: https://www.youtube.com/embed/Ya0HgLRUxJM] ストレスをかけても波形が乱れません。 [埋め込み: https://www.youtube.com/embed/yGnNx8fs3qs] “””
周波数計算の前提
clock = 192000 / freq はPWMの基準クロックが19.2MHzで、Rangeが100の場合の分周値の計算です。一般形は 出力周波数 = 基準クロック / (分周値 × Range) です。基板や使用ライブラリによって基準クロックや有効な設定範囲が異なるため、この定数を全機種に当てはめません。