pigpioでPWM制御する

PWMによる速度制御は「WiringPiでPWM制御する」で実験しましたが、致命的な問題により実用とはなりませんでした。 他に良い方法はないものかと探していると、pigpioというライブラリを発見! 実験してみました。

wave

pigpioは、サーボの制御やPWM信号の出力、またパルスの計測などの機能を提供するライブラリで、C言語やPython、コマンドラインなどから使用することができ、デーモンとしての動作も可能な為、非常に幅広く利用可能です。

インストール

wget abyz.co.uk/rpi/pigpio/pigpio.zip
unzip pigpio.zip
cd PIGPIO
make
make install

デーモンの起動

sudo pigpiod -a 1        #DMAメモリアロケーションモードをPMAPに指定

コマンドラインからの利用

pigs s 17 500          #GPIO17へ接続したサーボへ500ms幅のパルス出力 (500-2500)
pigs p 22 128         #GPIO22へデューティー比50%のPWM信号出力 (0-255)

C言語からの利用

ヘッダファイルとして pigpiod_if.h をインクルード
set_PWM_range(22, 255)                #GPIO22へ最大値を設定
set_PWM_dutycycle(22,128)          #GPIO22へデューティー比50%のPWM信号出力
gcc example.c -o example -lpigpiod_if -lpthread -lrt          #-lpigpiod_if を指定してコンパイル
コマンド一覧はこちらです

ダウンロードアーカイブにはサンプルプログラムも含まれていますので参考になります。

ServoBlasterとの共用は不具合を生じましたので、サーボ制御とPWM制御はpigpioに置き換えました。

今のところ問題なく動作していますので、このまま利用を継続し、他の機能についても検証してみたいと思います。

※2016.1.28追記

pigpioの使用方法についてコメントを頂きましたので、モーターの速度制御に使用しているコードを掲載いたします。

例えば、コンパイルしたmotor_pigpioを使用し、 sudo ./motor_pigpio f 128 と、実行することにより、50%の速度(デューティー比)で前進します。 この時、GPIO23,25に信号が出力されていますので、LEDを接続すると50%の明るさで点灯します。 128の数値を変えることでデューティー比が変化します。

//motor pigpio.c v1.00 20150810
//コンパイルは以下のコマンドを実行
//gcc motor_pigpio.c -o motor_pigpio -lpigpiod_if -lpthread -lrt

#include <stdio.h>
#include <pigpiod_if.h>


#define MOTOR1 22			// GPIO22
#define MOTOR2 23			// GPIO23
#define MOTOR3 24			// GPIO24
#define MOTOR4 25			// GPIO25
#define RANGE 255			//PWM最大値
#define LEFT_STR "l"
#define RIGHT_STR "r"
#define FWRD_STR "f"
#define BACK_STR "b"
#define STOP_STR "s"

int main(int argc, char **argv)
{
	int pwm,status;

	// 速度を設定
	if ( argc < 3 ){ pwm = 0; } else { pwm = atoi(argv[2]); } if ( pwm > RANGE ){ pwm = RANGE; }

	// pigpiod接続
	status = pigpio_start(0, 0);
	//if (status < 0){ return 1; }

	// softPWM設定
	set_PWM_range(MOTOR1, RANGE);
	set_PWM_range(MOTOR2, RANGE);
	set_PWM_range(MOTOR3, RANGE);
	set_PWM_range(MOTOR4, RANGE);

	//停止
	set_PWM_dutycycle(MOTOR1, 0);
	set_PWM_dutycycle(MOTOR4, 0);
	set_PWM_dutycycle(MOTOR2, 0);
	set_PWM_dutycycle(MOTOR3, 0);

	if ( strcmp( argv[1], FWRD_STR ) == 0 ){
		//前進
		set_PWM_dutycycle(MOTOR2,pwm);
		set_PWM_dutycycle(MOTOR4,pwm);
		return 0;
	} else if ( strcmp( argv[1], BACK_STR ) == 0 ){
		//後退
		set_PWM_dutycycle(MOTOR1,pwm);
		set_PWM_dutycycle(MOTOR3,pwm);
		return 0;
	} else if ( strcmp( argv[1], LEFT_STR ) == 0 ){
		//左ターン
		set_PWM_dutycycle(MOTOR1,pwm);
		set_PWM_dutycycle(MOTOR4,pwm);
		return 0;
	} else if ( strcmp( argv[1], RIGHT_STR ) == 0 ){
		//右ターン
		set_PWM_dutycycle(MOTOR2,pwm);
		set_PWM_dutycycle(MOTOR3,pwm);
		return 0;
	}

	//ブレーキ
	set_PWM_dutycycle(MOTOR1, RANGE);
	set_PWM_dutycycle(MOTOR4, RANGE);
	set_PWM_dutycycle(MOTOR2, RANGE);
	set_PWM_dutycycle(MOTOR3, RANGE);
	time_sleep(0.5);
	//停止
	set_PWM_dutycycle(MOTOR1, 0);
	set_PWM_dutycycle(MOTOR4, 0);
	set_PWM_dutycycle(MOTOR2, 0);
	set_PWM_dutycycle(MOTOR3, 0);

	return 0;
}

 

 

