C言語

PWMをつかってサーボモーターを制御!(ハードウェア方式編)

PWMをつかってサーボモーターを制御!(ハードウェア方式編)

スポンサーリンク

こんにちは。駆け出しエンジニアのまっきーです。

前回、ハードウェア方式のPWM制御を学習しました。

その応用として、サーボモータの制御を行っていきたいと思います。

ソフトウェア方式で一度行っているので、必要なもの、回路図は全て同じです。

それではやってみます!

ハードPWM復習

簡単な復習からしていきたいと思います。

  1.  pinMode(pin番号,PWM_OUTPUT):ピンモードをPWM用にする
  2.  pwmSetClock(内部クロック*最小変化幅):最小変化幅(分解能)を設定
  3.  pwmSetRange(階調):階調の設定
  4.  pwmSetMode(PWM_MODE_MS or BAL):モードの設定
  5.  pwmWrite(pin番号,パルスONの値):パルス波を生成

上記の5つの手順でできるんでしたね。

準備(計算)

データシートは以下のようになります

画像に alt 属性が指定されていません。ファイル名: servo.png

周期20msのPWM信号を作るために変数を計算していきます。

T = 最小変化幅*階調(*階調を200で行ってみます)

f = 1 / T (T:周期f:周波数)より

50Hz = 1 / (最小変化幅*階調) 階調(range)は200とするので

これを解くと…最小変化幅 = 0.0001 = 100us

つまりpwmSetClock(100μs*19.2MHz=1920)

とすればよいことがわかる

電子回路図

今回はGPIO19(PWM1)を使用する。

プログラムコード

前回の反省もかねて、scanf入力でどう動くかを確認してみます。

計算上、rangeの値を10~20に変えれば動くと思うのですが…

#include <stdio.h>
#include <wiringPi.h>
#define SERVO 19

int main(void){
		int divisor = 1920;
		int range = 200;
		
		wiringPiSetupGpio();
	
		pinMode(SERVO,PWM_OUTPUT);
		pwmSetClock(divisor);
		pwmSetRange(range);
		pwmSetMode(PWM_MODE_MS);
			
		while(1){
		scanf("%d",&range);
		pwmWrite(SERVO,range);
	    }
		return 0;
}

実際に動かしてみると、ソフトの時と同様、約5~25の間で180度動作しました。

ん~、なんでだろう。

とりあえず、最終的なコードはこちら

#include <stdio.h>
#include <wiringPi.h>
#define SERVO 19

int main(void){
		int divisor = 1920;
		int range = 200;
		
		wiringPiSetupGpio();
	
		pinMode(SERVO,PWM_OUTPUT);
		pwmSetClock(divisor);
		pwmSetRange(range);
		pwmSetMode(PWM_MODE_MS);
		
		
	/*	
		while(1){
		scanf("%d",&range);
		pwmWrite(SERVO,range);
	}*/
		while(1){
		for(range = 5;range <= 25;range++){
		pwmWrite(SERVO,range);
		delay(500);
		}
	}
		return 0;
}

動作しています。

まとめ・考察

・ハードウェア方式のPWMでも、サーボモータを制御することができました。

・2つの方式どちらでやっても約0.5ms~24msで動作していることから、データシートが違うのでしょうか。

・もしくは私の計算の仕方が違っているのかもしれませんが、詳しくはわかりません。わかる方がいらっしゃいましたら教えてください…

ありがとうございました。

スポンサーリンク

-C言語