この文書では,モータドライバに接続されたファンをRPiで制御するJavaプログラムの作成方法について説明しています.モータドライバとしてDRV8832DGQRを用いており,このドライバにはファンの停止,正転および逆転させることと,回転速度を調整させることができます.しかし,RPiのピンをすべて使い切ってしまっているため,正転をさせることができない回路構成となっています.従って,ここではファンの停止と逆転,加えて回転速度を調整するプログラムを作成します.
回路構成
下にモータドライバ周りの回路図を示します.右側にはファンを停止および逆転させるための端子であるMOT_INと,ファンの回転速度を調整するMOT_SPDがあります.また,左側にあるCN1にはファンが接続される端子があります. モータドライバとRPiは直接接続されているのではなく,間にNPN型トランジスタが含まれています.これは,RPiから流すことのできる電流があまり多くないためです.

ファンの停止と逆転
IN1とIN2の状態でファンの停止,正転および逆転を決めることができます.下の表にまとめておきます.上記の回路図から,IN2は常にHighとなりますので,IN1がLowの時には逆転,Highのときにはブレーキとなります.従いまして,MOT_INをLowにするとIN1がHighとなり,ファンは停止,MOT_INをHighとするとIN1がLowとなり,ファンは逆転します.
| IN1 | IN2 | 機能 |
|---|---|---|
| Low | Low | スタンバイ/惰走 |
| Low | High | 逆転 |
| High | Low | 正転 |
| High | High | 停止(ブレーキ) |
PWM
Pulse Width Modulation(略してPWM)は,電圧をパルス状(方形波)を変化させ,ONとOFFの比率を変えることで,トータルで見たときに電圧を変化させているように見せる方法です.PWMにおいて,見た目の電圧を決めるには方形波のデューティ比を変化させることで実現します.デューティ比とはHighとLowの比率であり,100%であればずっとHigh,0%であればずっとLowとなります.モータドライバの端子VSETには回転速度を制御する電圧を印加することができますので,そこにPWMを用います.
プログラム
RPiにはPWMを出力できる専用端子が1個だけあり,それがGPIO_01です.このピンをPi4Jで利用するには,これまでのLEDなどのようにGpioPinDigitalOutputとして取り扱うのではなく,GpioPinPwmOutputを用いることになります.下のプログラム例はGPIO_01ピンをPWM端子としてインスタンス化し,PWMのデューティ比を300としています.なお,setPwmの引数は0~1023までの値となっています.また,回路構成上,NPNトランジスタがRPiとモータドライバの間にあるため,setPwmでデューティ比が大きくなればモータドライバへはデューティ比が小さくなりますので注意してください.ただし,今回使用するファンでは0から1023までの値を変化させたとき,回転速度がリニアに変化しません.具体的には0~200だとファンが回り,400以上になるとファンが止まってしまいます.従いまして,200~400の間の値をsetPwmに設定してください.
/* GPIOコントローラを取得する */ final GpioController gpio = GpioFactory.getInstance(); /* 回転速度を調整するピンのインスタンスを得る */ final GpioPinPwmOutput rotate_speed = gpio.provisionPwmOutputPin(RaspiPin.GPIO_01); /* PWMのデューティ比を設定する */ rotate_speed.setPwm(300);
演習
下に示すクラスはファンを制御するクラスです.アットマークになっている箇所をコメントにもとづき実装してください.
package jp.ac.nagano_nct.ashida_lab.fan;
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.GpioPinPwmOutput;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;
public class Fan {
/* モータの停止と回転をさせる端子 */
private final GpioPinDigitalOutput _motorOnOff;
/* モータの回転速度を決める端子 */
private final GpioPinPwmOutput _motorSpeed;
/**
* コンストラクタ
*/
public Fan(){
/* GPIOコントローラを得る */
final GpioController gpio = @@@@@@@@@@;
/* GPIO_12をディジタル出力ピンとしてインスタンス化し,_motorOnOffにする.(初期状態:High) */
_motorOnOff = @@@@@@@@@@@;
/* GPIO_01をPWM出力ピンとしてインスタンス化し,_motorSpeedにする */
_motorSpeed = @@@@@@@@@@@@@;
/* モータの回転速度を300にする */
_motorSpeed.@@@@@@@@@@;
}
/**
* ファンを停止させる
*/
public void stop(){
_motorOnOff.@@@@@;
}
/**
* ファンを回転させる
*/
public void rotate(){
_motorOnOff.@@@@@;
}
/**
* ファンの回転速度を設定する
* @param speed 0~100までの値.数値が多いほど速く回る
*/
public void setRotateSpeed(int speed){
/* 0未満,もしくは100より大きかったら値を設定しない */
if(0>speed || speed<100){
return;
}
/* 使っているファンは200(速)~400(遅)までの値しか使えないため, */
/* 400-speed*2にしている */
_motorSpeed.setPwm(400-speed*2);
}
public static void main(String[] args) throws InterruptedException {
/* ファンをインスタンス化する */
Fan fan = new Fan();
/* ファンを回転させる */
fan.rotate();
/* 3000ミリ秒待つ */
Thread.sleep(3000);
/* ファンを停止させる */
fan.stop();
/* 3000ミリ秒待つ */
Thread.sleep(3000);
/* ファンを回転させる */
fan.rotate();
/* ファンの速度を0~100まで変化させる */
for(int i=0; i<=100; i++){
/* ファンの速度をiにする */
fan.setRotateSpeed(i);
/* 200ミリ秒待つ */
Thread.sleep(200);
}
}
}
