RaspBerryPi3でサーボモータ制御 (Pi4j)

```math
\def\textlarge#1{%
  {\rm\Large #1}
}
\def\textsmall#1{%
  {\rm\scriptsize #1}
}
```
#**１、サーボモータ制御！**
　前回の「RaspBerryPi3でLEDをPWMで光らせる (Pi4j)」でPWMを操れましたので、ついにモータの制御です。
　[入門キット※1](https://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwidnK_Bm5jWAhVIyrwKHYTXCQgQFggnMAA&url=https%3A%2F%2Fwww.amazon.co.jp%2FKuman-Raspberry-1602%25E6%25B6%25B2%25E6%2599%25B6%25E3%2583%2587%25E3%2582%25A3%25E3%2582%25B9%25E3%2583%2597%25E3%2583%25AC%25E3%2582%25A4-BMP180%25E3%2583%2587%25E3%2582%25B8%25E3%2582%25BF%25E3%2583%25AB%25E6%25B0%2597%25E5%259C%25A7%25E3%2582%25BB%25E3%2583%25B3%25E3%2582%25B5%25E3%2583%25BC-HC-SR501%25E8%25B5%25A4%25E5%25A4%2596%25E7%25B7%259A%25E3%2583%25A2%25E3%2583%25BC%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%25B3%25E3%2582%25BB%25E3%2583%25B3%25E3%2582%25B5%25E3%2583%25A2%25E3%2582%25B8%25E3%2583%25A5%25E3%2583%25BC%25E3%2583%25AB%2Fdp%2FB01LZ4AZUX&usg=AFQjCNGa4JXocNCbJf54e6eounq35hL17w)についているSG90をPWM制御で制御します。この制御をすることで任意の角度を保つことができます。
　![image.png](https://qiita-image-store.s3.amazonaws.com/0/164812/35f6667f-2f45-5ef3-41f1-f8a6cf044997.png)

　注意
　・私は電子機器については電圧=抵抗×電流がわかる程度の全くの素人です。

$\textsmall{　　※1「Kuman 35個 Raspberry Piに適用 初心者 電子工作 1602液晶ディスプレイ+温度/湿度センサ+BMP180デジタル気圧センサー}$
$\textsmall{　　　+HC-SR501赤外線モーションセンサモジュール 子供遊び Raspberry Pi 3 2 model B A A+ + に対応 電子工作入門キット ラズベリーパイ K71」}$
#**2、本題**
##　(1)接続
　サーボモーターを接続しています。
　①全体画像
![image.png](https://qiita-image-store.s3.amazonaws.com/0/164812/5d90531f-a5a4-629d-386e-660f4329d5a0.png)

　②詳細
　![image.png](https://qiita-image-store.s3.amazonaws.com/0/164812/d64bad67-8201-a563-9bed-3d88d31c8204.png)

##　(2)Raspberry piの設定
　シリアルを有効にすることで、ピンを制御できるようになります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/164812/6b8e44a3-9e95-87c5-cc8b-d4d1fab423d2.png)
##　(3)実行プログラム
　180度、1秒待つ、90度、1秒待つ、0度、1秒待つを繰り返します。

```java:TestPwmServoMotor.java
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinPwmOutput;
import com.pi4j.io.gpio.Pin;
import com.pi4j.io.gpio.RaspiPin;
import com.pi4j.util.CommandArgumentParser;




public class TestPwmServoMotor {

	public static void main(String[] args) throws InterruptedException {
		pwm(args);
	}


	/**
	 * 100Hzで出力
	 * @param args
	 * @throws InterruptedException
	 */
	public static void pwm(String[] args) throws InterruptedException{

		final GpioController gpio = GpioFactory.getInstance();
		
		Pin pin = CommandArgumentParser.getPin(
		RaspiPin.class,    
		RaspiPin.GPIO_00,  
		args);             
		GpioPinPwmOutput pwm = gpio.provisionSoftPwmOutputPin(pin);
		pwm.setPwmRange(100);//出力時間を100分割

		    
		int sleep = 1000;
		for(int i = 0 ;i<10;i++){
			//180度
			pwm.setPwm(25);//デューティー比25
			System.out.println("PWM rate is: " + pwm.getPwm());
			Thread.sleep(sleep);

			
			//90度
			pwm.setPwm(15);//デューティー比15
			System.out.println("PWM rate is: " + pwm.getPwm());
			Thread.sleep(sleep);
			
			//0度
			pwm.setPwm(6);//デューティー比6
			System.out.println("PWM rate is: " + pwm.getPwm());
			Thread.sleep(sleep);

		}
		gpio.shutdown();		
		
		System.out.println("pwm end");

        
	}
}
```
　javaDocの説明を見るとどうやら100Hzの信号を出している様です。
　測ってみたら確かにほぼ100Hz！
　![image.png](https://qiita-image-store.s3.amazonaws.com/0/164812/c159987a-fb1d-71ff-cb75-eee8de6ee5ae.png)

##　(4)実行結果
　3段階の角度を制御できています。
![15054437161wEtQ9snzA3SxmI1505443699.gif](https://qiita-image-store.s3.amazonaws.com/0/164812/aaf7b473-635e-e34d-9508-f85220c0874e.gif)


#**3、おわりに**
　モータが制御できればいろいろできそうで夢が広がります！
　いつかやってみたいと思っていたロボット作りができるかも。

　今回のテストで二つ課題があります。
　１つは指定できるデューティー比が0～100であるため微妙な角度を表現できません。
　2つ目、本当はハードウェアのPWMを使用したかったのですが、どうしてもうまくいきませんでした。
　ハードウェアなら指定できるデューティー比が0～1024なのに！
　javaから制御ができていないように思います。権限の問題でしょうか・・・。

参考
[モータ制御に欠かせない技術“PWM”って何？](http://monoist.atmarkit.co.jp/mn/articles/0706/06/news132.html)
　PWM制御がすごくわかりやすく解説されていました。