関連記事

  • WiringPiでPWM制御するWiringPiでPWM制御する Raspberry […]
  • 新型シャーシの製作新型シャーシの製作 今年も残すところ2週間となりましたが、ついに新型シャーシの製作に着手しました。 素材はアルミ、自力での加工を選択しました。 タイヤやサーボ […]
  • フォトインタラプタで距離を測定するフォトインタラプタで距離を測定する 加速度センサーによる距離の推定結果が思わしくなかったため、オーソドックスなフォトインタラプタ(フォトリフレクタ)を使用し、距離を測定するこ […]
  • 加速度センサーで距離を推定する加速度センサーで距離を推定する ハウスローバーにとって、走行距離の計測は重要な項目です。 最も基本的な方法は、車輪の回転を検知することですが、車輪のスリップや障害物の影響 […]
  • ジャイロセンサーを使うジャイロセンサーを使う 小型の電動ヘリが出始めの頃、ジャイロセンサーは高級なイメージだったように思います。 ジャイロといえば、地球ゴマが一定の姿勢を保つ動きが連想 […]
  • リアルタイムクロック RTC-8564NB で起動するリアルタイムクロック RTC-8564NB で起動する ESAの彗星探査機「フィラエ」が電力喪失、スリープモードに移行 探査機にとって電力は命です。 フィラエは太陽光パネルに光が当たれば、復活 […]

pigpioでPWM制御する」への6件のフィードバック

  1. 高橋 寛文

    はじめまして。
    記事を拝見させていただき「C言語からの利用」のところを参考に適当にLED点灯でもやって見ようと思ったのですが、
    うまく出来ませんでした。
    参考プログラム等ありましたら教えていただきたいです。

    ダウンロードアーカイブとはhttps://github.com/joan2937/pigpioのことでしょうか?

    返信
    1. spacelab 投稿作成者

      コメントありがとうございます。

      当方で実際に使用しているコードを掲載いたしましたので参考にしていただければ幸いです。
      http://sp-lab.extrem.ne.jp/archives/4061

      ダウンロードアーカイブは、https://github.com/joan2937/pigpioで、間違いありません。
      使用にあたり、pigpioについて、情報を検索しましたが、ほとんど見つかりませんでした。
      もっと、情報量の多いものに変えたいとも思っているのですが、今のところ不具合もないのでこのままです。

      返信
      1. 高橋 寛文

        返信ありがとうございます。

        コメントやプログラム等を参考にさせてもらいうまく動かすことができました。
        ありがとうございます。

        もう1つだけお聞きしたいのですが、PIGPIOでのPWM信号は通常1周期で何ヘルツで何μsecくらいなのでしょうか?
        通信に関して素人なので教えていただけたら嬉しいです。また、参考になる資料等ございましたら教えていただけると嬉しいです。

        返信
        1. spacelab 投稿作成者

          pigpioは、高機能のようですが、情報が少ないですね。
          モーターの速度制御の為に使用していますが、特にトラブルもなく動いてしまったので、深く調べることがありませんでした。

          改めて、コマンド一覧を確認すると、gpioGetPWMfrequencyの項目がありました。
          http://abyz.co.uk/rpi/pigpio/cif.html#gpioGetPWMfrequency

          コマンドラインからは、pigs pfg [gpio No.] です。
          実際に確認してみると、

          root@raspberrypi:~# pigs pfg 23
          400

          400Hzのようです。
          gpioSetPWMfrequencyで、変更することもできますので、モーター制御の周波数を最高の4kHzに設定すると、

          root@raspberrypi:~# pigs pfs 23 4000
          4000

          モーターの駆動音で変化を確認できました。
          設定できる範囲や値はサンプルレートとの兼ね合いで決まるようですが、このあたりが不明確です。
          他の用途でも使用可能かと思いますので、さらに、理解を深めたいところです。

          返信
  2. sakamoto

    はじめまして。
    記事を拝見させていただき、またプログラムを参考にさせていただいてraspberryPiのGPIOからPIGPIOを使用してPWM信号を出力することが出来ました。
    ありがとうございます。

    このプログラムを使用してros上の情報を購読してraspberryPiのGPIOから出す信号を変えたいのですがうまくできませんでした。
    ros上でPIGPIOを使用できる方法、プログラム等ありました教えていただけないでしょうか。
    また、参考になる資料等ございましたら教えていただけると嬉しいです。
    よろしくお願いします。

    返信
    1. spacelab 投稿作成者

      コメントありがとうございます。

      残念ながら、ROSについては実験経験がありません。
      ロボット制御用言語のようなものは、採用したいと思っていましたので、今後の実験テーマとしたいところです。

      答えにならず、恐縮ですが、ご容赦下さい。

      返信

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です